instrument-control-0.9.4/0000755000000000000000000000000014743226261012347 5ustar00instrument-control-0.9.4/COPYING0000644000000000000000000001037614743226261013411 0ustar00devel/testtcp.m GPLv3+ inst/clrdevice.m GPLv3+ inst/instrhwinfo.m GPLv3+ inst/@octave_gpib/fclose.m GPLv3+ inst/@octave_gpib/fopen.m GPLv3+ inst/@octave_gpib/fprintf.m GPLv3+ inst/@octave_gpib/fscanf.m GPLv3+ inst/@octave_gpib/fwrite.m GPLv3+ inst/@octave_i2c/fclose.m GPLv3+ inst/@octave_i2c/fopen.m GPLv3+ inst/@octave_serial/fclose.m GPLv3+ inst/@octave_serial/fopen.m GPLv3+ inst/@octave_serial/get.m GPLv3+ inst/@octave_serial/set.m GPLv3+ inst/@octave_serial/srl_baudrate.m GPLv3+ inst/@octave_serial/srl_bytesize.m GPLv3+ inst/@octave_serial/srl_close.m GPLv3+ inst/@octave_serial/srl_flush.m GPLv3+ inst/@octave_serial/srl_parity.m GPLv3+ inst/@octave_serial/srl_stopbits.m GPLv3+ inst/@octave_serial/srl_timeout.m GPLv3+ inst/@octave_tcpip/fclose.m GPLv3+ inst/@octave_tcpip/fopen.m GPLv3+ inst/@octave_udp/fclose.m GPLv3+ inst/@octave_udp/fopen.m GPLv3+ inst/@octave_udp/fprintf.m GPLv3+ inst/@octave_udp/fread.m GPLv3+ inst/@octave_udp/fwrite.m GPLv3+ inst/@octave_udp/get.m GPLv3+ inst/@octave_udp/set.m GPLv3+ inst/@octave_usbtmc/fclose.m GPLv3+ inst/@octave_usbtmc/fopen.m GPLv3+ inst/@octave_vxi11/fclose.m GPLv3+ inst/@octave_vxi11/fopen.m GPLv3+ inst/spoll.m GPLv3+ inst/trigger.m GPLv3+ inst/udp_demo.m GPLv3+ src/gpib/gpib.cc GPLv3+ src/gpib/gpib_class.cc GPLv3+ src/gpib/gpib_class.h GPLv3+ src/gpib/gpib_close.cc GPLv3+ src/gpib/__gpib_clrdevice__.cc GPLv3+ src/gpib/gpib_read.cc GPLv3+ src/gpib/__gpib_spoll__.cc GPLv3+ src/gpib/gpib_timeout.cc GPLv3+ src/gpib/__gpib_trigger__.cc GPLv3+ src/gpib/gpib_write.cc GPLv3+ src/i2c/i2c_addr.cc GPLv3+ src/i2c/i2c.cc GPLv3+ src/i2c/i2c_class.cc GPLv3+ src/i2c/i2c_class.h GPLv3+ src/i2c/i2c_close.cc GPLv3+ src/i2c/i2c_read.cc GPLv3+ src/i2c/i2c_write.cc GPLv3+ src/parallel/parallel.cc GPLv3+ src/parallel/parallel_class.cc GPLv3+ src/parallel/parallel_class.h GPLv3+ src/parallel/pp_close.cc GPLv3+ src/parallel/pp_ctrl.cc GPLv3+ src/parallel/pp_data.cc GPLv3+ src/parallel/pp_datadir.cc GPLv3+ src/parallel/pp_stat.cc GPLv3+ src/resolvehost/resolvehost.cc GPLv3+ src/serial/serial.cc GPLv3+ src/serial/serial_class.h GPLv3+ src/serial/serial_class_lin.cc GPLv3+ src/serial/serial_class_lin.h GPLv3+ src/serial/serial_class_win32.cc GPLv3+ src/serial/serial_class_win32.h GPLv3+ src/serial/__srl_properties__.cc GPLv3+ src/serial/srl_read.cc GPLv3+ src/serial/srl_write.cc GPLv3+ src/octave-wrappers.h.in GPLv3+ src/tcp/tcp.cc GPLv3+ src/tcp/tcp_class.cc GPLv3+ src/tcp/tcp_class.h GPLv3+ src/tcp/tcp_close.cc GPLv3+ src/tcp/tcp_read.cc GPLv3+ src/tcp/tcp_timeout.cc GPLv3+ src/tcp/tcp_write.cc GPLv3+ src/udp/__udp_properties__.cc GPLv3+ src/udp/udp.cc GPLv3+ src/udp/udp_class.cc GPLv3+ src/udp/udp_class.h GPLv3+ src/udp/udp_close.cc GPLv3+ src/udp/udp_read.cc GPLv3+ src/udp/udp_timeout.cc GPLv3+ src/udp/udp_write.cc GPLv3+ src/usbtmc/usbtmc.cc GPLv3+ src/usbtmc/usbtmc_class.cc GPLv3+ src/usbtmc/usbtmc_class.h GPLv3+ src/usbtmc/usbtmc_close.cc GPLv3+ src/usbtmc/usbtmc_read.cc GPLv3+ src/usbtmc/usbtmc_write.cc GPLv3+ src/vxi11/vxi11.cc GPLv3+ src/vxi11/vxi11_class.cc GPLv3+ src/vxi11/vxi11_class.h GPLv3+ src/vxi11/vxi11_close.cc GPLv3+ src/vxi11/vxi11_read.cc GPLv3+ src/vxi11/vxi11_write.cc GPLv3+ src/vxi11/vxi11.x public domain instrument-control-0.9.4/DESCRIPTION0000644000000000000000000000074114743226261014057 0ustar00Name: instrument-control Version: 0.9.4 Date: 2025-01-19 Author: Andrius Sutas , Stefan Mahr , John Donoghue Maintainer: Stefan Mahr , John Donoghue Title: Instrument Control Description: Low level I/O functions for serial, i2c, spi, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces. Categories: instrument-control Depends: octave (>= 4.0.0) Autoload: no License: GPLv3+ instrument-control-0.9.4/INDEX0000644000000000000000000000727014743226261013147 0ustar00instrument-control >> Low level I/O functions Common Functions flushinput flushoutput readbinblock readline writebinblock writeline writeread General instrhelp instrhwinfo resolvehost GPIB clrdevice gpib gpib_read gpib_write gpib_timeout gpib_close spoll trigger @octave_gpib/fclose @octave_gpib/fopen @octave_gpib/fprintf @octave_gpib/fread @octave_gpib/fscanf @octave_gpib/fwrite I2C i2c i2c_addr i2c_close i2c_read i2c_write @octave_i2c/fclose @octave_i2c/fopen @octave_i2c/fread @octave_i2c/fwrite @octave_i2c/get @octave_i2c/set Modbus modbus @octave_modbus/get @octave_modbus/maskWrite @octave_modbus/read @octave_modbus/set @octave_modbus/write @octave_modbus/writeRead Parallel parallel pp_close pp_ctrl pp_data pp_datadir pp_stat @octave_parallel/fclose @octave_parallel/fopen @octave_parallel/fread @octave_parallel/fwrite Serial (Deprecated) serial seriallist srl_read srl_write @octave_serial/fopen @octave_serial/fclose @octave_serial/flushinput @octave_serial/flushoutput @octave_serial/fprintf @octave_serial/fread @octave_serial/fwrite @octave_serial/get @octave_serial/serialbreak @octave_serial/set @octave_serial/srl_baudrate @octave_serial/srl_bytesize @octave_serial/srl_close @octave_serial/srl_flush @octave_serial/srl_parity @octave_serial/srl_stopbits @octave_serial/srl_timeout Serial Port serialport serialportlist @octave_serialport/configureTerminator @octave_serialport/flush @octave_serialport/fprintf @octave_serialport/fread @octave_serialport/fwrite @octave_serialport/get @octave_serialport/getpinstatus @octave_serialport/read @octave_serialport/serialbreak @octave_serialport/set @octave_serialport/setDTR @octave_serialport/setRTS @octave_serialport/write SPI spi spi_close spi_read spi_write spi_writeAndRead @octave_spi/fclose @octave_spi/fopen @octave_spi/fread @octave_spi/fwrite @octave_spi/get @octave_spi/read @octave_spi/set @octave_spi/write @octave_spi/writeAndRead TCP (Deprecated) tcp tcp_close tcp_read tcp_write tcp_timeout tcpip @octave_tcp/fclose @octave_tcp/flush @octave_tcp/flushinput @octave_tcp/flushoutput @octave_tcp/fopen @octave_tcp/fprintf @octave_tcp/fread @octave_tcp/fwrite @octave_tcp/get @octave_tcp/read @octave_tcp/set @octave_tcp/write TCP Client tcpclient @octave_tcpclient/configureTerminator @octave_tcpclient/flush @octave_tcpclient/get @octave_tcpclient/read @octave_tcpclient/set @octave_tcpclient/write TCP Server tcpserver @octave_tcpserver/configureTerminator @octave_tcpserver/flush @octave_tcpserver/get @octave_tcpserver/read @octave_tcpserver/set @octave_tcpserver/write UDP (Deprecated) udp udp_close udp_demo udp_read udp_timeout udp_write @octave_udp/fclose @octave_udp/flush @octave_udp/flushinput @octave_udp/flushoutput @octave_udp/fopen @octave_udp/fprintf @octave_udp/fread @octave_udp/fwrite @octave_udp/get @octave_udp/read @octave_udp/set @octave_udp/write UDP Port udpport @octave_udpport/configureMulticast @octave_udpport/configureTerminator @octave_udpport/flush @octave_udpport/fread @octave_udpport/fwrite @octave_udpport/fprintf @octave_udpport/get @octave_udpport/read @octave_udpport/set @octave_udpport/write @octave_udpport/writeline USBTMC usbtmc usbtmc_read usbtmc_write usbtmc_close @octave_usbtmc/fclose @octave_usbtmc/fopen @octave_usbtmc/fread @octave_usbtmc/fwrite VXI11 vxi11 vxi11_close vxi11_read vxi11_write @octave_vxi11/fclose @octave_vxi11/fopen @octave_vxi11/fread @octave_vxi11/fwrite instrument-control-0.9.4/Makefile0000644000000000000000000002706614743226261014022 0ustar00## Copyright 2015-2016 Carnë Draug ## Copyright 2015-2016 Oliver Heimlich ## Copyright 2017 Julien Bect ## Copyright 2017 Olaf Till ## Copyright 2018-2020 John Donoghue ## ## 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. TOPDIR := $(shell pwd) ## Some basic tools (can be overriden using environment variables) SED ?= sed TAR ?= tar GREP ?= grep CUT ?= cut TR ?= tr TEXI2PDF ?= texi2pdf -q # work out a possible help generator ifeq ($(strip $(QHELPGENERATOR)),) ifneq ($(shell qhelpgenerator-qt5 -v 2>/dev/null),) QHELPGENERATOR = qhelpgenerator-qt5 else ifneq ($(shell qcollectiongenerator-qt5 -v 2>/dev/null),) QHELPGENERATOR = qcollectiongenerator-qt5 #else ifneq ($(shell qhelpgenerator -qt5 -v 2>/dev/null),) # v4 doesnt work # QHELPGENERATOR = qhelpgenerator -qt5 else ifneq ($(shell qcollectiongenerator -qt5 -v 2>/dev/null),) QHELPGENERATOR = qcollectiongenerator -qt5 else QHELPGENERATOR = true endif endif ## Note the use of ':=' (immediate set) and not just '=' (lazy set). ## http://stackoverflow.com/a/448939/1609556 package := $(shell $(GREP) "^Name: " DESCRIPTION | $(CUT) -f2 -d" " | \ $(TR) '[:upper:]' '[:lower:]') version := $(shell $(GREP) "^Version: " DESCRIPTION | $(CUT) -f2 -d" ") pkg_date := $(shell $(GREP) "^Date: " DESCRIPTION | $(CUT) -f2 -d" ") ## These are the paths that will be created for the releases. target_dir := target release_dir := $(target_dir)/$(package)-$(version) release_tarball := $(target_dir)/$(package)-$(version).tar.gz html_dir := $(target_dir)/$(package)-html html_tarball := $(target_dir)/$(package)-html.tar.gz ## Using $(realpath ...) avoids problems with symlinks due to bug ## #50994 in Octaves scripts/pkg/private/install.m. But at least the ## release directory above is needed in the relative form, for 'git ## archive --format=tar --prefix=$(release_dir). real_target_dir := $(realpath .)/$(target_dir) installation_dir := $(real_target_dir)/.installation package_list := $(installation_dir)/.octave_packages install_stamp := $(installation_dir)/.install_stamp ## These can be set by environment variables which allow to easily ## test with different Octave versions. ifndef OCTAVE OCTAVE := octave endif OCTAVE := $(OCTAVE) --no-gui --silent --norc MKOCTFILE ?= mkoctfile OCTAVE_CONFIG ?= octave-config ## Command used to set permissions before creating tarballs FIX_PERMISSIONS ?= chmod -R a+rX,u+w,go-w,ug-s HG := hg HG_CMD = $(HG) --config alias.$(1)=$(1) --config defaults.$(1)= $(1) HG_ID := $(shell $(call HG_CMD,identify) --id | sed -e 's/+//' ) HG_TIMESTAMP := $(firstword $(shell $(call HG_CMD,log) --rev $(HG_ID) --template '{date|hgdate}')) TAR_REPRODUCIBLE_OPTIONS := --sort=name --mtime="@$(HG_TIMESTAMP)" --owner=0 --group=0 --numeric-owner TAR_OPTIONS := --format=ustar $(TAR_REPRODUCIBLE_OPTIONS) ## Detect which VCS is used vcs := $(if $(wildcard .hg),hg,$(if $(wildcard .git),git,unknown)) ifeq ($(vcs),hg) release_dir_dep := .hg/dirstate endif ifeq ($(vcs),git) release_dir_dep := .git/index endif ## .PHONY indicates targets that are not filenames ## (https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html) .PHONY: help ## make will display the command before runnning them. Use @command ## to not display it (makes specially sense for echo). help: @echo "Targets:" @echo " dist - Create $(release_tarball) for release." @echo " html - Create $(html_tarball) for release." @echo " release - Create both of the above and show md5sums." @echo " install - Install the package in $(installation_dir), where it is not visible in a normal Octave session." @echo " check - Execute package tests." @echo " doctest - Test the help texts with the doctest package." @echo " run - Run Octave with the package installed in $(installation_dir) in the path." @echo " clean - Remove everything made with this Makefile." ## ## Recipes for release tarballs (package + html) ## .PHONY: release dist html clean-tarballs clean-unpacked-release ## To make a release, build the distribution and html tarballs. release: dist html md5sum $(release_tarball) $(html_tarball) @echo "Upload @ https://sourceforge.net/p/octave/package-releases/new/" @echo " and note the changeset the release corresponds to" ## dist and html targets are only PHONY/alias targets to the release ## and html tarballs. dist: $(release_tarball) html: $(html_tarball) ## An implicit rule with a recipe to build the tarballs correctly. %.tar.gz: % $(TAR) -cf - $(TAR_OPTIONS) -C "$(target_dir)/" "$(notdir $<)" | gzip -9n > "$@" clean-tarballs: @echo "## Cleaning release tarballs (package + html)..." -$(RM) $(release_tarball) $(html_tarball) @echo ## Create the unpacked package. ## ## Notes: ## * having ".hg/dirstate" (or ".git/index") as a prerequesite means it is ## only rebuilt if we are at a different commit. ## * the variable RM usually defaults to "rm -f" ## * having this recipe separate from the one that makes the tarball ## makes it easy to have packages in alternative formats (such as zip) ## * note that if a commands needs to be run in a specific directory, ## the command to "cd" needs to be on the same line. Each line restores ## the original working directory. $(release_dir): $(release_dir_dep) -$(RM) -r "$@" ifeq (${vcs},hg) hg archive --exclude ".hg*" --type files "$@" endif ifeq (${vcs},git) git archive --format=tar --prefix="$@/" HEAD | $(TAR) -x $(RM) "$@/.gitignore" endif ## Don't fall back to run the supposed necessary contents of ## 'bootstrap' here. Users are better off if they provide ## 'bootstrap'. Administrators, checking build reproducibility, can ## put in the missing 'bootstrap' file if they feel they know its ## necessary contents. ifneq (,$(wildcard src/bootstrap)) cd "$@/src" && ./bootstrap && $(RM) -r "autom4te.cache" endif ## Uncomment this if your src/Makefile.in has these targets for ## pre-building something for the release (e.g. documentation). cd "$@/src" && ./configure && $(MAKE) prebuild && \ $(MAKE) distclean && $(RM) Makefile ## $(MAKE) -C "$@" docs cd "$@" && $(RM) -rf "devel" # && $(RM) -f doc/mkfuncdocs.py doc/mkqhcp.py ${FIX_PERMISSIONS} "$@" run_in_place = $(OCTAVE) --eval ' pkg ("local_list", "$(package_list)"); ' \ --eval ' pkg ("load", "$(package)"); ' # html_options = --eval 'options = get_html_options ("octave-forge");' ## Uncomment this for package documentation. html_options = --eval 'options = get_html_options ("octave-forge");' \ --eval 'options.package_doc = "$(package).texi";' \ --eval 'options.package_doc_options = [options.package_doc_options " --css-include=$(package).css"];' $(html_dir): $(install_stamp) $(RM) -r "$@"; $(run_in_place) \ --eval ' pkg load generate_html; ' \ $(html_options) \ --eval ' generate_package_html ("$(package)", "$@", options); '; $(FIX_PERMISSIONS) "$@"; clean-unpacked-release: @echo "## Cleaning unpacked release tarballs (package + html)..." -$(RM) -r $(release_dir) $(html_dir) @echo doc/version.texi: $(release_dir_dep) @echo Generating $@ @echo "@c autogenerated from Makefile" > $@ @echo "@set VERSION $(version)" >> $@ @echo "@set PACKAGE $(package)" >> $@ @echo "@set DATE $(pkg_date)" >> $@ .PHONY: docs docs: doc/$(package).pdf doc/$(package).info doc/$(package).qhc doc/$(package).html echo $(shell qhelpgenerator-qt5 2>/dev/null) doc/$(package).html: doc/$(package).texi doc/functions.texi doc/version.texi cd doc && SOURCE_DATE_EPOCH=$(HG_TIMESTAMP) $(MAKEINFO) --html --css-ref=$(package).css --no-split $(package).texi doc/$(package).qhc: doc/$(package).html # try also create qch file if can cd doc && ./mkqhcp.py $(package) && $(QHELPGENERATOR) $(package).qhcp -o $(package).qhc cd doc && $(RM) -f $(package).qhcp $(package).qhp doc/$(package).info: doc/$(package).texi doc/functions.texi doc/version.texi cd doc && $(MAKEINFO) $(package).texi doc/$(package).pdf: doc/$(package).texi doc/functions.texi doc/version.texi cd doc && SOURCE_DATE_EPOCH=$(HG_TIMESTAMP) $(TEXI2PDF) $(package).texi #cd doc && texi2html --split=n --output $(package).html $(package).texi cd doc && $(RM) -f $(package).aux $(package).cp $(package).cps $(package).fn $(package).fns $(package).log $(package).toc doc/functions.texi: $(release_dir_dep) $(eval src_dirs = $(shell cd doc && find ../src -type d -printf '--src-dir=%p ')) cd doc && ./mkfuncdocs.py --src-dir=../inst/ $(src_dirs) ../INDEX | $(SED) 's/@seealso/@xseealso/g' > functions.texi .PHONY: clean-docs clean-docs: $(RM) -f doc/$(package).info $(RM) -f doc/$(package).pdf $(RM) -f doc/$(package).html $(RM) -f doc/functions.texi ## ## Recipes for installing the package. ## .PHONY: install clean-install octave_install_commands = \ ' llist_path = pkg ("local_list"); \ mkdir ("$(installation_dir)"); \ load (llist_path); \ local_packages(cellfun (@ (x) strcmp ("$(package)", x.name), local_packages)) = []; \ save ("$(package_list)", "local_packages"); \ pkg ("local_list", "$(package_list)"); \ pkg ("prefix", "$(installation_dir)", "$(installation_dir)"); \ pkg ("install", "-local", "-verbose", "$(release_tarball)"); ' ## Install unconditionally. Maybe useful for testing installation with ## different versions of Octave. install: $(release_tarball) @echo "Installing package under $(installation_dir) ..." $(OCTAVE) --eval $(octave_install_commands) touch $(install_stamp) ## Install only if installation (under target/...) is not current. $(install_stamp): $(release_tarball) @echo "Installing package under $(installation_dir) ..." $(OCTAVE) --eval $(octave_install_commands) touch $(install_stamp) clean-install: @echo "## Cleaning installation under $(installation_dir) ..." -$(RM) -r $(installation_dir) @echo ## ## Recipes for testing purposes ## .PHONY: run doctest check ## Start an Octave session with the package directories on the path for ## interactice test of development sources. run: $(install_stamp) $(run_in_place) --persist rungui: $(install_stamp) $(run_in_place) --gui --persist ## Test example blocks in the documentation. Needs doctest package ## https://octave.sourceforge.io/doctest/index.html doctest: $(install_stamp) $(run_in_place) --eval 'pkg load doctest;' \ --eval "targets = pkg('list', '$(package)'){1}.dir;" \ --eval "doctest (targets);" ## Test package. octave_test_commands = \ ' pkgs = pkg("list", "instrument-control"); \ dirs = {pkgs{1}.dir}; \ __run_test_suite__ (dirs, {}); ' ## the following works, too, but provides no overall summary output as ## __run_test_suite__ does: ## ## else cellfun (@runtests, horzcat (cellfun (@ (dir) ostrsplit (([~, dirs] = system (sprintf ("find %s -type d", dir))), "\n\r", true), dirs, "UniformOutput", false){:})); endif ' check: $(install_stamp) $(run_in_place) --eval $(octave_test_commands) ## ## CLEAN ## .PHONY: clean ARCHDIR := "$(shell $(OCTAVE_CONFIG) -p CANONICAL_HOST_TYPE)-$(shell $(OCTAVE_CONFIG) -p API_VERSION)" clean: clean-tarballs clean-unpacked-release clean-install clean-docs test -e inst/$(ARCHDIR) && rmdir inst/$(ARCHDIR) || true test -e $(target_dir)/fntests.log && rm -f $(target_dir)/fntests.log || true @echo "## Removing target directory (if empty)..." test -e $(target_dir) && rmdir $(target_dir) || true @echo @echo "## Cleaning done" @echo instrument-control-0.9.4/NEWS0000644000000000000000000002222514743226261013051 0ustar00Summary of important user-visible changes for instrument-control 0.9.4 ------------------------------------------------------------------- ** readline: use read terminator if one provided ** SERIALPORT: dont use errno in win32 report of error Summary of important user-visible changes for instrument-control 0.9.3 ------------------------------------------------------------------- ** SERIALPORT: use max VTIME of 5, allow use of case insensive get properties ** TCPCLIENT: add enabletransferdelay property ** UDP, UDPPORT: use memmove for overlapped mem usage ** VXI11: use inst0 as default instrument name ** MODBUS: use input precision when specified in read Summary of important user-visible changes for instrument-control 0.9.2 ------------------------------------------------------------------- ** UDPPORT, UDP: increase buffer read size on larger packets ** General updates to support Octave 9+ ** Updates to package documentation Summary of important user-visible changes for instrument-control 0.9.1 ------------------------------------------------------------------- ** bugfix modbus portnumber input Summary of important user-visible changes for instrument-control 0.9.0 ------------------------------------------------------------------- ** General updates to support Octave 8+ ** readline: updated docs, minor bug fixes ** VXI11: add instrument name support ** UDPPORT: add new writeline function, buffer reading ** UDP: buffer reading Summary of important user-visible changes for instrument-control 0.8.0 ------------------------------------------------------------------- ** MODBUS: Added new modbus class ** TCPSERVER: Added new tcpserver class ** minor bug fixes in configure ** added QT help doc generation ** updates to package documentation ** added common functions: writeline readline readbinblock writebinblock writeread ** TCPCLIENT: bugfix read when used with no size parameter ** UDPPORT: bugfix read when used with no size parameter ** Min octave version is now 4.0 Summary of important user-visible changes for instrument-control 0.7.1 ------------------------------------------------------------------- ** General updates to support Octave 7+ ** Updated common functions fread - set correct size of uint16 fprintf - fix else for multiple args Summary of important user-visible changes for instrument-control 0.7.0 ------------------------------------------------------------------- ** Update get function for instrument controls to not use cellfun (Bug #59581) ** UDPPORT: Added new udpport class ** TCPCLIENT: Added new tcpclient class ** SERIALPORT: update property access to proper case usage Summary of important user-visible changes for instrument-control 0.6.0 ------------------------------------------------------------------- ** SPI: added new spi object and functions ** TCP: added tcpclient, deprecated tcpip added methods flush, read, write ** UDP: added methods flush, read, write Summary of important user-visible changes for instrument-control 0.5.0 ------------------------------------------------------------------- ** General updates to support Octave 6+ ** Added common functions flushinput flushoutput instrhelp ** SERIALPORT: added new serialport object and functions ** SERIAL: use extended win32 serial name for comports so > 10 work. New serial functions: serialbreak Added overload functions for: fprintf fread fwrite Added properties: port Added .property access ** UDP: add .property access to the object Added properties: localhost Updates property timeout to be seconds Updated udp constructor to be closer to matlab compatible ** TCP: add .property access to the object Updates property timeout to be seconds Updated constructor to be closer to matlab compatible ** I2C: Implement object properties Added overload functions for: fread fwrite get set ** PARALLEL: Added overload functions for: fclose fopen fread fwrite ** USBTMC: Added overload functions for: fread fwrite ** VXI11: Added overload functions for: fread fwrite ** insthwinfo: updated to show i2c ports ** added toolkit manual Summary of important user-visible changes for instrument-control 0.4.0 ------------------------------------------------------------------- ** SERIAL: added 'status', 'bytesavailable', 'name' and 'type' properties, and the following functions: seriallist flushinput flushoutput ** UDP: added 'status' and 'bytesavailable' properties and the following functions: flushinput flushoutput ** TCP: added properties to object, added overridden functions: get set fprintf fread fwrite flushinput flushoutput ** tcpip(): added wrapper to be matlab compatible(ish) ** distribute rpc generated files ** verify -M option will work on rpcgen ** detect if rpc_error functions allow use of const inputs ** prefer libtirpc over builtin rpc when detecting vxi11 functionality ** add lock functions used on pkg load/unlock to lock .oct files ** implemented instrhwinfo serial list for mac Summary of important user-visible changes for instrument-control 0.3.1: ------------------------------------------------------------------- ** Updated build to allow install on octave 4.4 ** using polling rather than signal handling to break from instrument reads ** insthwinfo() updated to show enabled modules ** added initial builtin tests for each instrument Summary of important user-visible changes for instrument-control 0.3.0: ------------------------------------------------------------------- ** SERIAL: allow non standard baudrates in win32 ** TCP: new functions: resolvehost ** UDP: new interface with functions for: udp udp_timeout udp_read udp_write udp_close udp_demo ** UDP overload functions for: fprintf fread fwrite fclose fopen get set Summary of important user-visible changes for instrument-control 0.2.3: ------------------------------------------------------------------- ** New function: instrhwinfo ** GPIB: Fix EOI handling ** SERIAL: Fix display of bytesize setting ** SERIAL: Win32: Fix srl_read ** TCP: Fix infinite loop on connection lost Summary of important user-visible changes for instrument-control 0.2.2: ------------------------------------------------------------------- ** GPIB: new function: fread ** SERIAL: Add pinstatus property ** SERIAL: Change display for serial object ** SERIAL: Fix MACOS compilation error ** Fix warnings when using Octave 4.0 Summary of important user-visible changes for instrument-control 0.2.1: ------------------------------------------------------------------- ** GPIB: New functions: spoll trigger clrdevice fopen fclose fwrite fprintf fscanf ** I2C, TCPIP, USBTMC, VXI11: New functions: fopen fclose ** SERIAL: Add Win32 support ** SERIAL: New functions: fclose fopen get set ** SERIAL: Deprecate functions, use set and get instead: srl_baudrate srl_bytesize srl_close srl_flush srl_parity srl_stopbits srl_timeout Summary of important user-visible changes for instrument-control 0.2.0: ------------------------------------------------------------------- ** Support for TCP interface I/O ** Support for USBTMC interface I/O ** Support for GPIB interface I/O ** Support for VXI11 interface I/O ** The following functions are new: tcp tcp_read tcp_write tcp_timeout tcp_close usbtmc usbtmc_read usbtmc_write usbtmc_close gpib gpib_read gpib_write gpib_timeout gpib_close vxi11 vxi11_read vxi11_write vxi11_close ** Interfaces are now compiled seperately (i.e. failed compilation of one interface does not mean fail of whole package) ** Parallel and i2c interface support for FreeBSD platform ** i2c_write no longer accepts strings for data parameter Summary of important user-visible changes for instrument-control 0.1.0: ------------------------------------------------------------------- ** Initial release ** Support for Parallel interface I/O ** Support for Serial interface I/O ** Support for i2c interface I/O ** The following functions are new: serial srl_close srl_read srl_write srl_baudrate srl_flush srl_stopbits srl_bytesize srl_parity srl_timeout i2c i2c_addr i2c_read i2c_close i2c_write parallel pp_ctrl pp_stat pp_close pp_data pp_datadir instrument-control-0.9.4/README.md0000644000000000000000000000255614743226261013636 0ustar00Introduction ============ The Instrument control package provides low level I/O functions for serial, i2c, spi, parallel, tcp, gpib, vxi11, modbus, udp and usbtmc interfaces. It attempts to provide the same function calls as the Matlab toolkit, as well as additional functionality. Requirements ============ * Octave >= 4.0.0 * linux-gpib (Linux only) * libmodbus for MOSBUS support * rpcgen and libtirpc for VXI11 support Installing ========== To install, run the octave package manager: 1. If running Windows, the package may already be installed: type pkg list, to view the installed packages. 2. To install from source forge: pkg install -forge instrument-control 3. To install from a local tarball. pkg install instrument-control-XXXXXXX.tar.gz Where XXXXXXX is the version of the the downloaded tarball. Usage: ====== 1. Load the package. pkg load instrument-control (Required each time Octave is started) 2. Use the function calls to control the instrument hardware. Documentation ============== See the function list for instrument-control on [octave forge](https://octave.sourceforge.io/instrument-control/overview.html) for function documentation. Read the Octave [instrument-control wiki](https://wiki.octave.org/Instrument_control_package) for install tips and examples. Known limitations and bugs ========================== None provided instrument-control-0.9.4/doc/0000755000000000000000000000000014743226261013114 5ustar00instrument-control-0.9.4/doc/functions.texi0000644000000000000000000034657614743226261016044 0ustar00@c --------------------------------------------------- @node Common Functions @section Common Functions @cindex Common Functions @c Common Functions flushinput @c ----------------------------------------- @subsection flushinput @cindex flushinput @deftypefn {} {} flushinput (@var{dev}) Flush the instruments input buffers @subsubheading Inputs @var{dev} - connected device or array of devices @subsubheading Outputs None @xseealso{flushoutput} @end deftypefn @c Common Functions flushoutput @c ----------------------------------------- @subsection flushoutput @cindex flushoutput @deftypefn {} {} flushoutput (@var{dev}) Flush the instruments output buffers @subsubheading Inputs @var{dev} - connected device or array of devices @subsubheading Outputs None @xseealso{flushinput} @end deftypefn @c Common Functions readbinblock @c ----------------------------------------- @subsection readbinblock @cindex readbinblock @deftypefn {} {@var{data} =} readbinblock (@var{dev}) @deftypefnx {} {@var{data} =} readbinblock (@var{dev}, @var{datatype}) read a binblock of data from a instrument device @subsubheading Inputs @var{dev} - connected device @var{datatype} - optional data type to read data as (default 'uint8') @subsubheading Outputs @var{data} - data read @xseealso{flushoutput} @end deftypefn @c Common Functions readline @c ----------------------------------------- @subsection readline @cindex readline @deftypefn {} {@var{data} =} readline (@var{dev}) read data from a instrument device excluding terminator value @subsubheading Inputs @var{dev} - connected device @subsubheading Outputs @var{data} - ASCII data read @xseealso{flushoutput} @end deftypefn @c Common Functions writebinblock @c ----------------------------------------- @subsection writebinblock @cindex writebinblock @deftypefn {} {} writebinblock (@var{dev}, @var{data}, @var{datatype}) Write a IEEE 488.2 binblock of data to a instrument device binblock formatted data is defined as: # where: ASCII number containing the length of part ASCII number containing the number of bytes of Binary data block @subsubheading Inputs @var{dev} - connected device @var{data} - binary data to send @var{datatype} - datatype to send data as @subsubheading Outputs None @xseealso{flushoutput} @end deftypefn @c Common Functions writeline @c ----------------------------------------- @subsection writeline @cindex writeline @deftypefn {} {} writeline (@var{dev}, @var{data}) Write data to a instrument device including terminator value @subsubheading Inputs @var{dev} - connected device @var{data} - ASCII data to write @subsubheading Outputs None @xseealso{flushoutput} @end deftypefn @c Common Functions writeread @c ----------------------------------------- @subsection writeread @cindex writeread @deftypefn {} {@var{data} =} writeread (@var{dev}, @var{command}) write a ASCII command and read data from a instrument device. @subsubheading Inputs @var{dev} - connected device @var{command} - ASCII command @subsubheading Outputs @var{data} - ASCII data read @xseealso{readline, writeline} @end deftypefn @c --------------------------------------------------- @node General @section General @cindex General @c General instrhelp @c ----------------------------------------- @subsection instrhelp @cindex instrhelp @deftypefn {} {} instrhelp () @deftypefnx {} {} instrhelp (@var{funcname}) @deftypefnx {} {} instrhelp (@var{obj}) Display instrument help @subsubheading Inputs @var{funcname} - function to display help about.@* @var{obj} - object to display help about.@* If no input is provided, the function will display and overview of the package functionality. @subsubheading Outputs None @end deftypefn @c General instrhwinfo @c ----------------------------------------- @subsection instrhwinfo @cindex instrhwinfo @deftypefn {Function File} {[@var{list}] =} instrhwinfo () @deftypefnx {Function File} {@var{list} =} instrhwinfo (@var{interface}) Query available hardware for instrument-control When run without any input parameters, instrhwinfo will provide the toolbox information and a list of supported interfaces. @subsubheading Inputs @var{interface} is the instrument interface to query. When provided, instrhwinfo will provide information on the specified interface. Currently only interface "serialport","i2c" and "spi" and is supported, which will provide a list of available serial ports or i2c ports. @subsubheading Outputs If an output variable is provided, the function will store the information to the variable, otherwise it will be displayed to the screen. @subsubheading Example @example instrhwinfo scalar structure containing the fields: ToolboxVersion = 0.4.0 ToolboxName = octave instrument control package SupportedInterfaces = @{ [1,1] = i2c [1,2] = parallel [1,3] = serialport [1,4] = tcp [1,5] = udp [1,6] = usbtmc [1,7] = vxi11 @} @end example @end deftypefn @c General resolvehost @c ----------------------------------------- @subsection resolvehost @cindex resolvehost @deftypefn {Loadable Function} {@var{name} = } resolvehost (@var{host}) @deftypefnx {Loadable Function} {[@var{name}, @var{address}] = } resolvehost (@var{host}) @deftypefnx {Loadable Function} {@var{out} = } resolvehost (@var{host}, @var{returntype}) Resolve a network host name or address to network name and address @subsubheading Inputs @var{host} - Host name or IP address string to resolve.@* @var{name} - Resolved IP host name.@* @var{returntype} - 'name' to get host name, 'address' to get IP address. @subsubheading Outputs @var{name} - Resolved IP host name.@* @var{address} - Resolved IP host address.@* @var{out} - host name if @var{returntype} is 'name', ipaddress if @var{returntype} is 'address'@* @subsubheading Example @example %% get resolved ip name and address of www.gnu.org [name, address] = resolvehost ('www.gnu.org'); %% get ip address of www.gnu.org ipaddress = resolvehost ('www.gnu.org', 'address'); @end example @xseealso{tcp, udp} @end deftypefn @c --------------------------------------------------- @node GPIB @section GPIB @cindex GPIB @c GPIB @octave_gpib/fclose @c ----------------------------------------- @subsection @@octave_gpib/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes connection to GPIB device @var{obj} @end deftypefn @c GPIB @octave_gpib/fopen @c ----------------------------------------- @subsection @@octave_gpib/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens connection to GPIB device @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c GPIB @octave_gpib/fprintf @c ----------------------------------------- @subsection @@octave_gpib/fprintf @cindex fprintf @deftypefn {Function File} {} fprintf (@var{obj}, @var{cmd}) @deftypefnx {Function File} {} fprintf (@var{obj}, @var{format}, @var{cmd}) @deftypefnx {Function File} {} fprintf (@var{obj}, @var{cmd}, @var{mode}) @deftypefnx {Function File} {} fprintf (@var{obj}, @var{format}, @var{cmd}, @var{mode}) Writes string @var{cmd} to GPIB instrument @var{obj} is a GPIB object @var{cmd} String @var{format} Format specifier @var{mode} sync @end deftypefn @c GPIB @octave_gpib/fread @c ----------------------------------------- @subsection @@octave_gpib/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from GPIB instrument @var{obj} is a GPIB object @var{size} Number of values to read. (Default: 100) @var{precision} precision of data @var{count} values read @var{errmsg} read operation error message @end deftypefn @c GPIB @octave_gpib/fscanf @c ----------------------------------------- @subsection @@octave_gpib/fscanf @cindex fscanf @deftypefn {Function File} {@var{res} =} fscanf (@var{obj}) @deftypefnx {Function File} {@var{res} =} fscanf (@var{obj}, @var{format}) @deftypefnx {Function File} {@var{res} =} fscanf (@var{obj}, @var{format}, @var{size}) @deftypefnx {Function File} {[@var{res},@var{count}] =} fscanf (@var{obj}, ...) @deftypefnx {Function File} {[@var{res},@var{count},@var{errmsg}] =} fscanf (@var{obj}, ...) Reads data @var{res} from GPIB instrument @var{obj} is a GPIB object @var{format} Format specifier @var{size} number of values @var{count} values read @var{errmsg} read operation error message @end deftypefn @c GPIB @octave_gpib/fwrite @c ----------------------------------------- @subsection @@octave_gpib/fwrite @cindex fwrite @deftypefn {Function File} {} fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {} fwrite (@var{obj}, @var{data}, @var{precision}) @deftypefnx {Function File} {} fwrite (@var{obj}, @var{data}, @var{mode}) @deftypefnx {Function File} {} fwrite (@var{obj}, @var{data}, @var{precision}, @var{mode}) Writes @var{data} to GPIB instrument @var{obj} is a GPIB object @var{data} data to write @var{precision} precision of data @var{mode} sync @end deftypefn @c GPIB clrdevice @c ----------------------------------------- @subsection clrdevice @cindex clrdevice @deftypefn {Function File} {} clrdevice (@var{obj}) Send clear command to Clear GPIB instrument. @var{obj} is a GPIB object @end deftypefn @c GPIB gpib @c ----------------------------------------- @subsection gpib @cindex gpib @deftypefn {Loadable Function} {@var{gpib} = } gpib ([@var{gpibid}], [@var{timeout}]) Open gpib interface. @var{gpibid} - the interface number.@* @var{timeout} - the interface timeout value. If omitted defaults to blocking call. The gpib() shall return instance of @var{octave_gpib} class as the result @var{gpib}. @end deftypefn @c GPIB gpib_close @c ----------------------------------------- @subsection gpib_close @cindex gpib_close @deftypefn {Loadable Function} {} gpib_close (@var{gpib}) Close the interface and release a file descriptor. @var{gpib} - instance of @var{octave_gpib} class. @end deftypefn @c GPIB gpib_read @c ----------------------------------------- @subsection gpib_read @cindex gpib_read @deftypefn {Loadable Function} {[@var{data}, @var{count}, @var{eoi}] = } gpib_read (@var{gpib}, @var{n}) Read from gpib interface. @var{gpib} - instance of @var{octave_gpib} class.@* @var{n} - number of bytes to attempt to read of type Integer. The gpib_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array. @var{eoi} indicates read operation complete @end deftypefn @c GPIB gpib_timeout @c ----------------------------------------- @subsection gpib_timeout @cindex gpib_timeout @deftypefn {Loadable Function} {} gpib_timeout (@var{gpib}, @var{timeout}) @deftypefnx {Loadable Function} {@var{t} = } gpib_timeout (@var{gpib}) Set new or get existing gpib interface timeout parameter. The timeout value is valid from 0 to 17. @var{gpib} - instance of @var{octave_gpib} class.@* @var{timeout} - Value of 0 means never timeout, 11 means one second and 17 means 1000 seconds (see GPIB documentation (ibtmo) for further details) If @var{timeout} parameter is omitted, the gpib_timeout() shall return current timeout value as the result @var{t}. @end deftypefn @c GPIB gpib_write @c ----------------------------------------- @subsection gpib_write @cindex gpib_write @deftypefn {Loadable Function} {@var{n} = } gpib_write (@var{gpib}, @var{data}) Write data to a gpib interface. @var{gpib} - instance of @var{octave_gpib} class.@* @var{data} - data to be written to the gpib interface. Can be either of String or uint8 type. Upon successful completion, gpib_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c GPIB spoll @c ----------------------------------------- @subsection spoll @cindex spoll @deftypefn {Function File} {@var{out} =} spoll (@var{obj}) @deftypefnx {Function File} {[@var{out},@var{statusByte}] =} spoll (@var{obj}) Serial polls GPIB instruments. @var{obj} is a GPIB object or a cell array of GPIB objects @var{out} GPIB objects ready for service @var{statusByte} status Byte @end deftypefn @c GPIB trigger @c ----------------------------------------- @subsection trigger @cindex trigger @deftypefn {Function File} {} trigger (@var{obj}) Triggers GPIB instrument. @var{obj} is a GPIB object @end deftypefn @c --------------------------------------------------- @node I2C @section I2C @cindex I2C @c I2C @octave_i2c/fclose @c ----------------------------------------- @subsection @@octave_i2c/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes I2C connection @var{obj} @end deftypefn @c I2C @octave_i2c/fopen @c ----------------------------------------- @subsection @@octave_i2c/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens I2C connection @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c I2C @octave_i2c/fread @c ----------------------------------------- @subsection @@octave_i2c/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from I2C instrument @subsubheading Inputs @var{obj} is a I2C object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} data values.@* @var{count} number of values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c I2C @octave_i2c/fwrite @c ----------------------------------------- @subsection @@octave_i2c/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to I2C instrument @subsubheading Inputs @var{obj} is a I2C object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c I2C @octave_i2c/get @c ----------------------------------------- @subsection @@octave_i2c/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{i2c}) @deftypefnx {Function File} {@var{field} = } get (@var{i2c}, @var{property}) Get the properties of i2c object. @subsubheading Inputs @var{i2c} - instance of @var{octave_i2c} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_i2c/set} @end deftypefn @c I2C @octave_i2c/set @c ----------------------------------------- @subsection @@octave_i2c/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of i2c object. @subsubheading Inputs @var{obj} - instance of @var{octave_i2c} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'name' Set the name for the i2c socket. @item 'remoteaddress' Set the remote address for the i2c socket. @end table @subsubheading Outputs None @xseealso{@@octave_i2c/get} @end deftypefn @c I2C i2c @c ----------------------------------------- @subsection i2c @cindex i2c @deftypefn {Loadable Function} {@var{i2c} = } i2c ([@var{port_path}], [@var{address}]) Open i2c interface. @subsubheading Inputs @var{port_path} - the interface device port/path of type String. If omitted defaults to '/dev/i2c-0'. @* @var{address} - the slave device address. If omitted must be set using i2c_addr() call. @subsubheading Outputs @var{i2c} - An instance of @var{octave_i2c} class. @subsubheading Properties The i2c object has the following properties: @table @asis @item name Name of the object @item remoteaddress the slave device address @item port The interface driver port (readonly) @end table @end deftypefn @c I2C i2c_addr @c ----------------------------------------- @subsection i2c_addr @cindex i2c_addr @deftypefn {Loadable Function} {} i2c_addr (@var{i2c}, @var{address}) @deftypefnx {Loadable Function} {@var{addr} = } i2c_addr (@var{i2c}) Set new or get existing i2c slave device address. @subsubheading Inputs @var{i2c} - instance of @var{octave_i2c} class.@* @var{address} - i2c slave device address of type Integer. The address is passed in the 7 or 10 lower bits of the argument. @subsubheading Outputs @var{addr} - If @var{address} parameter is omitted, the i2c_addr() shall return current i2c slave device address. @end deftypefn @c I2C i2c_close @c ----------------------------------------- @subsection i2c_close @cindex i2c_close @deftypefn {Loadable Function} {} i2c_close (@var{i2c}) Close the interface and release a file descriptor. @subsubheading Inputs @var{i2c} - instance of @var{octave_i2c} class.@* @subsubheading Outputs None @end deftypefn @c I2C i2c_read @c ----------------------------------------- @subsection i2c_read @cindex i2c_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } i2c_read (@var{i2c}, @var{n}) Read from i2c slave device. @subsubheading Inputs @var{i2c} - instance of @var{octave_i2c} class.@* @var{n} - number of bytes to attempt to read of type Integer. @subsubheading Outputs The i2c_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array. @end deftypefn @c I2C i2c_write @c ----------------------------------------- @subsection i2c_write @cindex i2c_write @deftypefn {Loadable Function} {@var{n} = } i2c_write (@var{i2c}, @var{data}) Write data to a i2c slave device. @subsubheading Inputs @var{i2c} - instance of @var{octave_i2c} class.@* @var{data} - data, of type uint8, to be written to the slave device. @subsubheading Outputs Upon successful completion, i2c_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c --------------------------------------------------- @node Modbus @section Modbus @cindex Modbus @c Modbus @octave_modbus/get @c ----------------------------------------- @subsection @@octave_modbus/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{dev}) @deftypefnx {Function File} {@var{field} = } get (@var{dev}, @var{property}) Get the properties of modbus object. @subsubheading Inputs @var{dev} - instance of @var{octave_modbus} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_modbus/set} @end deftypefn @c Modbus @octave_modbus/maskWrite @c ----------------------------------------- @subsection @@octave_modbus/maskWrite @cindex maskWrite @deftypefn {} {@var{data} =} maskWrite (@var{dev}, @var{address}, @var{andmask}, @var{ormask}) @deftypefnx {} {@var{data} =} maskWrite (@var{dev}, @var{address}, @var{andmask}, @var{ormask}, @var{serverid}) Read holding register at @var{address} from modbus device @var{dev} apply masking and write the change data. writeregister value = (readregister value AND andMask) OR (orMask AND (NOT andMask)) @subsubheading Inputs @var{dev} - connected modbus device @var{address} - address to read from. @var{andmask} - AND mask to apply to the register @var{ormask} - OR mask to apply to the register @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. @subsubheading Outputs @var{data} - data read from the device @xseealso{modbus} @end deftypefn @c Modbus @octave_modbus/read @c ----------------------------------------- @subsection @@octave_modbus/read @cindex read @deftypefn {} {@var{data} =} read (@var{dev}, @var{target}, @var{address}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{target}, @var{address}, @var{count}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{target}, @var{address}, @var{count}, @var{serverId}, @var{precision}) Read data from modbus device @var{dev} target @var{target} starting at address @var{address}. @subsubheading Inputs @var{dev} - connected modbus device @var{target} - target type to read. One of 'coils', 'inputs', 'inputregs' or 'holdingregs' @var{address} - address to start reading from. @var{count} - number of elements to read. If not provided, count is 1. @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. @var{precision} - Optional precision for how to interpret the read data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. @subsubheading Outputs @var{data} - data read from the device @xseealso{modbus} @end deftypefn @c Modbus @octave_modbus/set @c ----------------------------------------- @subsection @@octave_modbus/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of modbus object. @subsubheading Inputs @var{obj} - instance of @var{octave_modbus} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'Name' Set the stored string name of the object. @item 'Timeout' Set the timeout value. @item 'Numretries' Set the numretries value. @item 'ByteOrder' Set the byteorder value @item 'WordOrder' Set the wordorder value @item 'UserData' Set the userdata value @end table @subsubheading Outputs None @xseealso{@@octave_modbus/get} @end deftypefn @c Modbus @octave_modbus/write @c ----------------------------------------- @subsection @@octave_modbus/write @cindex write @deftypefn {} {} write (@var{dev}, @var{target}, @var{address}, @var{values}) @deftypefnx {} {} read (@var{dev}, @var{target}, @var{address}, @var{values}, @var{serverId}, @var{precision}) Write data @var{data} to modbus device @var{dev} target @var{target} starting at address @var{address}. @subsubheading Inputs @var{dev} - connected modbus device @var{target} - target type to read. One of 'coils' or 'holdingregs' @var{address} - address to start reading from. @var{data} - data to write. @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. @var{precision} - Optional precision for how to interpret the write data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. @subsubheading Outputs None @xseealso{modbus} @end deftypefn @c Modbus @octave_modbus/writeRead @c ----------------------------------------- @subsection @@octave_modbus/writeRead @cindex writeRead @deftypefn {} {@var{data} =} writeRead (@var{dev}, @var{writeAddress}, @var{values}, @var{readAddress}, @var{readcount}) @deftypefnx {} {@var{data} =} writeRead (@var{dev}, @var{writeAddress}, @var{values}, @var{readAddress}, @var{readcount}, @var{serverId}) @deftypefnx {} {@var{data} =} writeRead (@var{dev}, @var{writeAddress}, @var{values}, @var{writePrecision}, @var{readAddress}, @var{readCount}, @var{readPrecision}) Write data @var{values} to the modbus device @var{dev} holding registers starting at address @var{writeAddress} and then read @var{readCount} register values starting at address @var{readAddress}. @subsubheading Inputs @var{dev} - connected modbus device @var{writeAddress} - address to start writing to. @var{values} - data to write to the device. @var{readAddress} - address to start reading from. @var{readCount} - number of elements to read. @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. @var{precision} - Optional precision for how to interpret the read data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. @subsubheading Outputs @var{data} - data read from the device @xseealso{modbus} @end deftypefn @c Modbus modbus @c ----------------------------------------- @subsection modbus @cindex modbus @deftypefn {Loadable Function} {@var{dev} = } modbus ('tcpip', @var{deviceaddress}) @deftypefnx {Loadable Function} {@var{dev} = } modbus ('tcpip', @var{deviceaddress}, @var{remoteport}) @deftypefnx {Loadable Function} {@var{dev} = } modbus ('tcpip', @var{deviceaddress}, @var{name}, @var{value}) @deftypefnx {Loadable Function} {@var{dev} = } modbus ('serialrtu', @var{serialport}) @deftypefnx {Loadable Function} {@var{dev} = } modbus ('serialrtu', @var{serialport}, @var{name}, @var{value}) Open modbus interface using a specified transport of 'tcpip' or 'serialrtu'. @subsubheading Inputs @var{deviceaddress} - the device ip address of type String.@* @var{remoteport} - the device remote port number. If not specified, a default of 502 will be used.@* @var{name}, @var{value} - Optional name value pairs for setting properties of the object.@* @var{serialport} - the name of the serial port to connect to. It must be specified when transport is 'serialrtu'.@* @subsubheading Common Input Name, Value pairs @table @asis @item Timeout timeout value used for waiting for data @item NumRetries number of retries after a timeout @item UserData Additional data to attach to the object @end table @subsubheading Serial RTU Input Name, Value pairs @table @asis @item BaudRate Baudrate for the serial port @item DataBits number of databits for serial port @item Parity Parity for serial port ('odd', 'even' or 'none') @item StopBits number of stopbits for serial port @end table @subsubheading Outputs The modbus() shall return instance of @var{octave_modbus} class as the result @var{modbus}. @subsubheading Properties The modbus object has the following public properties: @table @asis @item Name name assigned to the modbus object @item Type instrument type 'modbus' (readonly) @item Port Remote port number or serial port name (readonly) @item DeviceAddress Device address if transport was 'tcpip' (readonly) @item Status status of the object 'open' or 'closed' (readonly) @item Timeout timeout value used for waiting for data @item NumRetries number of retries after a timeout @item UserData Additional data to attach to the object @end table @end deftypefn @c --------------------------------------------------- @node Parallel @section Parallel @cindex Parallel @c Parallel @octave_parallel/fclose @c ----------------------------------------- @subsection @@octave_parallel/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes parallel connection @var{obj} @end deftypefn @c Parallel @octave_parallel/fopen @c ----------------------------------------- @subsection @@octave_parallel/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens parallel interface @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c Parallel @octave_parallel/fread @c ----------------------------------------- @subsection @@octave_parallel/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from parallel instrument @subsubheading Inputs @var{obj} is a parallel object.@* @var{size} Number of values to read. (Default: 1).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} The read data.@* @var{count} values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c Parallel @octave_parallel/fwrite @c ----------------------------------------- @subsection @@octave_parallel/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to parallel instrument @subsubheading Inputs @var{obj} is a parallel object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c Parallel parallel @c ----------------------------------------- @subsection parallel @cindex parallel @deftypefn {Loadable Function} {@var{parallel} = } parallel ([@var{path}], [@var{direction}]) Open Parallel interface. @subsubheading Inputs @var{path} - the interface path of type String. If omitted defaults to '/dev/parport0'.@* @var{direction} - the direction of interface drivers of type Integer, see: PP_DATADIR for more info. If omitted defaults to 1 (Input). @subsubheading Outputs The parallel() shall return instance of @var{octave_parallel} class as the result @var{parallel}. @end deftypefn @c Parallel pp_close @c ----------------------------------------- @subsection pp_close @cindex pp_close @deftypefn {Loadable Function} {} pp_close (@var{parallel}) Close the interface and release a file descriptor. @subsubheading Inputs @var{parallel} - instance of @var{octave_serial} class.@* @subsubheading Outputs None @end deftypefn @c Parallel pp_ctrl @c ----------------------------------------- @subsection pp_ctrl @cindex pp_ctrl @deftypefn {Loadable Function} {} pp_ctrl (@var{parallel}, @var{ctrl}) @deftypefnx {Loadable Function} {@var{c} = } pp_ctrl (@var{parallel}) Sets or Read the Control lines. @subsubheading Inputs @var{parallel} - instance of @var{octave_parallel} class.@* @var{ctrl} - control parameter to be set of type Byte. @subsubheading Outputs If @var{ctrl} parameter is omitted, the pp_ctrl() shall return current Control lines state as the result @var{c}. @end deftypefn @c Parallel pp_data @c ----------------------------------------- @subsection pp_data @cindex pp_data @deftypefn {Loadable Function} {} pp_data (@var{parallel}, @var{data}) @deftypefnx {Loadable Function} {@var{d} = } pp_data (@var{parallel}) Sets or Read the Data lines. @subsubheading Inputs @var{parallel} - instance of @var{octave_parallel} class.@* @var{data} - data parameter to be set of type Byte. @subsubheading Outputs If @var{data} parameter is omitted, the pp_data() shall return current Data lines state as the result @var{d}. @end deftypefn @c Parallel pp_datadir @c ----------------------------------------- @subsection pp_datadir @cindex pp_datadir @deftypefn {Loadable Function} {} pp_datadir (@var{parallel}, @var{direction}) @deftypefnx {Loadable Function} {@var{dir} = } pp_datadir (@var{parallel}) Controls the Data line drivers. Normally the computer's parallel port will drive the data lines, but for byte-wide transfers from the peripheral to the host it is useful to turn off those drivers and let the peripheral drive the signals. (If the drivers on the computer's parallel port are left on when this happens, the port might be damaged.) @subsubheading Inputs @var{parallel} - instance of @var{octave_parallel} class.@* @var{direction} - direction parameter of type Integer. Supported values: 0 - the drivers are turned on (Output/Forward direction); 1 - the drivers are turned off (Input/Reverse direction). @subsubheading Outputs If @var{direction} parameter is omitted, the pp_datadir() shall return current Data direction as the result @var{dir}. @end deftypefn @c Parallel pp_stat @c ----------------------------------------- @subsection pp_stat @cindex pp_stat @deftypefn {Loadable Function} {@var{stat} = } pp_stat (@var{parallel}) Reads the Status lines. @subsubheading Inputs @var{parallel} - instance of @var{octave_parallel} class.@* @subsubheading Outputs The pp_stat() shall return current Status lines state as the result @var{stat}. @end deftypefn @c --------------------------------------------------- @node Serial (Deprecated) @section Serial (Deprecated) @cindex Serial (Deprecated) @c Serial (Deprecated) @octave_serial/fclose @c ----------------------------------------- @subsection @@octave_serial/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes SERIAL connection @var{obj} @end deftypefn @c Serial (Deprecated) @octave_serial/flushinput @c ----------------------------------------- @subsection @@octave_serial/flushinput @cindex flushinput @deftypefn {Loadable Function} {} flushinput (@var{serial}) Flush the pending input, which will also make the BytesAvailable property be 0. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class. @subsubheading Outputs None @xseealso{srl_flush, flushoutput} @end deftypefn @c Serial (Deprecated) @octave_serial/flushoutput @c ----------------------------------------- @subsection @@octave_serial/flushoutput @cindex flushoutput @deftypefn {Loadable Function} {} flushoutput (@var{serial}) Flush the output buffer. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class. @subsubheading Outputs None @xseealso{srl_flush, flushinput} @end deftypefn @c Serial (Deprecated) @octave_serial/fopen @c ----------------------------------------- @subsection @@octave_serial/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens SERIAL interface @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c Serial (Deprecated) @octave_serial/fprintf @c ----------------------------------------- @subsection @@octave_serial/fprintf @cindex fprintf @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) Writes formatted string @var{template} using optional parameters to serial instrument @subsubheading Inputs @var{obj} is a serial object.@* @var{template} Format template string @subsubheading Outputs @var{numbytes} - number of bytes written to the serial device. @end deftypefn @c Serial (Deprecated) @octave_serial/fread @c ----------------------------------------- @subsection @@octave_serial/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from serial instrument @subsubheading Inputs @var{obj} is a serial object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} The read data.@* @var{count} values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c Serial (Deprecated) @octave_serial/fwrite @c ----------------------------------------- @subsection @@octave_serial/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to serial instrument @subsubheading Inputs @var{obj} is a serial object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c Serial (Deprecated) @octave_serial/get @c ----------------------------------------- @subsection @@octave_serial/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{serial}) @deftypefnx {Function File} {@var{field} = } get (@var{serial}, @var{property}) Get the properties of serial object. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_serial/set} @end deftypefn @c Serial (Deprecated) @octave_serial/serialbreak @c ----------------------------------------- @subsection @@octave_serial/serialbreak @cindex serialbreak @deftypefn {Function File} {} serialbreak (@var{serial}) @deftypefnx {Function File} {} serialbreak (@var{serial}, @var{time}) Send a break to the serial port @subsubheading Inputs @var{serial} - serial object@* @var{time} - number of milliseconds to break for. If not specified a value of 10 will be used. @subsubheading Outputs None @xseealso{serial} @end deftypefn @c Serial (Deprecated) @octave_serial/set @c ----------------------------------------- @subsection @@octave_serial/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of serial object. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'baudrate' Set the baudrate of serial port. Supported values by instrument-control: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your serial port may be different. @item 'bytesize' Set the bytesize. Supported values: 5, 6, 7 and 8. @item 'name' Set the stored string name of the serial object. @item 'parity' Set the parity value. Supported values: Even/Odd/None. This Parameter must be of type string. It is case insensitive and can be abbreviated to the first letter only @item 'stopbits' Set the number of stopbits. Supported values: 1, 2. @item 'timeout' Set the timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds). @item 'requesttosend' Set the requesttosend (RTS) line. @item 'dataterminalready' Set the dataterminalready (DTR) line. @end table @subsubheading Outputs None @xseealso{@@octave_serial/get} @end deftypefn @c Serial (Deprecated) @octave_serial/srl_baudrate @c ----------------------------------------- @subsection @@octave_serial/srl_baudrate @cindex srl_baudrate @deftypefn {Loadable Function} {} srl_baudrate (@var{serial}, @var{baudrate})\ @deftypefnx {Loadable Function} {@var{br} = } srl_baudrate (@var{serial}) Set new or get existing serial interface baudrate parameter. Only standard values are supported. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{baudrate} - the baudrate value used. Supported values: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600 19200, 38400, 57600, 115200 and 230400.@* If @var{baudrate} parameter is omitted, the srl_baudrate() shall return current baudrate value as the result @var{br}. @subsubheading Outputs @var{br} - The currently set baudrate This function is obsolete. Use get and set method instead. @end deftypefn @c Serial (Deprecated) @octave_serial/srl_bytesize @c ----------------------------------------- @subsection @@octave_serial/srl_bytesize @cindex srl_bytesize @deftypefn {Loadable Function} {} srl_bytesize (@var{serial}, @var{bsize}) @deftypefnx {Loadable Function} {@var{bs} = } srl_bytesize (@var{serial}) Set new or get existing serial interface byte size parameter. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{bsize} - byte size of type Integer. Supported values: 5/6/7/8.@* If @var{bsize} parameter is omitted, the srl_bytesize() shall return current byte size value or in case of unsupported setting -1, as the result @var{bs}. This function is obsolete. Use get and set method instead. @subsubheading Outputs @var{bs} -the currently set byte size. @end deftypefn @c Serial (Deprecated) @octave_serial/srl_close @c ----------------------------------------- @subsection @@octave_serial/srl_close @cindex srl_close @deftypefn {Loadable Function} {} srl_close (@var{serial}) Close the interface and release a file descriptor. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class. This function is obsolete. Use fclose() method instead. @subsubheading Outputs None @end deftypefn @c Serial (Deprecated) @octave_serial/srl_flush @c ----------------------------------------- @subsection @@octave_serial/srl_flush @cindex srl_flush @deftypefn {Loadable Function} {} srl_flush (@var{serial}, [@var{q}]) Flush the pending input/output. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{q} - queue selector of type Integer. Supported values:@* @table @asis @item 0 flush untransmitted output @item 1 flush pending input @item 2 flush both pending input and untransmitted output. @end table If @var{q} parameter is omitted, the srl_flush() shall flush both, input and output buffers. @subsubheading Outputs None @end deftypefn @c Serial (Deprecated) @octave_serial/srl_parity @c ----------------------------------------- @subsection @@octave_serial/srl_parity @cindex srl_parity @deftypefn {Loadable Function} {} srl_parity (@var{serial}, @var{parity}) @deftypefnx {Loadable Function} {@var{p} = } srl_parity (@var{serial}) Set new or get existing serial interface parity parameter. Even/Odd/None values are supported. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{parity} - parity value of type String. Supported values: Even/Odd/None (case insensitive, can be abbreviated to the first letter only)@* If @var{parity} parameter is omitted, the srl_parity() shall return current parity value as the result @var{p}. This function is obsolete. Use get and set method instead. @subsubheading Outputs @var{p} - The currently set parity @end deftypefn @c Serial (Deprecated) @octave_serial/srl_stopbits @c ----------------------------------------- @subsection @@octave_serial/srl_stopbits @cindex srl_stopbits @deftypefn {Loadable Function} {} srl_stopbits (@var{serial}, @var{stopb}) @deftypefnx {Loadable Function} {@var{sb} = } srl_stopbits (@var{serial}) Set new or get existing serial interface stop bits parameter. Only 1 or 2 stop bits are supported. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{stopb} - number of stop bits used. Supported values: 1, 2.@* @subsubheading Outputs If @var{stopb} parameter is omitted, the srl_stopbits() shall return current stop bits value as the result @var{sb}. This function is obsolete. Use get and set method instead. @end deftypefn @c Serial (Deprecated) @octave_serial/srl_timeout @c ----------------------------------------- @subsection @@octave_serial/srl_timeout @cindex srl_timeout @deftypefn {Loadable Function} {} srl_timeout (@var{serial}, @var{timeout}) @deftypefnx {Loadable Function} {@var{t} = } srl_timeout (@var{serial}) Set new or get existing serial interface timeout parameter used for srl_read() requests. The timeout value is specified in tenths of a second. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{timeout} - srl_read() timeout value in tenths of a second. A value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds).@* @subsubheading Outputs If @var{timeout} parameter is omitted, the srl_timeout() shall return current timeout value as the result @var{t}. This function is obsolete. Use get and set method instead. @end deftypefn @c Serial (Deprecated) serial @c ----------------------------------------- @subsection serial @cindex serial @deftypefn {Loadable Function} {@var{serial} = } serial ([@var{path}], [@var{baudrate}], [@var{timeout}]) Open serial interface. @subsubheading Inputs @var{path} - the interface path of type String. @* @var{baudrate} - the baudrate of interface. If omitted defaults to 115200. @* @var{timeout} - the interface timeout value. If omitted defaults to blocking call. @subsubheading Outputs The serial() shall return an instance of @var{octave_serial} class as the result @var{serial}. @subsubheading Properties The serial object has the following public properties: @table @asis @item name name assigned to the object @item type instrument type 'serial' (readonly) @item port OS specific port name (readonly) @item status status of the object 'open' or 'closed' (readonly) @item timeout timeout value used for waiting for data @item bytesavailable number of bytes currently available to read (readonly) @item stopbits number of stopbits to use @item requesttosend request to send state - 'on' or 'off' @item parity Parity setting 'none', 'even', 'odd' @item bytesize Number of bits to a byte (7 or 8) @item baudrate Baudrate setting @item dataterminalready state of dataterminal ready - 'on' or 'off' @item pinstatus current state of pins (readonly) @end table @end deftypefn @c Serial (Deprecated) seriallist @c ----------------------------------------- @subsection seriallist @cindex seriallist @deftypefn {Function File} {@var{list} = } seriallist () Returns a list of all serial ports detected in the system. @subsubheading Inputs None @subsubheading Outputs @var{list} is a string cell array of serial ports names detected in the system. @xseealso{instrhwinfo("serial")} @end deftypefn @c Serial (Deprecated) srl_read @c ----------------------------------------- @subsection srl_read @cindex srl_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } srl_read (@var{serial}, @var{n}) Read from serial interface. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{n} - number of bytes to attempt to read of type Integer. @subsubheading Outputs The srl_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array. @end deftypefn @c Serial (Deprecated) srl_write @c ----------------------------------------- @subsection srl_write @cindex srl_write @deftypefn {Loadable Function} {@var{n} = } srl_write (@var{serial}, @var{data}) Write data to a serial interface. @subsubheading Inputs @var{serial} - instance of @var{octave_serial} class.@* @var{data} - data to be written to the serial interface. Can be either of String or uint8 type. @subsubheading Outputs Upon successful completion, srl_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c --------------------------------------------------- @node Serial Port @section Serial Port @cindex Serial Port @c Serial Port @octave_serialport/configureTerminator @c ----------------------------------------- @subsection @@octave_serialport/configureTerminator @cindex configureTerminator @deftypefn {Function File} {} configureTerminator (@var{serial}, @var{term}) @deftypefnx {Function File} {} configureTerminator (@var{serial}, @var{readterm}, @var{writeterm}) Set terminator for ASCII string manipulation @subsubheading Inputs @var{serial} - serialport object@* @var{term} - terminal value for both read and write@* @var{readterm} = terminal value type for read data@* @var{writeterm} = terminal value for written data@* The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. @subsubheading Outputs None @xseealso{serialport} @end deftypefn @c Serial Port @octave_serialport/flush @c ----------------------------------------- @subsection @@octave_serialport/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the serial port buffers @subsubheading Inputs @var{dev} - connected serialport device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{serialport} @end deftypefn @c Serial Port @octave_serialport/fprintf @c ----------------------------------------- @subsection @@octave_serialport/fprintf @cindex fprintf @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) Writes formatted string @var{template} using optional parameters to serialport instrument @subsubheading Inputs @var{obj} is a serialport object.@* @var{template} Format template string @subsubheading Outputs @var{numbytes} - number of bytes written to the serial device. @end deftypefn @c Serial Port @octave_serialport/fread @c ----------------------------------------- @subsection @@octave_serialport/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from serial port instrument @subsubheading Inputs @var{obj} is a serialport object.@* @var{size} Number of values to read.@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} The read data.@* @var{count} number of values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c Serial Port @octave_serialport/fwrite @c ----------------------------------------- @subsection @@octave_serialport/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to serial port instrument @subsubheading Inputs @var{obj} is a serial port object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c Serial Port @octave_serialport/get @c ----------------------------------------- @subsection @@octave_serialport/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{serial}) @deftypefnx {Function File} {@var{field} = } get (@var{serial}, @var{property}) Get the properties of serialport object. @subsubheading Inputs @var{serial} - instance of @var{octave_serialport} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_serial/set} @end deftypefn @c Serial Port @octave_serialport/getpinstatus @c ----------------------------------------- @subsection @@octave_serialport/getpinstatus @cindex getpinstatus @deftypefn {Function File} {@var{status}} getpinstatus (@var{serial}) Get status of serial pins @subsubheading Inputs @var{serial} - serial object@* @subsubheading Outputs @var{status} - a structure with the logic names of ClearToSend, DataSetReady, CarrierDetect, and RingIndicator @xseealso{serialport} @end deftypefn @c Serial Port @octave_serialport/read @c ----------------------------------------- @subsection @@octave_serialport/read @cindex read @deftypefn {} {@var{data} =} read (@var{dev}, @var{count}) @deftypefnx {} {@var{data} =} read (@var{dev}, @var{count}, @var{precision}) Read a specified number of values from a serialport using optional precision for valuesize. @subsubheading Inputs @var{dev} - connected serialport device @var{count} - number of elements to read @var{precision} - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16, uint32, int32, uint64, uint64 @subsubheading Outputs @var{data} - data read from the device @xseealso{serialport} @end deftypefn @c Serial Port @octave_serialport/serialbreak @c ----------------------------------------- @subsection @@octave_serialport/serialbreak @cindex serialbreak @deftypefn {Function File} {} serialbreak (@var{serial}) @deftypefnx {Function File} {} serialbreak (@var{serial}, @var{time}) Send a break to the serial port @subsubheading Inputs @var{serial} - serialport object@* @var{time} - number of milliseconds to break for. If not specified a value of 10 will be used. @subsubheading Outputs None @xseealso{serial} @end deftypefn @c Serial Port @octave_serialport/set @c ----------------------------------------- @subsection @@octave_serialport/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of serialport object. @subsubheading Inputs @var{serial} - instance of @var{octave_serialport} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'baudrate' Set the baudrate of serial port. Supported values by instrument-control: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your serial port may be different. @item 'bytesize' Set the bytesize. Supported values: 5, 6, 7 and 8. @item 'name' Set the stored string name of the serial object. @item 'parity' Set the parity value. Supported values: Even/Odd/None. This Parameter must be of type string. It is case insensitive and can be abbreviated to the first letter only @item 'stopbits' Set the number of stopbits. Supported values: 1, 2. @item 'timeout' Set the timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds). @item 'requesttosend' Set the requesttosend (RTS) line. @item 'dataterminalready' Set the dataterminalready (DTR) line. @end table @subsubheading Outputs None @xseealso{@@octave_serialport/-get} @end deftypefn @c Serial Port @octave_serialport/setDTR @c ----------------------------------------- @subsection @@octave_serialport/setDTR @cindex setDTR @deftypefn {} {} setDTR (@var{dev}, @var{true_false}) Set the state of the DTR line @subsubheading Inputs @var{dev} - connected serial device.@* @var{true_false} - state to set the line.@* @subsubheading Outputs None @xseealso{serialport, getpinstatus, setRTS} @end deftypefn @c Serial Port @octave_serialport/setRTS @c ----------------------------------------- @subsection @@octave_serialport/setRTS @cindex setRTS @deftypefn {} {} setRTS (@var{dev}, @var{true_false}) Set the state of the RTS line @subsubheading Inputs @var{dev} - connected serial device.@* @var{true_false} - state to set the line.@* @subsubheading Outputs None @xseealso{serialport, getpinstatus} @end deftypefn @c Serial Port @octave_serialport/write @c ----------------------------------------- @subsection @@octave_serialport/write @cindex write @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to serialport instrument @subsubheading Inputs @var{obj} is a serialport object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c Serial Port serialport @c ----------------------------------------- @subsection serialport @cindex serialport @deftypefn {Loadable Function} {@var{serial} = } serialport ([@var{path}], [@var{baudrate}]) @deftypefnx {Loadable Function} {@var{serial} = } serialport ([@var{path}], [@var{propname}, @var{propvalue}]) Open serial port interface. @subsubheading Inputs @var{path} - the interface path of type String. @* @var{baudrate} - the baudrate of interface.@* @var{propname},@var{propvalue} - property name/value pairs. Known input properties: @table @asis @item BaudRate Numeric baudrate value @item Timeout Numeric timeout value in seconds or -1 to wait forever @item StopBits number of stopbits to use @item Parity Parity setting 'none', 'even', 'odd' @item DataBits Number of bits to a byte (5 to 8) @item FlowControl Number of bits to a byte 'none', 'hardware', 'software' @end table @subsubheading Outputs The serialport() shall return an instance of @var{octave_serialport} class as the result @var{serial}. @subsubheading Properties The serial object has the following public properties: @table @asis @item Name name assigned to the object @item Type instrument type 'serial' (readonly) @item Port OS specific port name (readonly) @item Status status of the object 'open' or 'closed' (readonly) @item Timeout timeout value used for waiting for data @item NumBytesAvailable number of bytes currently available to read (readonly) @item NumBytesWritten number of bytes written (readonly) @item StopBits number of stopbits to use @item Parity Parity setting 'none', 'even', 'odd' @item DataBits Number of bits to a byte (5 to 8) @item BaudRate Baudrate setting @item FlowControl Number of bits to a byte 'none', 'hardware', 'software' @item PinStatus current state of pins (readonly) @item UserData user defined data @end table @end deftypefn @c Serial Port serialportlist @c ----------------------------------------- @subsection serialportlist @cindex serialportlist @deftypefn {Function File} {@var{list} = } serialportlist () @deftypefnx {Function File} {@var{list} = } serialportlist ("all") @deftypefnx {Function File} {@var{list} = } serialportlist ("available") Returns a list of all serial ports detected in the system. @subsubheading Inputs 'all' - show all serial ports (same as providing no arguments) 'available' - show only serial ports that are available for use @subsubheading Outputs @var{list} is a string cell array of serial ports names detected in the system. @xseealso{instrhwinfo("serialport")} @end deftypefn @c --------------------------------------------------- @node SPI @section SPI @cindex SPI @c SPI @octave_spi/fclose @c ----------------------------------------- @subsection @@octave_spi/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes SPI connection @var{obj} @end deftypefn @c SPI @octave_spi/fopen @c ----------------------------------------- @subsection @@octave_spi/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens SPI connection @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c SPI @octave_spi/fread @c ----------------------------------------- @subsection @@octave_spi/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from a SPI instrument @subsubheading Inputs @var{obj} is a SPI object.@* @var{size} Number of values to read. (Default: 10).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} data values.@* @var{count} number of values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c SPI @octave_spi/fwrite @c ----------------------------------------- @subsection @@octave_spi/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to SPI instrument @subsubheading Inputs @var{obj} is a SPI object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c SPI @octave_spi/get @c ----------------------------------------- @subsection @@octave_spi/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{spi}) @deftypefnx {Function File} {@var{field} = } get (@var{spi}, @var{property}) Get the properties of spi object. @subsubheading Inputs @var{spi} - instance of @var{octave_spi} class.@* @var{property} - name of property.@* @subsubheading Properties @table @var @item 'name' Name for the spi socket. @item 'bitrate' The bitrate for the spi object. @item 'clockpolarity' The clock polarity for the spi object of 'idlehigh' or 'idlelow'. @item 'clockphase' The clock phase for the spi object of 'firstedge' or 'secondedge'. @item 'port' The device port name. @item 'status' The device status of 'open' or 'closed' @end table @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_spi/set} @end deftypefn @c SPI @octave_spi/read @c ----------------------------------------- @subsection @@octave_spi/read @cindex read @deftypefn {Function File} {@var{data} =} read (@var{obj}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) Reads @var{data} from SPI instrument @subsubheading Inputs @var{obj} is a SPI object.@* @var{size} Number of values to read. (Default: 10).@* @subsubheading Outputs @var{data} data values.@* @end deftypefn @c SPI @octave_spi/set @c ----------------------------------------- @subsection @@octave_spi/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of spi object. @subsubheading Inputs @var{obj} - instance of @var{octave_spi} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'name' Set the name for the spi socket. @item 'bitrate' Set the bitrate for the spi object. @item 'clockpolarity' Set the clock polarity for the spi object of 'idlehigh' or 'idlelow'. @item 'clockphase' Set the clock phase for the spi object of 'firstedge' or 'secondedge'. @end table @subsubheading Outputs None @xseealso{@@octave_spi/get} @end deftypefn @c SPI @octave_spi/write @c ----------------------------------------- @subsection @@octave_spi/write @cindex write @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) Writes @var{data} to SPI instrument @subsubheading Inputs @var{obj} is a SPI object.@* @var{data} data to write.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c SPI @octave_spi/writeAndRead @c ----------------------------------------- @subsection @@octave_spi/writeAndRead @cindex writeAndRead @deftypefn {Function File} {@var{data} =} writeAndRead (@var{obj}, @var{wrdata}) Writes and reads @var{data} from SPI instrument @subsubheading Inputs @var{obj} is a SPI object.@* @var{wrdata} Data to write.@* @subsubheading Outputs @var{data} data values read.@* @end deftypefn @c SPI spi @c ----------------------------------------- @subsection spi @cindex spi @deftypefn {Loadable Function} {@var{spi} = } spi ([@var{port_path}]) @deftypefnx {Loadable Function} {@var{spi} = } spi ([@var{port_path}], [@var{propname}, @var{propvalue}]) Open a spi interface. @subsubheading Inputs @var{port_path} - the interface device port/path of type String. If omitted defaults to '/dev/spi-0'. @* @var{propname},@var{propvalue} - property name/value pairs. Known input properties: @table @asis @item name Name of the object @item bitrate Numeric bitrate value @item clockpolarity Clock polarity: idlehigh or idlelow. @item clockphase Clock phase value: firstedge or secondedge @end table @subsubheading Outputs @var{spi} - An instance of @var{octave_spi} class. @subsubheading Properties The spi object has the following properties: @table @asis @item name Name of the object @item status Open or closed status of object (readonly). @item bitrate Numeric bitrate value @item clockpolarity Clock polarity: idlehigh or idlelow. @item clockphase Clock phase value: firstedge or secondedge @item port The interface driver port (readonly) @end table @end deftypefn @c SPI spi_close @c ----------------------------------------- @subsection spi_close @cindex spi_close @deftypefn {Loadable Function} {} spi_close (@var{spi}) Close the interface and release a file descriptor. @subsubheading Inputs @var{spi} - instance of @var{octave_spi} class.@* @subsubheading Outputs None @end deftypefn @c SPI spi_read @c ----------------------------------------- @subsection spi_read @cindex spi_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } spi_read (@var{spi}, @var{n}) Read from spi slave device. @subsubheading Inputs @var{spi} - instance of @var{octave_spi} class.@* @var{n} - number of bytes to attempt to read of type Integer. @subsubheading Outputs The spi_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array. @end deftypefn @c SPI spi_write @c ----------------------------------------- @subsection spi_write @cindex spi_write @deftypefn {Loadable Function} {@var{n} = } spi_write (@var{spi}, @var{data}) Write data to a spi slave device. @subsubheading Inputs @var{spi} - instance of @var{octave_spi} class.@* @var{data} - data, of type uint8, to be written to the slave device. @subsubheading Outputs Upon successful completion, spi_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c SPI spi_writeAndRead @c ----------------------------------------- @subsection spi_writeAndRead @cindex spi_writeAndRead @deftypefn {Loadable Function} {@var{rddata} = } spi_writeAndRead (@var{spi}, @var{wrdata}) Write data to a spi slave device and then read same number of values. @subsubheading Inputs @var{spi} - instance of @var{octave_spi} class.@* @var{wrdata} - data, of type uint8, to be written to the slave device.@* @subsubheading Outputs Upon successful completion, spi_writeAndRead() shall return the bytes read. @end deftypefn @c --------------------------------------------------- @node TCP (Deprecated) @section TCP (Deprecated) @cindex TCP (Deprecated) @c TCP (Deprecated) @octave_tcp/fclose @c ----------------------------------------- @subsection @@octave_tcp/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes TCP connection @var{obj} @end deftypefn @c TCP (Deprecated) @octave_tcp/flush @c ----------------------------------------- @subsection @@octave_tcp/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the tcp socket buffers @subsubheading Inputs @var{dev} - connected tcp device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{serialport} @end deftypefn @c TCP (Deprecated) @octave_tcp/flushinput @c ----------------------------------------- @subsection @@octave_tcp/flushinput @cindex flushinput @deftypefn {Loadable Function} {} flushinput (@var{tcp}) Flush the pending input, which will also make the BytesAvailable property be 0. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class. @subsubheading Outputs None. @xseealso{flushoutput} @end deftypefn @c TCP (Deprecated) @octave_tcp/flushoutput @c ----------------------------------------- @subsection @@octave_tcp/flushoutput @cindex flushoutput @deftypefn {Loadable Function} {} flushoutput (@var{tcp}) Flush the output buffer. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class. @subsubheading Outputs None. @xseealso{flushinput} @end deftypefn @c TCP (Deprecated) @octave_tcp/fopen @c ----------------------------------------- @subsection @@octave_tcp/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens TCP connection @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c TCP (Deprecated) @octave_tcp/fprintf @c ----------------------------------------- @subsection @@octave_tcp/fprintf @cindex fprintf @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) Writes formatted string @var{template} using optional parameters to TCP instrument @subsubheading Inputs @var{obj} is a TCP object.@* @var{template} Format template string @subsubheading Outputs Number of characters written @end deftypefn @c TCP (Deprecated) @octave_tcp/fread @c ----------------------------------------- @subsection @@octave_tcp/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from TCP instrument @subsubheading Inputs @var{obj} is a TCP object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} data read.@* @var{count} values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c TCP (Deprecated) @octave_tcp/fwrite @c ----------------------------------------- @subsection @@octave_tcp/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to TCP instrument @subsubheading Inputs @var{obj} is a TCP object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c TCP (Deprecated) @octave_tcp/get @c ----------------------------------------- @subsection @@octave_tcp/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{tcp}) @deftypefnx {Function File} {@var{field} = } get (@var{tcp}, @var{property}) Get the properties of tcp object. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_tcp/set} @end deftypefn @c TCP (Deprecated) @octave_tcp/read @c ----------------------------------------- @subsection @@octave_tcp/read @cindex read @deftypefn {Function File} {@var{data} =} read (@var{obj}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) Reads @var{data} from TCP instrument @subsubheading Inputs @var{obj} is a TCP object.@* @var{size} Number of values to read. (Default: 100).@* @var{datatype} datatype of data.@* @subsubheading Outputs @var{data} data read.@* @end deftypefn @c TCP (Deprecated) @octave_tcp/set @c ----------------------------------------- @subsection @@octave_tcp/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of tcp object. @subsubheading Inputs If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'name' Set the name for the tcp socket. @item 'remotehost' Set the remote host name for the tcp socket. @item 'remoteport' Set the remote port for the tcp socket. @item 'timeout' Set the timeout value in seconds. Value of -1 means a blocking call. @end table @subsubheading Outputs None @xseealso{@@octave_tcp/get} @end deftypefn @c TCP (Deprecated) @octave_tcp/write @c ----------------------------------------- @subsection @@octave_tcp/write @cindex write @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) Writes @var{data} to TCP instrument @subsubheading Inputs @var{obj} is a TCP object.@* @var{data} data to write.@* @var{datatype} datatype of data. If not specified, it defaults to "uint8".@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c TCP (Deprecated) tcp @c ----------------------------------------- @subsection tcp @cindex tcp @deftypefn {Loadable Function} {@var{tcp} = } tcp () @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}) @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, @var{port}) @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, @var{port}, @var{timeout}) @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, [@var{propertyname}, @var{propertyvalue}]) @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, @var{port}, [@var{propertyname}, @var{propertyvalue}]) Open tcp interface. @subsubheading Inputs @var{ipaddress} - the ip address of type String. If omitted defaults to '127.0.0.1'.@* @var{port} - the port number to connect. If omitted defaults to 23.@* @var{timeout} - the interface timeout value. If omitted defaults to blocking call.@* @var{propname},@var{propvalue} - property name/value pairs. Known input properties: @table @asis @item name name value @item timeout Numeric timeout value or -1 to wait forever @end table @subsubheading Outputs The tcp() shall return instance of @var{octave_tcp} class as the result @var{tcp}. @subsubheading Properties The tcp object has the following public properties: @table @asis @item name name assigned to the tcp object @item type instrument type 'tcp' (readonly) @item localport local port number (readonly) @item remoteport remote port number @item remotehost remote host @item status status of the object 'open' or 'closed' (readonly) @item timeout timeout value in seconds used for waiting for data @item bytesavailable number of bytes currently available to read (readonly) @end table @end deftypefn @c TCP (Deprecated) tcp_close @c ----------------------------------------- @subsection tcp_close @cindex tcp_close @deftypefn {Loadable Function} {} tcp_close (@var{tcp}) Close the interface and release a file descriptor. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class. @subsubheading Outputs None @end deftypefn @c TCP (Deprecated) tcp_read @c ----------------------------------------- @subsection tcp_read @cindex tcp_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } tcp_read (@var{tcp}, @var{n}, @var{timeout}) Read from tcp interface. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class.@* @var{n} - number of bytes to attempt to read of type Integer@* @var{timeout} - timeout in ms if different from default of type Integer @subsubheading Outputs @var{count} - number of bytes successfully read as an Integer@* @var{data} - data bytes themselves as uint8 array. @end deftypefn @c TCP (Deprecated) tcp_timeout @c ----------------------------------------- @subsection tcp_timeout @cindex tcp_timeout @deftypefn {Loadable Function} {} tcp_timeout (@var{tcp}, @var{timeout}) @deftypefnx {Loadable Function} {@var{t} = } tcp_timeout (@var{tcp}) Set new or get existing tcp interface timeout parameter used for tcp_read() requests. The timeout value is specified in milliseconds. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class.@* @var{timeout} - tcp_read() timeout value in milliseconds. Value of -1 means a blocking call. @subsubheading Outputs If @var{timeout} parameter is omitted, the tcp_timeout() shall return current timeout value as the result @var{t}. @end deftypefn @c TCP (Deprecated) tcp_write @c ----------------------------------------- @subsection tcp_write @cindex tcp_write @deftypefn {Loadable Function} {@var{n} = } tcp_write (@var{tcp}, @var{data}) Write data to a tcp interface. @subsubheading Inputs @var{tcp} - instance of @var{octave_tcp} class.@* @var{data} - data to be written to the tcp interface. Can be either of String or uint8 type. @subsubheading Outputs Upon successful completion, tcp_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c TCP (Deprecated) tcpip @c ----------------------------------------- @subsection tcpip @cindex tcpip @deftypefn {Function File} {@var{tcp} = } tcpip (@var{host}, [@var{port}], [@var{PropertyName}, @var{PropertyValue}...]) Matlab compatible wrapper to the tcp interface. NOTE: tcpip has been deprecated. Use tcpclient instead @subsubheading Inputs @var{host} - the host name or ip.@* @var{port} - the port number to connect. If omitted defaults to 80.@* @var{PropertyName}, @var{PropertyValue} - Optional property name, value pairs to set on the tcp object.@* @subsubheading Properties Currently the only known properties are "timeout" and "name". @subsubheading Outputs tcpip will return an instance of @var{octave_tcp} class as the result. @end deftypefn @c --------------------------------------------------- @node TCP Client @section TCP Client @cindex TCP Client @c TCP Client @octave_tcpclient/configureTerminator @c ----------------------------------------- @subsection @@octave_tcpclient/configureTerminator @cindex configureTerminator @deftypefn {Function File} {} configureTerminator (@var{tcp}, @var{term}) @deftypefnx {Function File} {} configureTerminator (@var{tcp}, @var{readterm}, @var{writeterm}) Set terminator on a tcpclient object for ASCII string manipulation @subsubheading Inputs @var{tcp} - tcpclient object@* @var{term} - terminal value for both read and write@* @var{readterm} = terminal value type for read data@* @var{writeterm} = terminal value for written data@* The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. @subsubheading Outputs None @xseealso{tcpport} @end deftypefn @c TCP Client @octave_tcpclient/flush @c ----------------------------------------- @subsection @@octave_tcpclient/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the tcpclient socket buffers @subsubheading Inputs @var{dev} - connected tcpclient device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{serialport} @end deftypefn @c TCP Client @octave_tcpclient/get @c ----------------------------------------- @subsection @@octave_tcpclient/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{tcpclient}) @deftypefnx {Function File} {@var{field} = } get (@var{tcpclient}, @var{property}) Get the properties of tcpclient object. @subsubheading Inputs @var{tcpclient} - instance of @var{octave_tcpclient} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_tcpclient/set} @end deftypefn @c TCP Client @octave_tcpclient/read @c ----------------------------------------- @subsection @@octave_tcpclient/read @cindex read @deftypefn {Function File} {@var{data} =} read (@var{obj}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) Reads @var{data} from TCP instrument @subsubheading Inputs @var{obj} is a TCP object.@* @var{size} Number of values to read. (Default: NumBytesAvailable).@* @var{datatype} datatype of data.@* @subsubheading Outputs @var{data} data read.@* @end deftypefn @c TCP Client @octave_tcpclient/set @c ----------------------------------------- @subsection @@octave_tcpclient/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of tcpclient object. @subsubheading Inputs If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'Name' Set the name for the tcpclient socket. @item 'UserData' Set user data for the tcpclient socket. @item 'Timeout' Set the timeout value in seconds. Value of -1 means a blocking call. @end table @subsubheading Outputs None @xseealso{@@octave_tcpclient/get} @end deftypefn @c TCP Client @octave_tcpclient/write @c ----------------------------------------- @subsection @@octave_tcpclient/write @cindex write @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) Writes @var{data} to TCP instrument @subsubheading Inputs @var{obj} is a TCPclient object.@* @var{data} data to write.@* @var{datatype} datatype of data. If not specified, it defaults to "uint8".@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c TCP Client tcpclient @c ----------------------------------------- @subsection tcpclient @cindex tcpclient @deftypefn {Loadable Function} {@var{tcpclient} = } tcpclient (@var{ipaddress}, @var{port}) @deftypefnx {Loadable Function} {@var{tcpclient} = } tcpclient (@var{ipaddress}, @var{port}, [@var{propertyname}, @var{propertyvalue}]) Open tcpclient interface. @subsubheading Inputs @var{ipaddress} - the ip address of type String.@* @var{port} - the port number to connect.@* @var{propname},@var{propvalue} - property name/value pairs. Known input properties: @table @asis @item Name name value @item Timeout Numeric timeout value or -1 to wait forever @item EnableTransferDelay Boolean to enable or disable the nagle algorithm for delay transfer. @item UserData User data value. @end table @subsubheading Outputs The tcpclient() shall return instance of @var{octave_tcpclient} class as the result @var{tcpclient}. @subsubheading Properties The tcpclient object has the following public properties: @table @asis @item Name name assigned to the tcpclient object @item Type instrument type 'tcpclient' (readonly) @item Port remote port number (Readonly) @item Address remote host address (Readonly) @item Status status of the object 'open' or 'closed' (readonly) @item Timeout timeout value in seconds used for waiting for data @item NumBytesAvailable number of bytes currently available to read (readonly) @item NumBytesWritten number of bytes currently available to read (readonly) @item ByteOrder Byte order for data (currently not used) @item Terminator Terminator value used for string data (currently not used) @item UserData User data @item EnableTransferDelay Bool for whether transfer delay is enabled. (Read only) @end table @end deftypefn @c --------------------------------------------------- @node TCP Server @section TCP Server @cindex TCP Server @c TCP Server @octave_tcpserver/configureTerminator @c ----------------------------------------- @subsection @@octave_tcpserver/configureTerminator @cindex configureTerminator @deftypefn {Function File} {} configureTerminator (@var{tcp}, @var{term}) @deftypefnx {Function File} {} configureTerminator (@var{tcp}, @var{readterm}, @var{writeterm}) Set terminator on a tcpserver object for ASCII string manipulation @subsubheading Inputs @var{tcp} - tcpserver object@* @var{term} - terminal value for both read and write@* @var{readterm} = terminal value type for read data@* @var{writeterm} = terminal value for written data@* The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. @subsubheading Outputs None @xseealso{tcpport} @end deftypefn @c TCP Server @octave_tcpserver/flush @c ----------------------------------------- @subsection @@octave_tcpserver/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the tcpserver socket buffers @subsubheading Inputs @var{dev} - connected tcpserver device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{serialport} @end deftypefn @c TCP Server @octave_tcpserver/get @c ----------------------------------------- @subsection @@octave_tcpserver/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{tcpserver}) @deftypefnx {Function File} {@var{field} = } get (@var{tcpserver}, @var{property}) Get the properties of tcpserver object. @subsubheading Inputs @var{tcpserver} - instance of @var{octave_tcpserver} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_tcpserver/set} @end deftypefn @c TCP Server @octave_tcpserver/read @c ----------------------------------------- @subsection @@octave_tcpserver/read @cindex read @deftypefn {Function File} {@var{data} =} read (@var{obj}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) Reads @var{data} from TCP instrument @subsubheading Inputs @var{obj} is a TCP Server object.@* @var{size} Number of values to read. (Default: NumBytesAvailable).@* @var{datatype} datatype of data.@* @subsubheading Outputs @var{data} data read.@* @end deftypefn @c TCP Server @octave_tcpserver/set @c ----------------------------------------- @subsection @@octave_tcpserver/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of tcpserver object. @subsubheading Inputs If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'Name' Set the name for the tcpserver socket. @item 'UserData' Set user data for the tcpserver socket. @item 'Timeout' Set the timeout value in seconds. Value of -1 means a blocking call. @end table @subsubheading Outputs None @xseealso{@@octave_tcpserver/get} @end deftypefn @c TCP Server @octave_tcpserver/write @c ----------------------------------------- @subsection @@octave_tcpserver/write @cindex write @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) Writes @var{data} to TCP instrument @subsubheading Inputs @var{obj} is a TCPServer object.@* @var{data} data to write.@* @var{datatype} datatype of data. If not specified, it defaults to "uint8".@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c TCP Server tcpserver @c ----------------------------------------- @subsection tcpserver @cindex tcpserver @deftypefn {Loadable Function} {@var{tcpserver} = } tcpserver (@var{ipaddress}, @var{port}) @deftypefnx {Loadable Function} {@var{tcpserver} = } tcpserver (@var{port}) @deftypefnx {Loadable Function} {@var{tcpserver} = } tcpserver (@dots{}, [@var{propertyname}, @var{propertyvalue}]) Open tcpserver interface. @subsubheading Inputs @var{ipaddress} - the ip address of type String.@* @var{port} - the port number to bind.@* @var{propname},@var{propvalue} - property name/value pairs. Known input properties: @table @asis @item Name name value @item Timeout Numeric timeout value or -1 to wait forever @item UserData User data value. @end table @subsubheading Outputs The tcpserver() shall return instance of @var{octave_tcpserver} class as the result @var{tcpserver}. @subsubheading Properties The tcpserver object has the following public properties: @table @asis @item Connected boolean flag for when connected to a client (Readonly) @item ClientPort connected client port number (Readonly) @item ClientAddress connected client address (Readonly) @item Name name assigned to the tcpserver object @item Type instrument type 'tcpserver' (readonly) @item ServerPort server port number (Readonly) @item ServerAddress server address (Readonly) @item Status status of the object 'open' or 'closed' (readonly) @item Timeout timeout value in seconds used for waiting for data @item NumBytesAvailable number of bytes currently available to read (readonly) @item NumBytesWritten number of bytes currently available to read (readonly) @item ByteOrder Byte order for data (currently not used) @item Terminator Terminator value used for string data (currently not used) @item UserData User data @end table @end deftypefn @c --------------------------------------------------- @node UDP (Deprecated) @section UDP (Deprecated) @cindex UDP (Deprecated) @c UDP (Deprecated) @octave_udp/fclose @c ----------------------------------------- @subsection @@octave_udp/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes UDP connection @var{obj} @end deftypefn @c UDP (Deprecated) @octave_udp/flush @c ----------------------------------------- @subsection @@octave_udp/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the udp socket buffers @subsubheading Inputs @var{dev} - open udp device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{udp} @end deftypefn @c UDP (Deprecated) @octave_udp/flushinput @c ----------------------------------------- @subsection @@octave_udp/flushinput @cindex flushinput @deftypefn {Loadable Function} {} flushinput (@var{udp}) Flush the pending input, which will also make the BytesAvailable property be 0. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class. @subsubheading Outputs None @xseealso{flushoutput} @end deftypefn @c UDP (Deprecated) @octave_udp/flushoutput @c ----------------------------------------- @subsection @@octave_udp/flushoutput @cindex flushoutput @deftypefn {Loadable Function} {} flushoutput (@var{udp}) Flush the output buffer. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class. @subsubheading Outputs None @xseealso{flushinput} @end deftypefn @c UDP (Deprecated) @octave_udp/fopen @c ----------------------------------------- @subsection @@octave_udp/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens UDP connection @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c UDP (Deprecated) @octave_udp/fprintf @c ----------------------------------------- @subsection @@octave_udp/fprintf @cindex fprintf @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) Writes formatted string @var{template} using optional parameters to UDP instrument @subsubheading Inputs @var{obj} is a UDP object.@* @var{template} Format template string.@* @subsubheading Outputs @var{numbytes} is the number of bytes written to the device @end deftypefn @c UDP (Deprecated) @octave_udp/fread @c ----------------------------------------- @subsection @@octave_udp/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from UDP instrument @subsubheading Inputs @var{obj} is a UDP object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} data values.@* @var{count} number of values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c UDP (Deprecated) @octave_udp/fwrite @c ----------------------------------------- @subsection @@octave_udp/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to UDP instrument @subsubheading Inputs @var{obj} is a UDP object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c UDP (Deprecated) @octave_udp/get @c ----------------------------------------- @subsection @@octave_udp/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{udp}) @deftypefnx {Function File} {@var{field} = } get (@var{udp}, @var{property}) Get the properties of udp object. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_udp/set} @end deftypefn @c UDP (Deprecated) @octave_udp/read @c ----------------------------------------- @subsection @@octave_udp/read @cindex read @deftypefn {Function File} {@var{data} =} read (@var{obj}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) Reads @var{data} from UDP instrument @subsubheading Inputs @var{obj} is a UDP object.@* @var{size} Number of values to read. (Default: BytesAvailable).@* @var{datatype} datatype of data.@* @subsubheading Outputs @var{data} data read.@* @end deftypefn @c UDP (Deprecated) @octave_udp/set @c ----------------------------------------- @subsection @@octave_udp/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of udp object. @subsubheading Inputs @var{obj} - instance of @var{octave_udp} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'name' Set the name for the udp socket. @item 'remotehost' Set the remote host name for the udp socket. @item 'remoteport' Set the remote port for the udp socket. @item 'timeout' Set the timeout value in seconds. Value of -1 means a blocking call. @end table @subsubheading Outputs None @xseealso{@@octave_udp/get} @end deftypefn @c UDP (Deprecated) @octave_udp/write @c ----------------------------------------- @subsection @@octave_udp/write @cindex write @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}, @var{destinationAddress}, @var{destinationPort})) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}, @var{destinationAddress}, @var{destinationPort}) Writes @var{data} to UDP instrument @subsubheading Inputs @var{obj} is a UDP object.@* @var{data} data to write.@* @var{datatype} datatype of data. If not specified defaults to uint8.@* @var{destinationAddress} ipaddress to send to. If not specified, use the remote address.@* @var{destinationPort} port to send to. If not specified, use the remote port.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c UDP (Deprecated) udp @c ----------------------------------------- @subsection udp @cindex udp @deftypefn {Loadable Function} {@var{udp} = } udp () @deftypefnx {Loadable Function} {@var{udp} = } udp (@var{remoteipaddress}, @var{remoteport}) @deftypefnx {Loadable Function} {@var{udp} = } udp (@var{remoteipaddress}, @var{remoteport}, [@var{propertyname}, @var{propertyvalue} ...]) Open udp interface. @subsubheading Inputs @var{remoteipaddress} - the ip address of type String. If omitted defaults to '127.0.0.1'.@* @var{remoteport} - the port number to connect. If omitted defaults to 23.@* @var{localport} - the local port number to bind. If omitted defaults to 0@* @var{propertyname}, @var{propertyvalue} - property name/value pair @subsubheading Outputs The udp() shall return instance of @var{octave_udp} class as the result @var{udp}. @subsubheading Properties The udp object has the following public properties: @table @asis @item name name assigned to the udp object @item type instrument type 'udp' (readonly) @item localport local port number (readonly) @item localhost local host address (readonly) @item remoteport remote port number @item remotehost remote host @item status status of the object 'open' or 'closed' (readonly) @item timeout timeout value in seconds used for waiting for data @item bytesavailable number of bytes currently available to read (readonly) @end table @end deftypefn @c UDP (Deprecated) udp_close @c ----------------------------------------- @subsection udp_close @cindex udp_close @deftypefn {Loadable Function} {} udp_close (@var{udp}) Close the interface and release a file descriptor. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class. @subsubheading Inputs None @end deftypefn @c UDP (Deprecated) udp_demo @c ----------------------------------------- @subsection udp_demo @cindex udp_demo @deftypefn {Function File} {@var{result} =} udp_demo () Run test SNTP demonstration for udp class @xseealso{udp} @end deftypefn @c UDP (Deprecated) udp_read @c ----------------------------------------- @subsection udp_read @cindex udp_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } udp_read (@var{udp}, @var{n}, @var{timeout}) Read from udp interface. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class.@* @var{n} - number of bytes to attempt to read of type Integer@* @var{timeout} - timeout in ms if different from default of type Integer @subsubheading Outputs The udp_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array. @end deftypefn @c UDP (Deprecated) udp_timeout @c ----------------------------------------- @subsection udp_timeout @cindex udp_timeout @deftypefn {Loadable Function} {} udp_timeout (@var{udp}, @var{timeout}) @deftypefnx {Loadable Function} {@var{t} = } udp_timeout (@var{udp}) Set new or get existing udp interface timeout parameter used for udp_read() requests. The timeout value is specified in milliseconds. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class.@* @var{timeout} - udp_read() timeout value in milliseconds. Value of -1 means a blocking call. @subsubheading Outputs If @var{timeout} parameter is omitted, the udp_timeout() shall return current timeout value as the result @var{t}. @end deftypefn @c UDP (Deprecated) udp_write @c ----------------------------------------- @subsection udp_write @cindex udp_write @deftypefn {Loadable Function} {@var{n} = } udp_write (@var{udp}, @var{data}) Write data to a udp interface. @subsubheading Inputs @var{udp} - instance of @var{octave_udp} class.@* @var{data} - data to be written to the udp interface. Can be either of String or uint8 type. @subsubheading Outputs Upon successful completion, udp_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c --------------------------------------------------- @node UDP Port @section UDP Port @cindex UDP Port @c UDP Port @octave_udpport/configureMulticast @c ----------------------------------------- @subsection @@octave_udpport/configureMulticast @cindex configureMulticast @deftypefn {} {@var{data} =} configureMulticast((@var{dev}, @var{address}) @deftypefnx {} {@var{data} =} configureMulticast((@var{dev}, @var{"off"}) Configure udpport device to receive multicast data @subsubheading Inputs @var{dev} - open udpport device If @var{address} is 'off' disable udp multicast. Otherwise it is the multicast address to use. @subsubheading Outputs None @xseealso{udpport} @end deftypefn @c UDP Port @octave_udpport/configureTerminator @c ----------------------------------------- @subsection @@octave_udpport/configureTerminator @cindex configureTerminator @deftypefn {Function File} {} configureTerminator (@var{udp}, @var{term}) @deftypefnx {Function File} {} configureTerminator (@var{udp}, @var{readterm}, @var{writeterm}) Set terminator for ASCII string manipulation @subsubheading Inputs @var{udp} - udpport object@* @var{term} - terminal value for both read and write@* @var{readterm} = terminal value type for read data@* @var{writeterm} = terminal value for written data@* The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. @subsubheading Outputs None @xseealso{udpport} @end deftypefn @c UDP Port @octave_udpport/flush @c ----------------------------------------- @subsection @@octave_udpport/flush @cindex flush @deftypefn {} {@var{data} =} flush (@var{dev}) @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") Flush the udpport socket buffers @subsubheading Inputs @var{dev} - open udpport device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed @subsubheading Outputs None @xseealso{udpport} @end deftypefn @c UDP Port @octave_udpport/fprintf @c ----------------------------------------- @subsection @@octave_udpport/fprintf @cindex fprintf @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) Writes formatted string @var{template} using optional parameters to UDP instrument @subsubheading Inputs @var{obj} is a UDPPort object.@* @var{template} Format template string.@* @subsubheading Outputs @var{numbytes} is the number of bytes written to the device @end deftypefn @c UDP Port @octave_udpport/fread @c ----------------------------------------- @subsection @@octave_udpport/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from UDP instrument @subsubheading Inputs @var{obj} is a UDP port object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} data values.@* @var{count} number of values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c UDP Port @octave_udpport/fwrite @c ----------------------------------------- @subsection @@octave_udpport/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to UDP instrument @subsubheading Inputs @var{obj} is a UDP port object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c UDP Port @octave_udpport/get @c ----------------------------------------- @subsection @@octave_udpport/get @cindex get @deftypefn {Function File} {@var{struct} = } get (@var{udpport}) @deftypefnx {Function File} {@var{field} = } get (@var{udpport}, @var{property}) Get the properties of udpport object. @subsubheading Inputs @var{udpport} - instance of @var{octave_udpport} class.@* @var{property} - name of property.@* @subsubheading Outputs When @var{property} was specified, return the value of that property.@* otherwise return the values of all properties as a structure.@* @xseealso{@@octave_udpport/set} @end deftypefn @c UDP Port @octave_udpport/read @c ----------------------------------------- @subsection @@octave_udpport/read @cindex read @deftypefn {Function File} {@var{data} =} read (@var{obj}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) Reads @var{data} from UDP instrument @subsubheading Inputs @var{obj} is a UDP object.@* @var{size} Number of values to read. (Default: BytesAvailable).@* @var{datatype} datatype of data.@* @subsubheading Outputs @var{data} data read.@* @end deftypefn @c UDP Port @octave_udpport/set @c ----------------------------------------- @subsection @@octave_udpport/set @cindex set @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) Set the properties of udpport object. @subsubheading Inputs @var{obj} - instance of @var{octave_udpport} class.@* @var{property} - name of property.@* If @var{property} is a cell so must be @var{value}, it sets the values of all matching properties. The function also accepts property-value pairs. @subsubheading Properties @table @var @item 'Name' Set the name for the udpport socket. @item 'UserData' Set the user data of the object. @item 'Timeout' Set the timeout value in seconds. Value of -1 means a blocking call. @end table @subsubheading Outputs None @xseealso{@@octave_udpport/get} @end deftypefn @c UDP Port @octave_udpport/write @c ----------------------------------------- @subsection @@octave_udpport/write @cindex write @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}, @var{destinationAddress}, @var{destinationPort})) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}, @var{destinationAddress}, @var{destinationPort}) Writes @var{data} to UDP instrument @subsubheading Inputs @var{obj} is a UDPPort object.@* @var{data} data to write.@* @var{datatype} datatype of data. If not specified defaults to uint8.@* @var{destinationAddress} ipaddress to send to. If not specified, use the previously used remote address.@* @var{destinationPort} port to send to. If not specified, use the remote port.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c UDP Port @octave_udpport/writeline @c ----------------------------------------- @subsection @@octave_udpport/writeline @cindex writeline @deftypefn {} {} writeline (@var{dev}, @var{data}) @deftypefnx {} {} writeline (@var{dev}, @var{data}, @var{destaddr}, @var{destport}) Write data to a udpport including terminator value @subsubheading Inputs @var{dev} - connected device @var{data} - ASCII data to write @var{destaddr} - Destination address @var{destport} - Destination port Where the address and port is not specified, the previously used address and port is used. @subsubheading Outputs None @xseealso{flushoutput} @end deftypefn @c UDP Port udpport @c ----------------------------------------- @subsection udpport @cindex udpport @deftypefn {Loadable Function} {@var{udp} = } udpport () @deftypefnx {Loadable Function} {@var{udp} = } udpport (@var{propertyname}, @var{propertyvalue} ...) Open udpport interface. @subsubheading Inputs @var{propertyname}, @var{propertyvalue} - property name/value pair Known input properties: @table @asis @item Name name assigned to the udp object @item LocalPort local port number @item LocalHost local host address @item Timeout timeout value in seconds used for waiting for data @item EnablePortSharing Boolean if the socket has port sharing enabled (readonly) @end table @subsubheading Outputs The udpport() shall return instance of @var{octave_udp} class as the result @var{udp}. @subsubheading Properties The udp object has the following public properties: @table @asis @item Name name assigned to the udp object @item Type instrument type 'udpport' (readonly) @item LocalPort local port number (readonly) @item LocalHost local host address (readonly) @item Status status of the object 'open' or 'closed' (readonly) @item Timeout timeout value in seconds used for waiting for data @item NumBytesAvailable number of bytes currently available to read (readonly) @item MulticastGroup multicast group socket is subscribed to (readonly) @item EnableMultcast Boolean if the socket has any multicast group it is subscribed to (readonly) @item EnablePortSharing Boolean if the socket has port sharing enabled (readonly) @item Terminator Terminator value used for string data (currently not used) @end table @end deftypefn @c --------------------------------------------------- @node USBTMC @section USBTMC @cindex USBTMC @c USBTMC @octave_usbtmc/fclose @c ----------------------------------------- @subsection @@octave_usbtmc/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes USBTMC connection @var{obj} @subsubheading Inputs @var{obj} is a usbtmc object.@* @end deftypefn @c USBTMC @octave_usbtmc/fopen @c ----------------------------------------- @subsection @@octave_usbtmc/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens USBTMC connection @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c USBTMC @octave_usbtmc/fread @c ----------------------------------------- @subsection @@octave_usbtmc/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from usbtmc instrument @subsubheading Inputs @var{obj} is a usbtmc object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} The read data.@* @var{count} values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c USBTMC @octave_usbtmc/fwrite @c ----------------------------------------- @subsection @@octave_usbtmc/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to an usbtmc instrument @subsubheading Inputs @var{obj} is a usbtmc object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c USBTMC usbtmc @c ----------------------------------------- @subsection usbtmc @cindex usbtmc @deftypefn {Loadable Function} {@var{usbtmc} = } usbtmc (@var{path}) Open usbtmc interface. @subsubheading Inputs @var{path} - the interface path of type String. If omitted defaults to '/dev/usbtmc0'. @subsubheading Outputs The usbtmc() shall return instance of @var{octave_usbtmc} class as the result @var{usbtmc}. @end deftypefn @c USBTMC usbtmc_close @c ----------------------------------------- @subsection usbtmc_close @cindex usbtmc_close @deftypefn {Loadable Function} {} usbtmc_close (@var{usbtmc}) Close the interface and release a file descriptor. @subsubheading Inputs @var{usbtmc} - instance of @var{octave_usbtmc} class. @subsubheading Outputs None @end deftypefn @c USBTMC usbtmc_read @c ----------------------------------------- @subsection usbtmc_read @cindex usbtmc_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } usbtmc_read (@var{usbtmc}, @var{n}) Read from usbtmc slave device. @subsubheading Inputs @var{usbtmc} - instance of @var{octave_usbtmc} class.@* @var{n} - number of bytes to attempt to read of type Integer. @subsubheading Outputs @var{count} - the number of bytes successfully read as an Integer.@* @var{data} - the read bytes as a uint8 array. @end deftypefn @c USBTMC usbtmc_write @c ----------------------------------------- @subsection usbtmc_write @cindex usbtmc_write @deftypefn {Loadable Function} {@var{n} = } usbtmc_write (@var{usbtmc}, @var{data}) Write data to a usbtmc slave device. @subsubheading Inputs @var{usbtmc} - instance of @var{octave_usbtmc} class.@* @var{data} - data, of type uint8, to be written to the slave device. @subsubheading Outputs Upon successful completion, usbtmc_write() shall return the number of bytes written as the result @var{n}. @end deftypefn @c --------------------------------------------------- @node VXI11 @section VXI11 @cindex VXI11 @c VXI11 @octave_vxi11/fclose @c ----------------------------------------- @subsection @@octave_vxi11/fclose @cindex fclose @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) Closes VXI11 connection @var{obj} @end deftypefn @c VXI11 @octave_vxi11/fopen @c ----------------------------------------- @subsection @@octave_vxi11/fopen @cindex fopen @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) Opens VXI11 connection @var{obj} This currently is a dummy function to improve compatibility to MATLAB @end deftypefn @c VXI11 @octave_vxi11/fread @c ----------------------------------------- @subsection @@octave_vxi11/fread @cindex fread @deftypefn {Function File} {@var{data} =} fread (@var{obj}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) Reads @var{data} from vxi11 instrument @subsubheading Inputs @var{obj} is a vxi11 object.@* @var{size} Number of values to read. (Default: 100).@* @var{precision} precision of data.@* @subsubheading Outputs @var{data} The read data.@* @var{count} values read.@* @var{errmsg} read operation error message.@* @end deftypefn @c VXI11 @octave_vxi11/fwrite @c ----------------------------------------- @subsection @@octave_vxi11/fwrite @cindex fwrite @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) Writes @var{data} to vxi11 instrument @subsubheading Inputs @var{obj} is a vxi11 object.@* @var{data} data to write.@* @var{precision} precision of data.@* @subsubheading Outputs returns number of bytes written. @end deftypefn @c VXI11 vxi11 @c ----------------------------------------- @subsection vxi11 @cindex vxi11 @deftypefn {Loadable Function} {@var{vxi11} = } vxi11 (@var{ip},@var{instr}) Open vxi11 interface. @var{ip} - the ip address of type String. If omitted defaults to '127.0.0.1'. @var{instr} - the instrument name of type String. If omitted defaults to 'inst0'. The vxi11() shall return instance of @var{octave_vxi11} class as the result @var{vxi11}. @end deftypefn @c VXI11 vxi11_close @c ----------------------------------------- @subsection vxi11_close @cindex vxi11_close @deftypefn {Loadable Function} {} vxi11_close (@var{vxi11}) Close the interface and release a file descriptor. @var{vxi11} - instance of @var{octave_vxi11} class. @end deftypefn @c VXI11 vxi11_read @c ----------------------------------------- @subsection vxi11_read @cindex vxi11_read @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } vxi11_read (@var{vxi11}, @var{n}) Read from vxi11 slave device. @var{vxi11} - instance of @var{octave_vxi11} class.@* @var{n} - number of bytes to attempt to read of type Integer. The vxi11_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array. @end deftypefn @c VXI11 vxi11_write @c ----------------------------------------- @subsection vxi11_write @cindex vxi11_write @deftypefn {Loadable Function} {@var{n} = } vxi11_write (@var{vxi11}, @var{data}) Write data to a vxi11 slave device. @var{vxi11} - instance of @var{octave_vxi11} class.@* @var{data} - data to be written to the slave device. Can be either of String or uint8 type. Upon successful completion, vxi11_write() shall return the number of bytes written as the result @var{n}. @end deftypefn instrument-control-0.9.4/doc/gpl.texi0000644000000000000000000010433014743226261014572 0ustar00@node Copying @appendix GNU General Public License @cindex warranty @cindex copyright @center Version 3, 29 June 2007 @display Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @heading 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. @heading TERMS AND CONDITIONS @enumerate 0 @item 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. @item 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. @item 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. @item 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. @item 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. @item 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: @enumerate a @item The work must carry prominent notices stating that you modified it, and giving a relevant date. @item 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''. @item 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. @item 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. @end enumerate 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. @item 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: @enumerate a @item 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. @item 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. @item 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. @item 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. @item 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. @end enumerate 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. @item 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: @enumerate a @item Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or @item 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 @item 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 @item Limiting the use for publicity purposes of names of licensors or authors of the material; or @item Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or @item 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. @end enumerate 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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 enumerate @heading END OF TERMS AND CONDITIONS @heading 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. @smallexample @var{one line to give the program's name and a brief idea of what it does.} Copyright (C) @var{year} @var{name of author} 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 @url{http://www.gnu.org/licenses/}. @end smallexample 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: @smallexample @var{program} Copyright (C) @var{year} @var{name of author} This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}. This is free software, and you are welcome to redistribute it under certain conditions; type @samp{show c} for details. @end smallexample The hypothetical commands @samp{show w} and @samp{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 @url{http://www.gnu.org/licenses/}. 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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}. instrument-control-0.9.4/doc/instrument-control.css0000644000000000000000000000133714743226261017520 0ustar00pre.example, .header, .float-caption, hr { /* base00 ~ body text in light solarized theme */ color: #657b83; border-color: #657b83; } pre.example { /* base3 ~ background color in light solarized theme */ background-color: #fdf6e3; padding: 0.5em; } table.cartouche { border: 1px solid #948473; background-color: #FFE3C6; width: 100%; } table.cartouche td, table.cartouche th { border: 1px solid #948473; padding: 4px 4px; } /* newer texinfo generation styles */ div.example { /* base00 ~ body text in light solarized theme */ color: #657b83; border-color: #657b83; } pre.example-preformatted { /* base3 ~ background color in light solarized theme */ background-color: #fdf6e3; padding: 0.5em; } instrument-control-0.9.4/doc/instrument-control.html0000644000000000000000000161233614743226261017704 0ustar00 Octave Instrument Control Toolkit

Introduction

The Instrument Control toolkit is a set of low level I/O functions for serial, i2c, spi, modbus, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces

Table of Contents


1 Installing and loading

The Instrument Control toolkit must be installed and then loaded to be used.

It can be installed in GNU Octave directly from octave-forge, or can be installed in an off-line mode via a downloaded tarball.

The toolkit must be then be loaded once per each GNU Octave session in order to use its functionality.

1.1 Requirements

For GPIB support (Linux only), linux-gpib must be installed before installing instrument-control. GPIB support is also available for windows by following the information from the wiki: https://wiki.octave.org/Instrument_control_package#Requirements

For VXI11 support, rpcgen, and libtirpc-devel must be installed before installing instrument-control.

For MODBUS support, the libmodbus-devel must be installed before installing instrument-control.

1.2 Windows install

If using the GNU Octave installer in Windows, the toolkit will have already been installed, and does not need to be re-installed unless a newer version is available.

Run the following command to verify if the toolkit is available:

pkg list instrument-control

1.3 Online Direct install

With an internet connection available, toolkit can be installed from octave-forge using the following command within GNU Octave:

pkg install -forge instrument-control

The latest released version of the toolkit will be downloaded, compiled and installed.

1.4 Off-line install

With the toolkit package already downloaded, and in the current directory when running GNU Octave, the package can be installed using the following command within GNU Octave:

pkg install instrument-control-0.9.4.tar.gz

1.5 Loading

Regardless of the method of installing the toolkit, in order to use its functions, the toolkit must be loaded using the pkg load command:

pkg load instrument-control

The toolkit must be loaded on each GNU Octave session.


2 Basic Usage Overview


2.1 Authors

The Instrument control package provides low level I/O functions for serial, i2c, spi, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces.

It was written mainly by the following developers:

  • Andrius Sutas <andrius.sutasg at mail.com>
  • Stefan Mahr <dac922 at gmx.de>
  • John Donoghue <john.donoghue at ieee.org>

2.2 Available Interfaces

The ability to use each interface is dependent on OS and what libraries were available during the toolkit install.

To verify the available interfaces, run the following command in octave:

instrhwinfo

The function will return information on the supported interfaces that are available, similar to below:

    ToolboxVersion = 0.7.0
    ToolboxName = octave instrument control package
    SupportedInterfaces =
    {
      [1,1] = gpib
      [1,2] = i2c
      [1,3] = parallel
      [1,4] = serial
      [1,5] = serialport
      [1,6] = tcp
      [1,7] = tcpclient
      [1,8] = udp
      [1,9] = udpport
      [1,10] = usbtmc
      [1,11] = vxi11
    }

Most interfaces have two types of functions:

  • somewhat compatible matlab functions such as fread, fwrite
  • interface specific lower level functions such as udp_read, udp_write

2.3 Basic Serial

2.3.1 Serial

NOTE: The serial object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the serialport object.

The serial port can be opened using the serial function:

s = serial("/dev/ttyUSB1", 115200) 

The first parameter is the device name and is OS specific. The second parameter is the baudrate.

A list of available serial ports can be retrieved using the function:

seriallist

After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access.

s = serial("/dev/ttyUSB1", 115200) 
br = get(s, "baudrate") # gets the baudrate
br = s.baudrate  # also gets the baudrate

set(s, "baudrate", 9600) # set the baudrate
s.baudrate = 9600 # also sets the baudrate

The device can be written and read from using fread, fwrite and srl_read and slr_write functions.

srl_write(s, "hello world") # write hello world
fprintf(s, "hello again")

val = srl_read(s, 10) # attempt to read
val = fread(s, 10)

The device can be closed using fclose or srl_close.

fclose(s)

2.3.2 SerialPort

The recommended method of accessing serial ports is through the serialport object.

The serial port can be opened using the serialport function:

s = serialport("/dev/ttyUSB1", 115200) 

The first parameter is the device name and is OS specific. The second parameter is the baudrate.

A list of available serial ports can be retrieved using the function:

serialportlist

After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access.

s = serialport("/dev/ttyUSB1", 115200) 
br = get(s, "BaudRate") # gets the baudrate
br = s.BaudRate  # also gets the baudrate

set(s, "BaudRate", 9600) # set the baudrate
s.BaudRate = 9600 # also sets the baudrate

The device can be written and read from using read and write functions.

write(s, "hello world") # write hello world

val = read(s, 10)

The device can be closed by clearing the serialport object.

clear s

2.4 Basic TCP

2.4.1 TCP

NOTE: The TCP object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the tcpclient object.

A TCP connection can be opened using the tcp or tcpip function:

s = tcp("127.0.0.1", 80) 

The first parameter is the IP address to connect to. The second parameter is the port number. And optional timeout value can be also be provided.

A more matlab compatible function is available as tcpip to also open a tcp port:

s = tcpip("gnu.org", 80) 

The first parameter is a hostname or ip address, the second the port number. Additional parameter/value pairs can be provided after the port.

After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access.

s = tcp("127.0.0.1", 80)
oldtimeout = get(s, "timeout") # get timeout

set(s, "timeout", 10) # set the timeout
s.timeout = oldtimeout # also sets the timeout

The device can be written and read from using fread, fwrite and tcp_read and tcp_write functions.

tcp_write(s, "HEAD / HTTP/1.1\r\n\r\n")

val = tcp_read(s, 100, 500) # attempt to read 100 bytes

The device can be closed using fclose or tcp_close.

fclose(s)

2.4.2 TCP Client

The recommended method of creating a tcp connection is through the tcpclient object.

A TCP connection can be opened using the tcpclient function:

s = tcpclient("127.0.0.1", 80) 

The first parameter is the IP address or hostname to connect to. The second parameter is the port number.

Additional parameter/value pairs can be provided after the port.

After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access.

s = tcpclient("127.0.0.1", 80)
oldtimeout = get(s, "Timeout") # get timeout

set(s, "Timeout", 10) # set the timeout
s.Timeout = oldtimeout # also sets the timeout

The device can be written and read from using read and write functions.

write(s, "HEAD / HTTP/1.1\r\n\r\n")

val = read(s, 100) # attempt to read 100 bytes

The device can be closed by clearing the object variable.

clear s

2.5 Basic UDP

2.5.1 UDP

NOTE: The UDP object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the udpport object.

A UDP connection can be opened using the udp function:

s = udp("127.0.0.1", 80) 

The first parameter is the IP address data will be to. The second parameter is the port number.

If and ip address and port is not provides, it will default to "127.0.0.1" and 23.

The address and port can be changed after creation using the remotehost and remoteport properties.

s = udp() 
s.remotehost = "127.0.0.1";
s.remoteport = 100;

After creating the interface object, other properties of the device can be set or retrieved using get or set functions or as property access.

s = udp("127.0.0.1", 80)
oldtimeout = get(s, "timeout") # get timeout

set(s, "timeout", 10) # set the timeout
s.timeout = oldtimeout # also sets the timeout

The device can be written and read from using fread, fwrite and udp_read and udp_write functions.

udp_write(s, "test")

val = udp_read(s, 5)

The device can be closed using fclose or udp_close.

fclose(s)

2.5.2 UDP Port

The recommended method of creating a udp socket is through the udpport object.

A udpport object can be created using the udpport function:

s = udpport()

Additional parameter/value pairs can be provided during creation of the object.

After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access.

s = udpport()
oldtimeout = get(s, "Timeout") # get timeout

set(s, "Timeout", 10) # set the timeout
s.Timeout = oldtimeout # also sets the timeout

The device can be written and read from using read and write functions.

The destination address and port to send data to must be specified at least on the first time write is used.

write(s, "test", "127.0.0.1", s.LocalPort)

val = read(s)

The device can be closed by clearing the object variable.

clear s

3 Function Reference

The functions currently available in the toolkit are described below.


3.1 Common Functions

3.1.1 flushinput

: flushinput (dev)

Flush the instruments input buffers

Inputs

dev - connected device or array of devices

Outputs

None

See also: flushoutput.

3.1.2 flushoutput

: flushoutput (dev)

Flush the instruments output buffers

Inputs

dev - connected device or array of devices

Outputs

None

See also: flushinput.

3.1.3 readbinblock

: data = readbinblock (dev)
: data = readbinblock (dev, datatype)

read a binblock of data from a instrument device

Inputs

dev - connected device

datatype - optional data type to read data as (default ’uint8’)

Outputs

data - data read

See also: flushoutput.

3.1.4 readline

: data = readline (dev)

read data from a instrument device excluding terminator value

Inputs

dev - connected device

Outputs

data - ASCII data read

See also: flushoutput.

3.1.5 writebinblock

: writebinblock (dev, data, datatype)

Write a IEEE 488.2 binblock of data to a instrument device

binblock formatted data is defined as:

#<A><B><C>

where: <A> ASCII number containing the length of part <B>

<B> ASCII number containing the number of bytes of <C>

<C> Binary data block

Inputs

dev - connected device

data - binary data to send

datatype - datatype to send data as

Outputs

None

See also: flushoutput.

3.1.6 writeline

: writeline (dev, data)

Write data to a instrument device including terminator value

Inputs

dev - connected device

data - ASCII data to write

Outputs

None

See also: flushoutput.

3.1.7 writeread

: data = writeread (dev, command)

write a ASCII command and read data from a instrument device.

Inputs

dev - connected device

command - ASCII command

Outputs

data - ASCII data read

See also: readline, writeline.


3.2 General

3.2.1 instrhelp

: instrhelp ()
: instrhelp (funcname)
: instrhelp (obj)

Display instrument help

Inputs

funcname - function to display help about.
obj - object to display help about.

If no input is provided, the function will display and overview of the package functionality.

Outputs

None

3.2.2 instrhwinfo

Function File: [list] = instrhwinfo ()
Function File: list = instrhwinfo (interface)

Query available hardware for instrument-control

When run without any input parameters, instrhwinfo will provide the toolbox information and a list of supported interfaces.

Inputs

interface is the instrument interface to query. When provided, instrhwinfo will provide information on the specified interface.

Currently only interface "serialport","i2c" and "spi" and is supported, which will provide a list of available serial ports or i2c ports.

Outputs

If an output variable is provided, the function will store the information to the variable, otherwise it will be displayed to the screen.

Example

 instrhwinfo
 scalar structure containing the fields:

    ToolboxVersion = 0.4.0
    ToolboxName = octave instrument control package
    SupportedInterfaces =
    {
      [1,1] = i2c
      [1,2] = parallel
      [1,3] = serialport
      [1,4] = tcp
      [1,5] = udp
      [1,6] = usbtmc
      [1,7] = vxi11
    }

3.2.3 resolvehost

Loadable Function: name = resolvehost (host)
Loadable Function: [name, address] = resolvehost (host)
Loadable Function: out = resolvehost (host, returntype)

Resolve a network host name or address to network name and address

Inputs

host - Host name or IP address string to resolve.
name - Resolved IP host name.
returntype - ’name’ to get host name, ’address’ to get IP address.

Outputs

name - Resolved IP host name.
address - Resolved IP host address.
out - host name if returntype is ’name’, ipaddress if returntype is ’address’

Example

%% get resolved ip name and address of www.gnu.org
[name, address] = resolvehost ('www.gnu.org');

%% get ip address of www.gnu.org
ipaddress = resolvehost ('www.gnu.org', 'address');

See also: tcp, udp.


3.3 GPIB

3.3.1 @octave_gpib/fclose

Function File: res = fclose (obj)

Closes connection to GPIB device obj

3.3.2 @octave_gpib/fopen

Function File: res = fopen (obj) (dummy)

Opens connection to GPIB device obj This currently is a dummy function to improve compatibility to MATLAB

3.3.3 @octave_gpib/fprintf

Function File: fprintf (obj, cmd)
Function File: fprintf (obj, format, cmd)
Function File: fprintf (obj, cmd, mode)
Function File: fprintf (obj, format, cmd, mode)

Writes string cmd to GPIB instrument

obj is a GPIB object

cmd String format Format specifier mode sync

3.3.4 @octave_gpib/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from GPIB instrument

obj is a GPIB object

size Number of values to read. (Default: 100) precision precision of data

count values read errmsg read operation error message

3.3.5 @octave_gpib/fscanf

Function File: res = fscanf (obj)
Function File: res = fscanf (obj, format)
Function File: res = fscanf (obj, format, size)
Function File: [res,count] = fscanf (obj, ...)
Function File: [res,count,errmsg] = fscanf (obj, ...)

Reads data res from GPIB instrument

obj is a GPIB object

format Format specifier size number of values

count values read errmsg read operation error message

3.3.6 @octave_gpib/fwrite

Function File: fwrite (obj, data)
Function File: fwrite (obj, data, precision)
Function File: fwrite (obj, data, mode)
Function File: fwrite (obj, data, precision, mode)

Writes data to GPIB instrument

obj is a GPIB object

data data to write precision precision of data mode sync

3.3.7 clrdevice

Function File: clrdevice (obj)

Send clear command to Clear GPIB instrument.

obj is a GPIB object

3.3.8 gpib

Loadable Function: gpib = gpib ([gpibid], [timeout])

Open gpib interface.

gpibid - the interface number.
timeout - the interface timeout value. If omitted defaults to blocking call.

The gpib() shall return instance of octave_gpib class as the result gpib.

3.3.9 gpib_close

Loadable Function: gpib_close (gpib)

Close the interface and release a file descriptor.

gpib - instance of octave_gpib class.

3.3.10 gpib_read

Loadable Function: [data, count, eoi] = gpib_read (gpib, n)

Read from gpib interface.

gpib - instance of octave_gpib class.
n - number of bytes to attempt to read of type Integer.

The gpib_read() shall return number of bytes successfully read in count as Integer and the bytes themselves in data as uint8 array. eoi indicates read operation complete

3.3.11 gpib_timeout

Loadable Function: gpib_timeout (gpib, timeout)
Loadable Function: t = gpib_timeout (gpib)

Set new or get existing gpib interface timeout parameter. The timeout value is valid from 0 to 17.

gpib - instance of octave_gpib class.
timeout - Value of 0 means never timeout, 11 means one second and 17 means 1000 seconds (see GPIB documentation (ibtmo) for further details)

If timeout parameter is omitted, the gpib_timeout() shall return current timeout value as the result t.

3.3.12 gpib_write

Loadable Function: n = gpib_write (gpib, data)

Write data to a gpib interface.

gpib - instance of octave_gpib class.
data - data to be written to the gpib interface. Can be either of String or uint8 type.

Upon successful completion, gpib_write() shall return the number of bytes written as the result n.

3.3.13 spoll

Function File: out = spoll (obj)
Function File: [out,statusByte] = spoll (obj)

Serial polls GPIB instruments.

obj is a GPIB object or a cell array of GPIB objects

out GPIB objects ready for service statusByte status Byte

3.3.14 trigger

Function File: trigger (obj)

Triggers GPIB instrument.

obj is a GPIB object


3.4 I2C

3.4.1 @octave_i2c/fclose

Function File: res = fclose (obj)

Closes I2C connection obj

3.4.2 @octave_i2c/fopen

Function File: res = fopen (obj) (dummy)

Opens I2C connection obj

This currently is a dummy function to improve compatibility to MATLAB

3.4.3 @octave_i2c/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from I2C instrument

Inputs

obj is a I2C object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data data values.
count number of values read.
errmsg read operation error message.

3.4.4 @octave_i2c/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to I2C instrument

Inputs

obj is a I2C object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.4.5 @octave_i2c/get

Function File: struct = get (i2c)
Function File: field = get (i2c, property)

Get the properties of i2c object.

Inputs

i2c - instance of octave_i2c class.

property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_i2c/set.

3.4.6 @octave_i2c/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of i2c object.

Inputs

obj - instance of octave_i2c class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’name’

Set the name for the i2c socket.

’remoteaddress’

Set the remote address for the i2c socket.

Outputs

None

See also: @octave_i2c/get.

3.4.7 i2c

Loadable Function: i2c = i2c ([port_path], [address])

Open i2c interface.

Inputs

port_path - the interface device port/path of type String. If omitted defaults to ’/dev/i2c-0’.
address - the slave device address. If omitted must be set using i2c_addr() call.

Outputs

i2c - An instance of octave_i2c class.

Properties

The i2c object has the following properties:

name

Name of the object

remoteaddress

the slave device address

port

The interface driver port (readonly)

3.4.8 i2c_addr

Loadable Function: i2c_addr (i2c, address)
Loadable Function: addr = i2c_addr (i2c)

Set new or get existing i2c slave device address.

Inputs

i2c - instance of octave_i2c class.
address - i2c slave device address of type Integer. The address is passed in the 7 or 10 lower bits of the argument.

Outputs

addr - If address parameter is omitted, the i2c_addr() shall return current i2c slave device address.

3.4.9 i2c_close

Loadable Function: i2c_close (i2c)

Close the interface and release a file descriptor.

Inputs

i2c - instance of octave_i2c class.

Outputs

None

3.4.10 i2c_read

Loadable Function: [data, count] = i2c_read (i2c, n)

Read from i2c slave device.

Inputs

i2c - instance of octave_i2c class.
n - number of bytes to attempt to read of type Integer.

Outputs

The i2c_read() shall return number of bytes successfully read in count as Integer and the bytes themselves in data as uint8 array.

3.4.11 i2c_write

Loadable Function: n = i2c_write (i2c, data)

Write data to a i2c slave device.

Inputs

i2c - instance of octave_i2c class.
data - data, of type uint8, to be written to the slave device.

Outputs

Upon successful completion, i2c_write() shall return the number of bytes written as the result n.


3.5 Modbus

3.5.1 @octave_modbus/get

Function File: struct = get (dev)
Function File: field = get (dev, property)

Get the properties of modbus object.

Inputs

dev - instance of octave_modbus class.
property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_modbus/set.

3.5.2 @octave_modbus/maskWrite

: data = maskWrite (dev, address, andmask, ormask)
: data = maskWrite (dev, address, andmask, ormask, serverid)

Read holding register at address from modbus device dev apply masking and write the change data.

writeregister value = (readregister value AND andMask) OR (orMask AND (NOT andMask))

Inputs

dev - connected modbus device

address - address to read from.

andmask - AND mask to apply to the register

ormask - OR mask to apply to the register

serverId - address to send to (0-247). Default of 1 is used if not specified.

Outputs

data - data read from the device

See also: modbus.

3.5.3 @octave_modbus/read

: data = read (dev, target, address)
: data = read (dev, target, address, count)
: data = read (dev, target, address, count, serverId, precision)

Read data from modbus device dev target target starting at address address.

Inputs

dev - connected modbus device

target - target type to read. One of ’coils’, ’inputs’, ’inputregs’ or ’holdingregs’

address - address to start reading from.

count - number of elements to read. If not provided, count is 1.

serverId - address to send to (0-247). Default of 1 is used if not specified.

precision - Optional precision for how to interpret the read data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double.

Outputs

data - data read from the device

See also: modbus.

3.5.4 @octave_modbus/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of modbus object.

Inputs

obj - instance of octave_modbus class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’Name’

Set the stored string name of the object.

’Timeout’

Set the timeout value.

’Numretries’

Set the numretries value.

’ByteOrder’

Set the byteorder value

’WordOrder’

Set the wordorder value

’UserData’

Set the userdata value

Outputs

None

See also: @octave_modbus/get.

3.5.5 @octave_modbus/write

: write (dev, target, address, values)
: read (dev, target, address, values, serverId, precision)

Write data data to modbus device dev target target starting at address address.

Inputs

dev - connected modbus device

target - target type to read. One of ’coils’ or ’holdingregs’

address - address to start reading from.

data - data to write.

serverId - address to send to (0-247). Default of 1 is used if not specified.

precision - Optional precision for how to interpret the write data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double.

Outputs

None

See also: modbus.

3.5.6 @octave_modbus/writeRead

: data = writeRead (dev, writeAddress, values, readAddress, readcount)
: data = writeRead (dev, writeAddress, values, readAddress, readcount, serverId)
: data = writeRead (dev, writeAddress, values, writePrecision, readAddress, readCount, readPrecision)

Write data values to the modbus device dev holding registers starting at address writeAddress and then read readCount register values starting at address readAddress.

Inputs

dev - connected modbus device

writeAddress - address to start writing to.

values - data to write to the device.

readAddress - address to start reading from.

readCount - number of elements to read.

serverId - address to send to (0-247). Default of 1 is used if not specified.

precision - Optional precision for how to interpret the read data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double.

Outputs

data - data read from the device

See also: modbus.

3.5.7 modbus

Loadable Function: dev = modbus ('tcpip', deviceaddress)
Loadable Function: dev = modbus ('tcpip', deviceaddress, remoteport)
Loadable Function: dev = modbus ('tcpip', deviceaddress, name, value)
Loadable Function: dev = modbus ('serialrtu', serialport)
Loadable Function: dev = modbus ('serialrtu', serialport, name, value)

Open modbus interface using a specified transport of ’tcpip’ or ’serialrtu’.

Inputs

deviceaddress - the device ip address of type String.
remoteport - the device remote port number. If not specified, a default of 502 will be used.
name, value - Optional name value pairs for setting properties of the object.
serialport - the name of the serial port to connect to. It must be specified when transport is ’serialrtu’.

Common Input Name, Value pairs

Timeout

timeout value used for waiting for data

NumRetries

number of retries after a timeout

UserData

Additional data to attach to the object

Serial RTU Input Name, Value pairs

BaudRate

Baudrate for the serial port

DataBits

number of databits for serial port

Parity

Parity for serial port (’odd’, ’even’ or ’none’)

StopBits

number of stopbits for serial port

Outputs

The modbus() shall return instance of octave_modbus class as the result modbus.

Properties

The modbus object has the following public properties:

Name

name assigned to the modbus object

Type

instrument type ’modbus’ (readonly)

Port

Remote port number or serial port name (readonly)

DeviceAddress

Device address if transport was ’tcpip’ (readonly)

Status

status of the object ’open’ or ’closed’ (readonly)

Timeout

timeout value used for waiting for data

NumRetries

number of retries after a timeout

UserData

Additional data to attach to the object


3.6 Parallel

3.6.1 @octave_parallel/fclose

Function File: res = fclose (obj)

Closes parallel connection obj

3.6.2 @octave_parallel/fopen

Function File: res = fopen (obj) (dummy)

Opens parallel interface obj

This currently is a dummy function to improve compatibility to MATLAB

3.6.3 @octave_parallel/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from parallel instrument

Inputs

obj is a parallel object.
size Number of values to read. (Default: 1).
precision precision of data.

Outputs

data The read data.
count values read.
errmsg read operation error message.

3.6.4 @octave_parallel/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to parallel instrument

Inputs

obj is a parallel object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.6.5 parallel

Loadable Function: parallel = parallel ([path], [direction])

Open Parallel interface.

Inputs

path - the interface path of type String. If omitted defaults to ’/dev/parport0’.
direction - the direction of interface drivers of type Integer, see: PP_DATADIR for more info. If omitted defaults to 1 (Input).

Outputs

The parallel() shall return instance of octave_parallel class as the result parallel.

3.6.6 pp_close

Loadable Function: pp_close (parallel)

Close the interface and release a file descriptor.

Inputs

parallel - instance of octave_serial class.

Outputs

None

3.6.7 pp_ctrl

Loadable Function: pp_ctrl (parallel, ctrl)
Loadable Function: c = pp_ctrl (parallel)

Sets or Read the Control lines.

Inputs

parallel - instance of octave_parallel class.
ctrl - control parameter to be set of type Byte.

Outputs

If ctrl parameter is omitted, the pp_ctrl() shall return current Control lines state as the result c.

3.6.8 pp_data

Loadable Function: pp_data (parallel, data)
Loadable Function: d = pp_data (parallel)

Sets or Read the Data lines.

Inputs

parallel - instance of octave_parallel class.
data - data parameter to be set of type Byte.

Outputs

If data parameter is omitted, the pp_data() shall return current Data lines state as the result d.

3.6.9 pp_datadir

Loadable Function: pp_datadir (parallel, direction)
Loadable Function: dir = pp_datadir (parallel)

Controls the Data line drivers.

Normally the computer’s parallel port will drive the data lines, but for byte-wide transfers from the peripheral to the host it is useful to turn off those drivers and let the peripheral drive the signals. (If the drivers on the computer’s parallel port are left on when this happens, the port might be damaged.)

Inputs

parallel - instance of octave_parallel class.
direction - direction parameter of type Integer. Supported values: 0 - the drivers are turned on (Output/Forward direction); 1 - the drivers are turned off (Input/Reverse direction).

Outputs

If direction parameter is omitted, the pp_datadir() shall return current Data direction as the result dir.

3.6.10 pp_stat

Loadable Function: stat = pp_stat (parallel)

Reads the Status lines.

Inputs

parallel - instance of octave_parallel class.

Outputs

The pp_stat() shall return current Status lines state as the result stat.


3.7 Serial (Deprecated)

3.7.1 @octave_serial/fclose

Function File: res = fclose (obj)

Closes SERIAL connection obj

3.7.2 @octave_serial/flushinput

Loadable Function: flushinput (serial)

Flush the pending input, which will also make the BytesAvailable property be 0.

Inputs

serial - instance of octave_serial class.

Outputs

None

See also: srl_flush, flushoutput.

3.7.3 @octave_serial/flushoutput

Loadable Function: flushoutput (serial)

Flush the output buffer.

Inputs

serial - instance of octave_serial class.

Outputs

None

See also: srl_flush, flushinput.

3.7.4 @octave_serial/fopen

Function File: res = fopen (obj) (dummy)

Opens SERIAL interface obj

This currently is a dummy function to improve compatibility to MATLAB

3.7.5 @octave_serial/fprintf

Function File: numbytes = fprintf (obj, template ...)

Writes formatted string template using optional parameters to serial instrument

Inputs

obj is a serial object.
template Format template string

Outputs

numbytes - number of bytes written to the serial device.

3.7.6 @octave_serial/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from serial instrument

Inputs

obj is a serial object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data The read data.
count values read.
errmsg read operation error message.

3.7.7 @octave_serial/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to serial instrument

Inputs

obj is a serial object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.7.8 @octave_serial/get

Function File: struct = get (serial)
Function File: field = get (serial, property)

Get the properties of serial object.

Inputs

serial - instance of octave_serial class.
property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_serial/set.

3.7.9 @octave_serial/serialbreak

Function File: serialbreak (serial)
Function File: serialbreak (serial, time)

Send a break to the serial port

Inputs

serial - serial object
time - number of milliseconds to break for. If not specified a value of 10 will be used.

Outputs

None

See also: serial.

3.7.10 @octave_serial/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of serial object.

Inputs

serial - instance of octave_serial class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’baudrate’

Set the baudrate of serial port. Supported values by instrument-control: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your serial port may be different.

’bytesize’

Set the bytesize. Supported values: 5, 6, 7 and 8.

’name’

Set the stored string name of the serial object.

’parity’

Set the parity value. Supported values: Even/Odd/None. This Parameter must be of type string. It is case insensitive and can be abbreviated to the first letter only

’stopbits’

Set the number of stopbits. Supported values: 1, 2.

’timeout’

Set the timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds).

’requesttosend’

Set the requesttosend (RTS) line.

’dataterminalready’

Set the dataterminalready (DTR) line.

Outputs

None

See also: @octave_serial/get.

3.7.11 @octave_serial/srl_baudrate

Loadable Function: srl_baudrate (serial, baudrate)\
Loadable Function: br = srl_baudrate (serial)

Set new or get existing serial interface baudrate parameter. Only standard values are supported.

Inputs

serial - instance of octave_serial class.
baudrate - the baudrate value used. Supported values: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600 19200, 38400, 57600, 115200 and 230400.

If baudrate parameter is omitted, the srl_baudrate() shall return current baudrate value as the result br.

Outputs

br - The currently set baudrate

This function is obsolete. Use get and set method instead.

3.7.12 @octave_serial/srl_bytesize

Loadable Function: srl_bytesize (serial, bsize)
Loadable Function: bs = srl_bytesize (serial)

Set new or get existing serial interface byte size parameter.

Inputs

serial - instance of octave_serial class.
bsize - byte size of type Integer. Supported values: 5/6/7/8.

If bsize parameter is omitted, the srl_bytesize() shall return current byte size value or in case of unsupported setting -1, as the result bs.

This function is obsolete. Use get and set method instead.

Outputs

bs -the currently set byte size.

3.7.13 @octave_serial/srl_close

Loadable Function: srl_close (serial)

Close the interface and release a file descriptor.

Inputs

serial - instance of octave_serial class.

This function is obsolete. Use fclose() method instead.

Outputs

None

3.7.14 @octave_serial/srl_flush

Loadable Function: srl_flush (serial, [q])

Flush the pending input/output.

Inputs

serial - instance of octave_serial class.
q - queue selector of type Integer. Supported values:

0

flush untransmitted output

1

flush pending input

2

flush both pending input and untransmitted output.

If q parameter is omitted, the srl_flush() shall flush both, input and output buffers.

Outputs

None

3.7.15 @octave_serial/srl_parity

Loadable Function: srl_parity (serial, parity)
Loadable Function: p = srl_parity (serial)

Set new or get existing serial interface parity parameter. Even/Odd/None values are supported.

Inputs

serial - instance of octave_serial class.
parity - parity value of type String. Supported values: Even/Odd/None (case insensitive, can be abbreviated to the first letter only)

If parity parameter is omitted, the srl_parity() shall return current parity value as the result p.

This function is obsolete. Use get and set method instead.

Outputs

p - The currently set parity

3.7.16 @octave_serial/srl_stopbits

Loadable Function: srl_stopbits (serial, stopb)
Loadable Function: sb = srl_stopbits (serial)

Set new or get existing serial interface stop bits parameter. Only 1 or 2 stop bits are supported.

Inputs

serial - instance of octave_serial class.
stopb - number of stop bits used. Supported values: 1, 2.

Outputs

If stopb parameter is omitted, the srl_stopbits() shall return current stop bits value as the result sb.

This function is obsolete. Use get and set method instead.

3.7.17 @octave_serial/srl_timeout

Loadable Function: srl_timeout (serial, timeout)
Loadable Function: t = srl_timeout (serial)

Set new or get existing serial interface timeout parameter used for srl_read() requests. The timeout value is specified in tenths of a second.

Inputs

serial - instance of octave_serial class.
timeout - srl_read() timeout value in tenths of a second. A value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds).

Outputs

If timeout parameter is omitted, the srl_timeout() shall return current timeout value as the result t.

This function is obsolete. Use get and set method instead.

3.7.18 serial

Loadable Function: serial = serial ([path], [baudrate], [timeout])

Open serial interface.

Inputs

path - the interface path of type String.
baudrate - the baudrate of interface. If omitted defaults to 115200.
timeout - the interface timeout value. If omitted defaults to blocking call.

Outputs

The serial() shall return an instance of octave_serial class as the result serial.

Properties

The serial object has the following public properties:

name

name assigned to the object

type

instrument type ’serial’ (readonly)

port

OS specific port name (readonly)

status

status of the object ’open’ or ’closed’ (readonly)

timeout

timeout value used for waiting for data

bytesavailable

number of bytes currently available to read (readonly)

stopbits

number of stopbits to use

requesttosend

request to send state - ’on’ or ’off’

parity

Parity setting ’none’, ’even’, ’odd’

bytesize

Number of bits to a byte (7 or 8)

baudrate

Baudrate setting

dataterminalready

state of dataterminal ready - ’on’ or ’off’

pinstatus

current state of pins (readonly)

3.7.19 seriallist

Function File: list = seriallist ()

Returns a list of all serial ports detected in the system.

Inputs

None

Outputs

list is a string cell array of serial ports names detected in the system.

See also: instrhwinfo("serial").

3.7.20 srl_read

Loadable Function: [data, count] = srl_read (serial, n)

Read from serial interface.

Inputs

serial - instance of octave_serial class.
n - number of bytes to attempt to read of type Integer.

Outputs

The srl_read() shall return number of bytes successfully read in count as Integer and the bytes themselves in data as uint8 array.

3.7.21 srl_write

Loadable Function: n = srl_write (serial, data)

Write data to a serial interface.

Inputs

serial - instance of octave_serial class.
data - data to be written to the serial interface. Can be either of String or uint8 type.

Outputs

Upon successful completion, srl_write() shall return the number of bytes written as the result n.


3.8 Serial Port

3.8.1 @octave_serialport/configureTerminator

Function File: configureTerminator (serial, term)
Function File: configureTerminator (serial, readterm, writeterm)

Set terminator for ASCII string manipulation

Inputs

serial - serialport object
term - terminal value for both read and write
readterm = terminal value type for read data
writeterm = terminal value for written data

The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255.

Outputs

None

See also: serialport.

3.8.2 @octave_serialport/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the serial port buffers

Inputs

dev - connected serialport device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: serialport.

3.8.3 @octave_serialport/fprintf

Function File: numbytes = fprintf (obj, template ...)

Writes formatted string template using optional parameters to serialport instrument

Inputs

obj is a serialport object.
template Format template string

Outputs

numbytes - number of bytes written to the serial device.

3.8.4 @octave_serialport/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from serial port instrument

Inputs

obj is a serialport object.
size Number of values to read.
precision precision of data.

Outputs

data The read data.
count number of values read.
errmsg read operation error message.

3.8.5 @octave_serialport/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to serial port instrument

Inputs

obj is a serial port object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.8.6 @octave_serialport/get

Function File: struct = get (serial)
Function File: field = get (serial, property)

Get the properties of serialport object.

Inputs

serial - instance of octave_serialport class.
property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_serial/set.

3.8.7 @octave_serialport/getpinstatus

Function File: status getpinstatus (serial)

Get status of serial pins

Inputs

serial - serial object

Outputs

status - a structure with the logic names of ClearToSend, DataSetReady, CarrierDetect, and RingIndicator

See also: serialport.

3.8.8 @octave_serialport/read

: data = read (dev, count)
: data = read (dev, count, precision)

Read a specified number of values from a serialport using optional precision for valuesize.

Inputs

dev - connected serialport device

count - number of elements to read

precision - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16, uint32, int32, uint64, uint64

Outputs

data - data read from the device

See also: serialport.

3.8.9 @octave_serialport/serialbreak

Function File: serialbreak (serial)
Function File: serialbreak (serial, time)

Send a break to the serial port

Inputs

serial - serialport object
time - number of milliseconds to break for. If not specified a value of 10 will be used.

Outputs

None

See also: serial.

3.8.10 @octave_serialport/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of serialport object.

Inputs

serial - instance of octave_serialport class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’baudrate’

Set the baudrate of serial port. Supported values by instrument-control: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your serial port may be different.

’bytesize’

Set the bytesize. Supported values: 5, 6, 7 and 8.

’name’

Set the stored string name of the serial object.

’parity’

Set the parity value. Supported values: Even/Odd/None. This Parameter must be of type string. It is case insensitive and can be abbreviated to the first letter only

’stopbits’

Set the number of stopbits. Supported values: 1, 2.

’timeout’

Set the timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds).

’requesttosend’

Set the requesttosend (RTS) line.

’dataterminalready’

Set the dataterminalready (DTR) line.

Outputs

None

See also: @octave_serialport/-get.

3.8.11 @octave_serialport/setDTR

: setDTR (dev, true_false)

Set the state of the DTR line

Inputs

dev - connected serial device.
true_false - state to set the line.

Outputs

None

See also: serialport, getpinstatus, setRTS.

3.8.12 @octave_serialport/setRTS

: setRTS (dev, true_false)

Set the state of the RTS line

Inputs

dev - connected serial device.
true_false - state to set the line.

Outputs

None

See also: serialport, getpinstatus.

3.8.13 @octave_serialport/write

Function File: numbytes = write (obj, data)
Function File: numbytes = write (obj, data, precision)

Writes data to serialport instrument

Inputs

obj is a serialport object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.8.14 serialport

Loadable Function: serial = serialport ([path], [baudrate])
Loadable Function: serial = serialport ([path], [propname, propvalue])

Open serial port interface.

Inputs

path - the interface path of type String.
baudrate - the baudrate of interface.
propname,propvalue - property name/value pairs.

Known input properties:

BaudRate

Numeric baudrate value

Timeout

Numeric timeout value in seconds or -1 to wait forever

StopBits

number of stopbits to use

Parity

Parity setting ’none’, ’even’, ’odd’

DataBits

Number of bits to a byte (5 to 8)

FlowControl

Number of bits to a byte ’none’, ’hardware’, ’software’

Outputs

The serialport() shall return an instance of octave_serialport class as the result serial.

Properties

The serial object has the following public properties:

Name

name assigned to the object

Type

instrument type ’serial’ (readonly)

Port

OS specific port name (readonly)

Status

status of the object ’open’ or ’closed’ (readonly)

Timeout

timeout value used for waiting for data

NumBytesAvailable

number of bytes currently available to read (readonly)

NumBytesWritten

number of bytes written (readonly)

StopBits

number of stopbits to use

Parity

Parity setting ’none’, ’even’, ’odd’

DataBits

Number of bits to a byte (5 to 8)

BaudRate

Baudrate setting

FlowControl

Number of bits to a byte ’none’, ’hardware’, ’software’

PinStatus

current state of pins (readonly)

UserData

user defined data

3.8.15 serialportlist

Function File: list = serialportlist ()
Function File: list = serialportlist ("all")
Function File: list = serialportlist ("available")

Returns a list of all serial ports detected in the system.

Inputs

’all’ - show all serial ports (same as providing no arguments) ’available’ - show only serial ports that are available for use

Outputs

list is a string cell array of serial ports names detected in the system.

See also: instrhwinfo("serialport").


3.9 SPI

3.9.1 @octave_spi/fclose

Function File: res = fclose (obj)

Closes SPI connection obj

3.9.2 @octave_spi/fopen

Function File: res = fopen (obj) (dummy)

Opens SPI connection obj

This currently is a dummy function to improve compatibility to MATLAB

3.9.3 @octave_spi/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from a SPI instrument

Inputs

obj is a SPI object.
size Number of values to read. (Default: 10).
precision precision of data.

Outputs

data data values.
count number of values read.
errmsg read operation error message.

3.9.4 @octave_spi/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to SPI instrument

Inputs

obj is a SPI object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.9.5 @octave_spi/get

Function File: struct = get (spi)
Function File: field = get (spi, property)

Get the properties of spi object.

Inputs

spi - instance of octave_spi class.

property - name of property.

Properties

’name’

Name for the spi socket.

’bitrate’

The bitrate for the spi object.

’clockpolarity’

The clock polarity for the spi object of ’idlehigh’ or ’idlelow’.

’clockphase’

The clock phase for the spi object of ’firstedge’ or ’secondedge’.

’port’

The device port name.

’status’

The device status of ’open’ or ’closed’

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_spi/set.

3.9.6 @octave_spi/read

Function File: data = read (obj)
Function File: data = read (obj, size)

Reads data from SPI instrument

Inputs

obj is a SPI object.
size Number of values to read. (Default: 10).

Outputs

data data values.

3.9.7 @octave_spi/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of spi object.

Inputs

obj - instance of octave_spi class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’name’

Set the name for the spi socket.

’bitrate’

Set the bitrate for the spi object.

’clockpolarity’

Set the clock polarity for the spi object of ’idlehigh’ or ’idlelow’.

’clockphase’

Set the clock phase for the spi object of ’firstedge’ or ’secondedge’.

Outputs

None

See also: @octave_spi/get.

3.9.8 @octave_spi/write

Function File: numbytes = fwrite (obj, data)

Writes data to SPI instrument

Inputs

obj is a SPI object.
data data to write.

Outputs

returns number of bytes written.

3.9.9 @octave_spi/writeAndRead

Function File: data = writeAndRead (obj, wrdata)

Writes and reads data from SPI instrument

Inputs

obj is a SPI object.
wrdata Data to write.

Outputs

data data values read.

3.9.10 spi

Loadable Function: spi = spi ([port_path])
Loadable Function: spi = spi ([port_path], [propname, propvalue])

Open a spi interface.

Inputs

port_path - the interface device port/path of type String. If omitted defaults to ’/dev/spi-0’.
propname,propvalue - property name/value pairs.

Known input properties:

name

Name of the object

bitrate

Numeric bitrate value

clockpolarity

Clock polarity: idlehigh or idlelow.

clockphase

Clock phase value: firstedge or secondedge

Outputs

spi - An instance of octave_spi class.

Properties

The spi object has the following properties:

name

Name of the object

status

Open or closed status of object (readonly).

bitrate

Numeric bitrate value

clockpolarity

Clock polarity: idlehigh or idlelow.

clockphase

Clock phase value: firstedge or secondedge

port

The interface driver port (readonly)

3.9.11 spi_close

Loadable Function: spi_close (spi)

Close the interface and release a file descriptor.

Inputs

spi - instance of octave_spi class.

Outputs

None

3.9.12 spi_read

Loadable Function: [data, count] = spi_read (spi, n)

Read from spi slave device.

Inputs

spi - instance of octave_spi class.
n - number of bytes to attempt to read of type Integer.

Outputs

The spi_read() shall return number of bytes successfully read in count as Integer and the bytes themselves in data as uint8 array.

3.9.13 spi_write

Loadable Function: n = spi_write (spi, data)

Write data to a spi slave device.

Inputs

spi - instance of octave_spi class.
data - data, of type uint8, to be written to the slave device.

Outputs

Upon successful completion, spi_write() shall return the number of bytes written as the result n.

3.9.14 spi_writeAndRead

Loadable Function: rddata = spi_writeAndRead (spi, wrdata)

Write data to a spi slave device and then read same number of values.

Inputs

spi - instance of octave_spi class.
wrdata - data, of type uint8, to be written to the slave device.

Outputs

Upon successful completion, spi_writeAndRead() shall return the bytes read.


3.10 TCP (Deprecated)

3.10.1 @octave_tcp/fclose

Function File: res = fclose (obj)

Closes TCP connection obj

3.10.2 @octave_tcp/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the tcp socket buffers

Inputs

dev - connected tcp device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: serialport.

3.10.3 @octave_tcp/flushinput

Loadable Function: flushinput (tcp)

Flush the pending input, which will also make the BytesAvailable property be 0.

Inputs

tcp - instance of octave_tcp class.

Outputs

None.

See also: flushoutput.

3.10.4 @octave_tcp/flushoutput

Loadable Function: flushoutput (tcp)

Flush the output buffer.

Inputs

tcp - instance of octave_tcp class.

Outputs

None.

See also: flushinput.

3.10.5 @octave_tcp/fopen

Function File: res = fopen (obj) (dummy)

Opens TCP connection obj

This currently is a dummy function to improve compatibility to MATLAB

3.10.6 @octave_tcp/fprintf

Function File: numbytes = fprintf (obj, template ...)

Writes formatted string template using optional parameters to TCP instrument

Inputs

obj is a TCP object.
template Format template string

Outputs

Number of characters written

3.10.7 @octave_tcp/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from TCP instrument

Inputs

obj is a TCP object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data data read.
count values read.
errmsg read operation error message.

3.10.8 @octave_tcp/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to TCP instrument

Inputs

obj is a TCP object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.10.9 @octave_tcp/get

Function File: struct = get (tcp)
Function File: field = get (tcp, property)

Get the properties of tcp object.

Inputs

tcp - instance of octave_tcp class.
property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_tcp/set.

3.10.10 @octave_tcp/read

Function File: data = read (obj)
Function File: data = read (obj, size)
Function File: data = read (obj, size, datatype)

Reads data from TCP instrument

Inputs

obj is a TCP object.
size Number of values to read. (Default: 100).
datatype datatype of data.

Outputs

data data read.

3.10.11 @octave_tcp/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of tcp object.

Inputs

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’name’

Set the name for the tcp socket.

’remotehost’

Set the remote host name for the tcp socket.

’remoteport’

Set the remote port for the tcp socket.

’timeout’

Set the timeout value in seconds. Value of -1 means a blocking call.

Outputs

None

See also: @octave_tcp/get.

3.10.12 @octave_tcp/write

Function File: numbytes = write (obj, data)
Function File: numbytes = write (obj, data, datatype)

Writes data to TCP instrument

Inputs

obj is a TCP object.
data data to write.
datatype datatype of data. If not specified, it defaults to "uint8".

Outputs

returns number of bytes written.

3.10.13 tcp

Loadable Function: tcp = tcp ()
Loadable Function: tcp = tcp (ipaddress)
Loadable Function: tcp = tcp (ipaddress, port)
Loadable Function: tcp = tcp (ipaddress, port, timeout)
Loadable Function: tcp = tcp (ipaddress, [propertyname, propertyvalue])
Loadable Function: tcp = tcp (ipaddress, port, [propertyname, propertyvalue])

Open tcp interface.

Inputs

ipaddress - the ip address of type String. If omitted defaults to ’127.0.0.1’.
port - the port number to connect. If omitted defaults to 23.
timeout - the interface timeout value. If omitted defaults to blocking call.
propname,propvalue - property name/value pairs.

Known input properties:

name

name value

timeout

Numeric timeout value or -1 to wait forever

Outputs

The tcp() shall return instance of octave_tcp class as the result tcp.

Properties

The tcp object has the following public properties:

name

name assigned to the tcp object

type

instrument type ’tcp’ (readonly)

localport

local port number (readonly)

remoteport

remote port number

remotehost

remote host

status

status of the object ’open’ or ’closed’ (readonly)

timeout

timeout value in seconds used for waiting for data

bytesavailable

number of bytes currently available to read (readonly)

3.10.14 tcp_close

Loadable Function: tcp_close (tcp)

Close the interface and release a file descriptor.

Inputs

tcp - instance of octave_tcp class.

Outputs

None

3.10.15 tcp_read

Loadable Function: [data, count] = tcp_read (tcp, n, timeout)

Read from tcp interface.

Inputs

tcp - instance of octave_tcp class.
n - number of bytes to attempt to read of type Integer
timeout - timeout in ms if different from default of type Integer

Outputs

count - number of bytes successfully read as an Integer
data - data bytes themselves as uint8 array.

3.10.16 tcp_timeout

Loadable Function: tcp_timeout (tcp, timeout)
Loadable Function: t = tcp_timeout (tcp)

Set new or get existing tcp interface timeout parameter used for tcp_read() requests. The timeout value is specified in milliseconds.

Inputs

tcp - instance of octave_tcp class.
timeout - tcp_read() timeout value in milliseconds. Value of -1 means a blocking call.

Outputs

If timeout parameter is omitted, the tcp_timeout() shall return current timeout value as the result t.

3.10.17 tcp_write

Loadable Function: n = tcp_write (tcp, data)

Write data to a tcp interface.

Inputs

tcp - instance of octave_tcp class.
data - data to be written to the tcp interface. Can be either of String or uint8 type.

Outputs

Upon successful completion, tcp_write() shall return the number of bytes written as the result n.

3.10.18 tcpip

Function File: tcp = tcpip (host, [port], [PropertyName, PropertyValue...])

Matlab compatible wrapper to the tcp interface.

NOTE: tcpip has been deprecated. Use tcpclient instead

Inputs

host - the host name or ip.
port - the port number to connect. If omitted defaults to 80.
PropertyName, PropertyValue - Optional property name, value pairs to set on the tcp object.

Properties

Currently the only known properties are "timeout" and "name".

Outputs

tcpip will return an instance of octave_tcp class as the result.


3.11 TCP Client

3.11.1 @octave_tcpclient/configureTerminator

Function File: configureTerminator (tcp, term)
Function File: configureTerminator (tcp, readterm, writeterm)

Set terminator on a tcpclient object for ASCII string manipulation

Inputs

tcp - tcpclient object
term - terminal value for both read and write
readterm = terminal value type for read data
writeterm = terminal value for written data

The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255.

Outputs

None

See also: tcpport.

3.11.2 @octave_tcpclient/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the tcpclient socket buffers

Inputs

dev - connected tcpclient device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: serialport.

3.11.3 @octave_tcpclient/get

Function File: struct = get (tcpclient)
Function File: field = get (tcpclient, property)

Get the properties of tcpclient object.

Inputs

tcpclient - instance of octave_tcpclient class.
property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_tcpclient/set.

3.11.4 @octave_tcpclient/read

Function File: data = read (obj)
Function File: data = read (obj, size)
Function File: data = read (obj, size, datatype)

Reads data from TCP instrument

Inputs

obj is a TCP object.
size Number of values to read. (Default: NumBytesAvailable).
datatype datatype of data.

Outputs

data data read.

3.11.5 @octave_tcpclient/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of tcpclient object.

Inputs

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’Name’

Set the name for the tcpclient socket.

’UserData’

Set user data for the tcpclient socket.

’Timeout’

Set the timeout value in seconds. Value of -1 means a blocking call.

Outputs

None

See also: @octave_tcpclient/get.

3.11.6 @octave_tcpclient/write

Function File: numbytes = write (obj, data)
Function File: numbytes = write (obj, data, datatype)

Writes data to TCP instrument

Inputs

obj is a TCPclient object.
data data to write.
datatype datatype of data. If not specified, it defaults to "uint8".

Outputs

returns number of bytes written.

3.11.7 tcpclient

Loadable Function: tcpclient = tcpclient (ipaddress, port)
Loadable Function: tcpclient = tcpclient (ipaddress, port, [propertyname, propertyvalue])

Open tcpclient interface.

Inputs

ipaddress - the ip address of type String.
port - the port number to connect.
propname,propvalue - property name/value pairs.

Known input properties:

Name

name value

Timeout

Numeric timeout value or -1 to wait forever

EnableTransferDelay

Boolean to enable or disable the nagle algorithm for delay transfer.

UserData

User data value.

Outputs

The tcpclient() shall return instance of octave_tcpclient class as the result tcpclient.

Properties

The tcpclient object has the following public properties:

Name

name assigned to the tcpclient object

Type

instrument type ’tcpclient’ (readonly)

Port

remote port number (Readonly)

Address

remote host address (Readonly)

Status

status of the object ’open’ or ’closed’ (readonly)

Timeout

timeout value in seconds used for waiting for data

NumBytesAvailable

number of bytes currently available to read (readonly)

NumBytesWritten

number of bytes currently available to read (readonly)

ByteOrder

Byte order for data (currently not used)

Terminator

Terminator value used for string data (currently not used)

UserData

User data

EnableTransferDelay

Bool for whether transfer delay is enabled. (Read only)


3.12 TCP Server

3.12.1 @octave_tcpserver/configureTerminator

Function File: configureTerminator (tcp, term)
Function File: configureTerminator (tcp, readterm, writeterm)

Set terminator on a tcpserver object for ASCII string manipulation

Inputs

tcp - tcpserver object
term - terminal value for both read and write
readterm = terminal value type for read data
writeterm = terminal value for written data

The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255.

Outputs

None

See also: tcpport.

3.12.2 @octave_tcpserver/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the tcpserver socket buffers

Inputs

dev - connected tcpserver device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: serialport.

3.12.3 @octave_tcpserver/get

Function File: struct = get (tcpserver)
Function File: field = get (tcpserver, property)

Get the properties of tcpserver object.

Inputs

tcpserver - instance of octave_tcpserver class.
property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_tcpserver/set.

3.12.4 @octave_tcpserver/read

Function File: data = read (obj)
Function File: data = read (obj, size)
Function File: data = read (obj, size, datatype)

Reads data from TCP instrument

Inputs

obj is a TCP Server object.
size Number of values to read. (Default: NumBytesAvailable).
datatype datatype of data.

Outputs

data data read.

3.12.5 @octave_tcpserver/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of tcpserver object.

Inputs

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’Name’

Set the name for the tcpserver socket.

’UserData’

Set user data for the tcpserver socket.

’Timeout’

Set the timeout value in seconds. Value of -1 means a blocking call.

Outputs

None

See also: @octave_tcpserver/get.

3.12.6 @octave_tcpserver/write

Function File: numbytes = write (obj, data)
Function File: numbytes = write (obj, data, datatype)

Writes data to TCP instrument

Inputs

obj is a TCPServer object.
data data to write.
datatype datatype of data. If not specified, it defaults to "uint8".

Outputs

returns number of bytes written.

3.12.7 tcpserver

Loadable Function: tcpserver = tcpserver (ipaddress, port)
Loadable Function: tcpserver = tcpserver (port)
Loadable Function: tcpserver = tcpserver (…, [propertyname, propertyvalue])

Open tcpserver interface.

Inputs

ipaddress - the ip address of type String.
port - the port number to bind.
propname,propvalue - property name/value pairs.

Known input properties:

Name

name value

Timeout

Numeric timeout value or -1 to wait forever

UserData

User data value.

Outputs

The tcpserver() shall return instance of octave_tcpserver class as the result tcpserver.

Properties

The tcpserver object has the following public properties:

Connected

boolean flag for when connected to a client (Readonly)

ClientPort

connected client port number (Readonly)

ClientAddress

connected client address (Readonly)

Name

name assigned to the tcpserver object

Type

instrument type ’tcpserver’ (readonly)

ServerPort

server port number (Readonly)

ServerAddress

server address (Readonly)

Status

status of the object ’open’ or ’closed’ (readonly)

Timeout

timeout value in seconds used for waiting for data

NumBytesAvailable

number of bytes currently available to read (readonly)

NumBytesWritten

number of bytes currently available to read (readonly)

ByteOrder

Byte order for data (currently not used)

Terminator

Terminator value used for string data (currently not used)

UserData

User data


3.13 UDP (Deprecated)

3.13.1 @octave_udp/fclose

Function File: res = fclose (obj)

Closes UDP connection obj

3.13.2 @octave_udp/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the udp socket buffers

Inputs

dev - open udp device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: udp.

3.13.3 @octave_udp/flushinput

Loadable Function: flushinput (udp)

Flush the pending input, which will also make the BytesAvailable property be 0.

Inputs

udp - instance of octave_udp class.

Outputs

None

See also: flushoutput.

3.13.4 @octave_udp/flushoutput

Loadable Function: flushoutput (udp)

Flush the output buffer.

Inputs

udp - instance of octave_udp class.

Outputs

None

See also: flushinput.

3.13.5 @octave_udp/fopen

Function File: res = fopen (obj) (dummy)

Opens UDP connection obj This currently is a dummy function to improve compatibility to MATLAB

3.13.6 @octave_udp/fprintf

Function File: numbytes = fprintf (obj, template ...)

Writes formatted string template using optional parameters to UDP instrument

Inputs

obj is a UDP object.
template Format template string.

Outputs

numbytes is the number of bytes written to the device

3.13.7 @octave_udp/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from UDP instrument

Inputs

obj is a UDP object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data data values.
count number of values read.
errmsg read operation error message.

3.13.8 @octave_udp/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to UDP instrument

Inputs

obj is a UDP object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.13.9 @octave_udp/get

Function File: struct = get (udp)
Function File: field = get (udp, property)

Get the properties of udp object.

Inputs

udp - instance of octave_udp class.

property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_udp/set.

3.13.10 @octave_udp/read

Function File: data = read (obj)
Function File: data = read (obj, size)
Function File: data = read (obj, size, datatype)

Reads data from UDP instrument

Inputs

obj is a UDP object.
size Number of values to read. (Default: BytesAvailable).
datatype datatype of data.

Outputs

data data read.

3.13.11 @octave_udp/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of udp object.

Inputs

obj - instance of octave_udp class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’name’

Set the name for the udp socket.

’remotehost’

Set the remote host name for the udp socket.

’remoteport’

Set the remote port for the udp socket.

’timeout’

Set the timeout value in seconds. Value of -1 means a blocking call.

Outputs

None

See also: @octave_udp/get.

3.13.12 @octave_udp/write

Function File: numbytes = write (obj, data)
Function File: numbytes = write (obj, data, destinationAddress, destinationPort))
Function File: numbytes = write (obj, data, datatype)
Function File: numbytes = write (obj, data, datatype, destinationAddress, destinationPort)

Writes data to UDP instrument

Inputs

obj is a UDP object.
data data to write.
datatype datatype of data. If not specified defaults to uint8.
destinationAddress ipaddress to send to. If not specified, use the remote address.
destinationPort port to send to. If not specified, use the remote port.

Outputs

returns number of bytes written.

3.13.13 udp

Loadable Function: udp = udp ()
Loadable Function: udp = udp (remoteipaddress, remoteport)
Loadable Function: udp = udp (remoteipaddress, remoteport, [propertyname, propertyvalue ...])

Open udp interface.

Inputs

remoteipaddress - the ip address of type String. If omitted defaults to ’127.0.0.1’.
remoteport - the port number to connect. If omitted defaults to 23.
localport - the local port number to bind. If omitted defaults to 0
propertyname, propertyvalue - property name/value pair

Outputs

The udp() shall return instance of octave_udp class as the result udp.

Properties

The udp object has the following public properties:

name

name assigned to the udp object

type

instrument type ’udp’ (readonly)

localport

local port number (readonly)

localhost

local host address (readonly)

remoteport

remote port number

remotehost

remote host

status

status of the object ’open’ or ’closed’ (readonly)

timeout

timeout value in seconds used for waiting for data

bytesavailable

number of bytes currently available to read (readonly)

3.13.14 udp_close

Loadable Function: udp_close (udp)

Close the interface and release a file descriptor.

Inputs

udp - instance of octave_udp class.

Inputs

None

3.13.15 udp_demo

Function File: result = udp_demo ()

Run test SNTP demonstration for udp class

See also: udp.

3.13.16 udp_read

Loadable Function: [data, count] = udp_read (udp, n, timeout)

Read from udp interface.

Inputs

udp - instance of octave_udp class.
n - number of bytes to attempt to read of type Integer
timeout - timeout in ms if different from default of type Integer

Outputs

The udp_read() shall return number of bytes successfully read in count as Integer and the bytes themselves in data as uint8 array.

3.13.17 udp_timeout

Loadable Function: udp_timeout (udp, timeout)
Loadable Function: t = udp_timeout (udp)

Set new or get existing udp interface timeout parameter used for udp_read() requests. The timeout value is specified in milliseconds.

Inputs

udp - instance of octave_udp class.
timeout - udp_read() timeout value in milliseconds. Value of -1 means a blocking call.

Outputs

If timeout parameter is omitted, the udp_timeout() shall return current timeout value as the result t.

3.13.18 udp_write

Loadable Function: n = udp_write (udp, data)

Write data to a udp interface.

Inputs

udp - instance of octave_udp class.
data - data to be written to the udp interface. Can be either of String or uint8 type.

Outputs

Upon successful completion, udp_write() shall return the number of bytes written as the result n.


3.14 UDP Port

3.14.1 @octave_udpport/configureMulticast

: data = configureMulticast((dev, address)
: data = configureMulticast((dev, "off")

Configure udpport device to receive multicast data

Inputs

dev - open udpport device

If address is ’off’ disable udp multicast. Otherwise it is the multicast address to use.

Outputs

None

See also: udpport.

3.14.2 @octave_udpport/configureTerminator

Function File: configureTerminator (udp, term)
Function File: configureTerminator (udp, readterm, writeterm)

Set terminator for ASCII string manipulation

Inputs

udp - udpport object
term - terminal value for both read and write
readterm = terminal value type for read data
writeterm = terminal value for written data

The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255.

Outputs

None

See also: udpport.

3.14.3 @octave_udpport/flush

: data = flush (dev)
: data = flush (dev, "input")
: data = flush (dev, "output")

Flush the udpport socket buffers

Inputs

dev - open udpport device

If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed

Outputs

None

See also: udpport.

3.14.4 @octave_udpport/fprintf

Function File: numbytes = fprintf (obj, template ...)

Writes formatted string template using optional parameters to UDP instrument

Inputs

obj is a UDPPort object.
template Format template string.

Outputs

numbytes is the number of bytes written to the device

3.14.5 @octave_udpport/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from UDP instrument

Inputs

obj is a UDP port object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data data values.
count number of values read.
errmsg read operation error message.

3.14.6 @octave_udpport/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to UDP instrument

Inputs

obj is a UDP port object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.14.7 @octave_udpport/get

Function File: struct = get (udpport)
Function File: field = get (udpport, property)

Get the properties of udpport object.

Inputs

udpport - instance of octave_udpport class.

property - name of property.

Outputs

When property was specified, return the value of that property.
otherwise return the values of all properties as a structure.

See also: @octave_udpport/set.

3.14.8 @octave_udpport/read

Function File: data = read (obj)
Function File: data = read (obj, size)
Function File: data = read (obj, size, datatype)

Reads data from UDP instrument

Inputs

obj is a UDP object.
size Number of values to read. (Default: BytesAvailable).
datatype datatype of data.

Outputs

data data read.

3.14.9 @octave_udpport/set

Function File: set (obj, property,value)
Function File: set (obj, property,value,…)

Set the properties of udpport object.

Inputs

obj - instance of octave_udpport class.
property - name of property.

If property is a cell so must be value, it sets the values of all matching properties.

The function also accepts property-value pairs.

Properties

’Name’

Set the name for the udpport socket.

’UserData’

Set the user data of the object.

’Timeout’

Set the timeout value in seconds. Value of -1 means a blocking call.

Outputs

None

See also: @octave_udpport/get.

3.14.10 @octave_udpport/write

Function File: numbytes = write (obj, data)
Function File: numbytes = write (obj, data, destinationAddress, destinationPort))
Function File: numbytes = write (obj, data, datatype)
Function File: numbytes = write (obj, data, datatype, destinationAddress, destinationPort)

Writes data to UDP instrument

Inputs

obj is a UDPPort object.
data data to write.
datatype datatype of data. If not specified defaults to uint8.
destinationAddress ipaddress to send to. If not specified, use the previously used remote address.
destinationPort port to send to. If not specified, use the remote port.

Outputs

returns number of bytes written.

3.14.11 @octave_udpport/writeline

: writeline (dev, data)
: writeline (dev, data, destaddr, destport)

Write data to a udpport including terminator value

Inputs

dev - connected device

data - ASCII data to write

destaddr - Destination address

destport - Destination port

Where the address and port is not specified, the previously used address and port is used.

Outputs

None

See also: flushoutput.

3.14.12 udpport

Loadable Function: udp = udpport ()
Loadable Function: udp = udpport (propertyname, propertyvalue ...)

Open udpport interface.

Inputs

propertyname, propertyvalue - property name/value pair

Known input properties:

Name

name assigned to the udp object

LocalPort

local port number

LocalHost

local host address

Timeout

timeout value in seconds used for waiting for data

EnablePortSharing

Boolean if the socket has port sharing enabled (readonly)

Outputs

The udpport() shall return instance of octave_udp class as the result udp.

Properties

The udp object has the following public properties:

Name

name assigned to the udp object

Type

instrument type ’udpport’ (readonly)

LocalPort

local port number (readonly)

LocalHost

local host address (readonly)

Status

status of the object ’open’ or ’closed’ (readonly)

Timeout

timeout value in seconds used for waiting for data

NumBytesAvailable

number of bytes currently available to read (readonly)

MulticastGroup

multicast group socket is subscribed to (readonly)

EnableMultcast

Boolean if the socket has any multicast group it is subscribed to (readonly)

EnablePortSharing

Boolean if the socket has port sharing enabled (readonly)

Terminator

Terminator value used for string data (currently not used)


3.15 USBTMC

3.15.1 @octave_usbtmc/fclose

Function File: res = fclose (obj)

Closes USBTMC connection obj

Inputs

obj is a usbtmc object.

3.15.2 @octave_usbtmc/fopen

Function File: res = fopen (obj) (dummy)

Opens USBTMC connection obj This currently is a dummy function to improve compatibility to MATLAB

3.15.3 @octave_usbtmc/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from usbtmc instrument

Inputs

obj is a usbtmc object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data The read data.
count values read.
errmsg read operation error message.

3.15.4 @octave_usbtmc/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to an usbtmc instrument

Inputs

obj is a usbtmc object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.15.5 usbtmc

Loadable Function: usbtmc = usbtmc (path)

Open usbtmc interface.

Inputs

path - the interface path of type String. If omitted defaults to ’/dev/usbtmc0’.

Outputs

The usbtmc() shall return instance of octave_usbtmc class as the result usbtmc.

3.15.6 usbtmc_close

Loadable Function: usbtmc_close (usbtmc)

Close the interface and release a file descriptor.

Inputs

usbtmc - instance of octave_usbtmc class.

Outputs

None

3.15.7 usbtmc_read

Loadable Function: [data, count] = usbtmc_read (usbtmc, n)

Read from usbtmc slave device.

Inputs

usbtmc - instance of octave_usbtmc class.
n - number of bytes to attempt to read of type Integer.

Outputs

count - the number of bytes successfully read as an Integer.
data - the read bytes as a uint8 array.

3.15.8 usbtmc_write

Loadable Function: n = usbtmc_write (usbtmc, data)

Write data to a usbtmc slave device.

Inputs

usbtmc - instance of octave_usbtmc class.
data - data, of type uint8, to be written to the slave device.

Outputs

Upon successful completion, usbtmc_write() shall return the number of bytes written as the result n.


3.16 VXI11

3.16.1 @octave_vxi11/fclose

Function File: res = fclose (obj)

Closes VXI11 connection obj

3.16.2 @octave_vxi11/fopen

Function File: res = fopen (obj) (dummy)

Opens VXI11 connection obj This currently is a dummy function to improve compatibility to MATLAB

3.16.3 @octave_vxi11/fread

Function File: data = fread (obj)
Function File: data = fread (obj, size)
Function File: data = fread (obj, size, precision)
Function File: [data,count] = fread (obj, ...)
Function File: [data,count,errmsg] = fread (obj, ...)

Reads data from vxi11 instrument

Inputs

obj is a vxi11 object.
size Number of values to read. (Default: 100).
precision precision of data.

Outputs

data The read data.
count values read.
errmsg read operation error message.

3.16.4 @octave_vxi11/fwrite

Function File: numbytes = fwrite (obj, data)
Function File: numbytes = fwrite (obj, data, precision)

Writes data to vxi11 instrument

Inputs

obj is a vxi11 object.
data data to write.
precision precision of data.

Outputs

returns number of bytes written.

3.16.5 vxi11

Loadable Function: vxi11 = vxi11 (ip,instr)

Open vxi11 interface.

ip - the ip address of type String. If omitted defaults to ’127.0.0.1’. instr - the instrument name of type String. If omitted defaults to ’inst0’.

The vxi11() shall return instance of octave_vxi11 class as the result vxi11.

3.16.6 vxi11_close

Loadable Function: vxi11_close (vxi11)

Close the interface and release a file descriptor.

vxi11 - instance of octave_vxi11 class.

3.16.7 vxi11_read

Loadable Function: [data, count] = vxi11_read (vxi11, n)

Read from vxi11 slave device.

vxi11 - instance of octave_vxi11 class.
n - number of bytes to attempt to read of type Integer.

The vxi11_read() shall return number of bytes successfully read in count as Integer and the bytes themselves in data as uint8 array.

3.16.8 vxi11_write

Loadable Function: n = vxi11_write (vxi11, data)

Write data to a vxi11 slave device.

vxi11 - instance of octave_vxi11 class.
data - data to be written to the slave device. Can be either of String or uint8 type.

Upon successful completion, vxi11_write() shall return the number of bytes written as the result n.


Appendix A GNU General Public License

Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. http://fsf.org/

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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:

    1. The work must carry prominent notices stating that you modified it, and giving a relevant date.
    2. 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”.
    3. 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.
    4. 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.

  7. 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:

    1. 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.
    2. 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.
    3. 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.
    4. 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.
    5. 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.

  8. 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:

    1. Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
    2. 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
    3. 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
    4. Limiting the use for publicity purposes of names of licensors or authors of the material; or
    5. Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
    6. 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.

  9. 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.

  10. 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.

  11. 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.

  12. 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.

  13. 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.

  14. 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.

  15. 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.

  16. 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.

  17. 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.

  18. 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.

one line to give the program's name and a brief idea of what it does.  
Copyright (C) year name of author

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 http://www.gnu.org/licenses/.

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:

program Copyright (C) year name of author 
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 http://www.gnu.org/licenses/.

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 http://www.gnu.org/philosophy/why-not-lgpl.html.


Index

Jump to:   B   C   F   G   I   L   M   O   P   R   S   T   U   V   W  
Index EntrySection

B
Basic Usage OverviewBasic Usage Overview

C
clrdeviceGPIB
Common FunctionsCommon Functions
configureMulticastUDP Port
configureTerminatorSerial Port
configureTerminatorTCP Client
configureTerminatorTCP Server
configureTerminatorUDP Port
copyrightCopying

F
fcloseGPIB
fcloseI2C
fcloseParallel
fcloseSerial (Deprecated)
fcloseSPI
fcloseTCP (Deprecated)
fcloseUDP (Deprecated)
fcloseUSBTMC
fcloseVXI11
flushSerial Port
flushTCP (Deprecated)
flushTCP Client
flushTCP Server
flushUDP (Deprecated)
flushUDP Port
flushinputCommon Functions
flushinputSerial (Deprecated)
flushinputTCP (Deprecated)
flushinputUDP (Deprecated)
flushoutputCommon Functions
flushoutputSerial (Deprecated)
flushoutputTCP (Deprecated)
flushoutputUDP (Deprecated)
fopenGPIB
fopenI2C
fopenParallel
fopenSerial (Deprecated)
fopenSPI
fopenTCP (Deprecated)
fopenUDP (Deprecated)
fopenUSBTMC
fopenVXI11
fprintfGPIB
fprintfSerial (Deprecated)
fprintfSerial Port
fprintfTCP (Deprecated)
fprintfUDP (Deprecated)
fprintfUDP Port
freadGPIB
freadI2C
freadParallel
freadSerial (Deprecated)
freadSerial Port
freadSPI
freadTCP (Deprecated)
freadUDP (Deprecated)
freadUDP Port
freadUSBTMC
freadVXI11
fscanfGPIB
Function ReferenceFunction Reference
fwriteGPIB
fwriteI2C
fwriteParallel
fwriteSerial (Deprecated)
fwriteSerial Port
fwriteSPI
fwriteTCP (Deprecated)
fwriteUDP (Deprecated)
fwriteUDP Port
fwriteUSBTMC
fwriteVXI11

G
GeneralGeneral
getI2C
getModbus
getSerial (Deprecated)
getSerial Port
getSPI
getTCP (Deprecated)
getTCP Client
getTCP Server
getUDP (Deprecated)
getUDP Port
getpinstatusSerial Port
GPIBGPIB
gpibGPIB
gpib_closeGPIB
gpib_readGPIB
gpib_timeoutGPIB
gpib_writeGPIB

I
I2CI2C
i2cI2C
i2c_addrI2C
i2c_closeI2C
i2c_readI2C
i2c_writeI2C
Installing and loadingInstalling and loading
instrhelpGeneral
instrhwinfoGeneral

L
LoadingInstalling and loading

M
maskWriteModbus
ModbusModbus
modbusModbus

O
Off-line installInstalling and loading
Online installInstalling and loading

P
ParallelParallel
parallelParallel
pp_closeParallel
pp_ctrlParallel
pp_dataParallel
pp_datadirParallel
pp_statParallel

R
readModbus
readSerial Port
readSPI
readTCP (Deprecated)
readTCP Client
readTCP Server
readUDP (Deprecated)
readUDP Port
readbinblockCommon Functions
readlineCommon Functions
RequirementsInstalling and loading
resolvehostGeneral

S
serialSerial (Deprecated)
Serial (Deprecated)Serial (Deprecated)
Serial PortSerial Port
serialbreakSerial (Deprecated)
serialbreakSerial Port
seriallistSerial (Deprecated)
serialportSerial Port
serialportlistSerial Port
setI2C
setModbus
setSerial (Deprecated)
setSerial Port
setSPI
setTCP (Deprecated)
setTCP Client
setTCP Server
setUDP (Deprecated)
setUDP Port
setDTRSerial Port
setRTSSerial Port
SPISPI
spiSPI
spi_closeSPI
spi_readSPI
spi_writeSPI
spi_writeAndReadSPI
spollGPIB
srl_baudrateSerial (Deprecated)
srl_bytesizeSerial (Deprecated)
srl_closeSerial (Deprecated)
srl_flushSerial (Deprecated)
srl_paritySerial (Deprecated)
srl_readSerial (Deprecated)
srl_stopbitsSerial (Deprecated)
srl_timeoutSerial (Deprecated)
srl_writeSerial (Deprecated)

T
tcpTCP (Deprecated)
TCP (Deprecated)TCP (Deprecated)
TCP ClientTCP Client
TCP ServerTCP Server
tcp_closeTCP (Deprecated)
tcp_readTCP (Deprecated)
tcp_timeoutTCP (Deprecated)
tcp_writeTCP (Deprecated)
tcpclientTCP Client
tcpipTCP (Deprecated)
tcpserverTCP Server
triggerGPIB

U
udpUDP (Deprecated)
UDP (Deprecated)UDP (Deprecated)
UDP PortUDP Port
udp_closeUDP (Deprecated)
udp_demoUDP (Deprecated)
udp_readUDP (Deprecated)
udp_timeoutUDP (Deprecated)
udp_writeUDP (Deprecated)
udpportUDP Port
USBTMCUSBTMC
usbtmcUSBTMC
usbtmc_closeUSBTMC
usbtmc_readUSBTMC
usbtmc_writeUSBTMC

V
VXI11VXI11
vxi11VXI11
vxi11_closeVXI11
vxi11_readVXI11
vxi11_writeVXI11

W
warrantyCopying
Windows installInstalling and loading
writeModbus
writeSerial Port
writeSPI
writeTCP (Deprecated)
writeTCP Client
writeTCP Server
writeUDP (Deprecated)
writeUDP Port
writeAndReadSPI
writebinblockCommon Functions
writelineCommon Functions
writelineUDP Port
writereadCommon Functions
writeReadModbus

instrument-control-0.9.4/doc/instrument-control.info0000644000000000000000000047420014743226261017666 0ustar00This is instrument-control.info, produced by makeinfo version 7.1 from instrument-control.texi. INFO-DIR-SECTION Math START-INFO-DIR-ENTRY * Octave Intrument Control: (instrument-control). Instrument Control Toolkit for Octave END-INFO-DIR-ENTRY  File: instrument-control.info, Node: Top, Next: Installing and loading, Up: (dir) Introduction ************ The Instrument Control toolkit is a set of low level I/O functions for serial, i2c, spi, modbus, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces * Menu: * Installing and loading:: Installing and loading the toolkit * Basic Usage Overview:: Basic Usage Overview * Function Reference:: Instrument Control functions * Copying:: Copying * Index:: Index  File: instrument-control.info, Node: Installing and loading, Next: Basic Usage Overview, Prev: Top, Up: Top 1 Installing and loading ************************ The Instrument Control toolkit must be installed and then loaded to be used. It can be installed in GNU Octave directly from octave-forge, or can be installed in an off-line mode via a downloaded tarball. The toolkit must be then be loaded once per each GNU Octave session in order to use its functionality. 1.1 Requirements ================ For GPIB support (Linux only), linux-gpib must be installed before installing instrument-control. GPIB support is also available for windows by following the information from the wiki: https://wiki.octave.org/Instrument_control_package#Requirements For VXI11 support, rpcgen, and libtirpc-devel must be installed before installing instrument-control. For MODBUS support, the libmodbus-devel must be installed before installing instrument-control. 1.2 Windows install =================== If using the GNU Octave installer in Windows, the toolkit will have already been installed, and does not need to be re-installed unless a newer version is available. Run the following command to verify if the toolkit is available: pkg list instrument-control 1.3 Online Direct install ========================= With an internet connection available, toolkit can be installed from octave-forge using the following command within GNU Octave: pkg install -forge instrument-control The latest released version of the toolkit will be downloaded, compiled and installed. 1.4 Off-line install ==================== With the toolkit package already downloaded, and in the current directory when running GNU Octave, the package can be installed using the following command within GNU Octave: pkg install instrument-control-0.9.4.tar.gz 1.5 Loading =========== Regardless of the method of installing the toolkit, in order to use its functions, the toolkit must be loaded using the pkg load command: pkg load instrument-control The toolkit must be loaded on each GNU Octave session.  File: instrument-control.info, Node: Basic Usage Overview, Next: Function Reference, Prev: Installing and loading, Up: Top 2 Basic Usage Overview ********************** * Menu: * Authors:: * Available Interface:: * Basic Serial:: * Basic TCP:: * Basic UDP::  File: instrument-control.info, Node: Authors, Next: Available Interface, Up: Basic Usage Overview 2.1 Authors =========== The Instrument control package provides low level I/O functions for serial, i2c, spi, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces. It was written mainly by the following developers: • Andrius Sutas • Stefan Mahr • John Donoghue  File: instrument-control.info, Node: Available Interface, Next: Basic Serial, Prev: Authors, Up: Basic Usage Overview 2.2 Available Interfaces ======================== The ability to use each interface is dependent on OS and what libraries were available during the toolkit install. To verify the available interfaces, run the following command in octave: instrhwinfo The function will return information on the supported interfaces that are available, similar to below: ToolboxVersion = 0.7.0 ToolboxName = octave instrument control package SupportedInterfaces = { [1,1] = gpib [1,2] = i2c [1,3] = parallel [1,4] = serial [1,5] = serialport [1,6] = tcp [1,7] = tcpclient [1,8] = udp [1,9] = udpport [1,10] = usbtmc [1,11] = vxi11 } Most interfaces have two types of functions: • somewhat compatible matlab functions such as fread, fwrite • interface specific lower level functions such as udp_read, udp_write  File: instrument-control.info, Node: Basic Serial, Next: Basic TCP, Prev: Available Interface, Up: Basic Usage Overview 2.3 Basic Serial ================ 2.3.1 Serial ------------ *NOTE*: The serial object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the serialport object. The serial port can be opened using the serial function: s = serial("/dev/ttyUSB1", 115200) The first parameter is the device name and is OS specific. The second parameter is the baudrate. A list of available serial ports can be retrieved using the function: seriallist After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. s = serial("/dev/ttyUSB1", 115200) br = get(s, "baudrate") # gets the baudrate br = s.baudrate # also gets the baudrate set(s, "baudrate", 9600) # set the baudrate s.baudrate = 9600 # also sets the baudrate The device can be written and read from using fread, fwrite and srl_read and slr_write functions. srl_write(s, "hello world") # write hello world fprintf(s, "hello again") val = srl_read(s, 10) # attempt to read val = fread(s, 10) The device can be closed using fclose or srl_close. fclose(s) 2.3.2 SerialPort ---------------- The recommended method of accessing serial ports is through the serialport object. The serial port can be opened using the serialport function: s = serialport("/dev/ttyUSB1", 115200) The first parameter is the device name and is OS specific. The second parameter is the baudrate. A list of available serial ports can be retrieved using the function: serialportlist After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. s = serialport("/dev/ttyUSB1", 115200) br = get(s, "BaudRate") # gets the baudrate br = s.BaudRate # also gets the baudrate set(s, "BaudRate", 9600) # set the baudrate s.BaudRate = 9600 # also sets the baudrate The device can be written and read from using read and write functions. write(s, "hello world") # write hello world val = read(s, 10) The device can be closed by clearing the serialport object. clear s  File: instrument-control.info, Node: Basic TCP, Next: Basic UDP, Prev: Basic Serial, Up: Basic Usage Overview 2.4 Basic TCP ============= 2.4.1 TCP --------- *NOTE*: The TCP object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the tcpclient object. A TCP connection can be opened using the tcp or tcpip function: s = tcp("127.0.0.1", 80) The first parameter is the IP address to connect to. The second parameter is the port number. And optional timeout value can be also be provided. A more matlab compatible function is available as tcpip to also open a tcp port: s = tcpip("gnu.org", 80) The first parameter is a hostname or ip address, the second the port number. Additional parameter/value pairs can be provided after the port. After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. s = tcp("127.0.0.1", 80) oldtimeout = get(s, "timeout") # get timeout set(s, "timeout", 10) # set the timeout s.timeout = oldtimeout # also sets the timeout The device can be written and read from using fread, fwrite and tcp_read and tcp_write functions. tcp_write(s, "HEAD / HTTP/1.1\r\n\r\n") val = tcp_read(s, 100, 500) # attempt to read 100 bytes The device can be closed using fclose or tcp_close. fclose(s) 2.4.2 TCP Client ---------------- The recommended method of creating a tcp connection is through the tcpclient object. A TCP connection can be opened using the tcpclient function: s = tcpclient("127.0.0.1", 80) The first parameter is the IP address or hostname to connect to. The second parameter is the port number. Additional parameter/value pairs can be provided after the port. After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. s = tcpclient("127.0.0.1", 80) oldtimeout = get(s, "Timeout") # get timeout set(s, "Timeout", 10) # set the timeout s.Timeout = oldtimeout # also sets the timeout The device can be written and read from using read and write functions. write(s, "HEAD / HTTP/1.1\r\n\r\n") val = read(s, 100) # attempt to read 100 bytes The device can be closed by clearing the object variable. clear s  File: instrument-control.info, Node: Basic UDP, Prev: Basic TCP, Up: Basic Usage Overview 2.5 Basic UDP ============= 2.5.1 UDP --------- *NOTE*: The UDP object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the udpport object. A UDP connection can be opened using the udp function: s = udp("127.0.0.1", 80) The first parameter is the IP address data will be to. The second parameter is the port number. If and ip address and port is not provides, it will default to "127.0.0.1" and 23. The address and port can be changed after creation using the remotehost and remoteport properties. s = udp() s.remotehost = "127.0.0.1"; s.remoteport = 100; After creating the interface object, other properties of the device can be set or retrieved using get or set functions or as property access. s = udp("127.0.0.1", 80) oldtimeout = get(s, "timeout") # get timeout set(s, "timeout", 10) # set the timeout s.timeout = oldtimeout # also sets the timeout The device can be written and read from using fread, fwrite and udp_read and udp_write functions. udp_write(s, "test") val = udp_read(s, 5) The device can be closed using fclose or udp_close. fclose(s) 2.5.2 UDP Port -------------- The recommended method of creating a udp socket is through the udpport object. A udpport object can be created using the udpport function: s = udpport() Additional parameter/value pairs can be provided during creation of the object. After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. s = udpport() oldtimeout = get(s, "Timeout") # get timeout set(s, "Timeout", 10) # set the timeout s.Timeout = oldtimeout # also sets the timeout The device can be written and read from using read and write functions. The destination address and port to send data to must be specified at least on the first time write is used. write(s, "test", "127.0.0.1", s.LocalPort) val = read(s) The device can be closed by clearing the object variable. clear s  File: instrument-control.info, Node: Function Reference, Next: Copying, Prev: Basic Usage Overview, Up: Top 3 Function Reference ******************** The functions currently available in the toolkit are described below. * Menu: * Common Functions:: * General:: * GPIB:: * I2C:: * Modbus:: * Parallel:: * Serial (Deprecated):: * Serial Port:: * SPI:: * TCP (Deprecated):: * TCP Client:: * TCP Server:: * UDP (Deprecated):: * UDP Port:: * USBTMC:: * VXI11::  File: instrument-control.info, Node: Common Functions, Next: General, Up: Function Reference 3.1 Common Functions ==================== 3.1.1 flushinput ---------------- -- : flushinput (DEV) Flush the instruments input buffers Inputs ...... DEV - connected device or array of devices Outputs ....... None See also: flushoutput. 3.1.2 flushoutput ----------------- -- : flushoutput (DEV) Flush the instruments output buffers Inputs ...... DEV - connected device or array of devices Outputs ....... None See also: flushinput. 3.1.3 readbinblock ------------------ -- : DATA = readbinblock (DEV) -- : DATA = readbinblock (DEV, DATATYPE) read a binblock of data from a instrument device Inputs ...... DEV - connected device DATATYPE - optional data type to read data as (default 'uint8') Outputs ....... DATA - data read See also: flushoutput. 3.1.4 readline -------------- -- : DATA = readline (DEV) read data from a instrument device excluding terminator value Inputs ...... DEV - connected device Outputs ....... DATA - ASCII data read See also: flushoutput. 3.1.5 writebinblock ------------------- -- : writebinblock (DEV, DATA, DATATYPE) Write a IEEE 488.2 binblock of data to a instrument device binblock formatted data is defined as: # where: ASCII number containing the length of part ASCII number containing the number of bytes of Binary data block Inputs ...... DEV - connected device DATA - binary data to send DATATYPE - datatype to send data as Outputs ....... None See also: flushoutput. 3.1.6 writeline --------------- -- : writeline (DEV, DATA) Write data to a instrument device including terminator value Inputs ...... DEV - connected device DATA - ASCII data to write Outputs ....... None See also: flushoutput. 3.1.7 writeread --------------- -- : DATA = writeread (DEV, COMMAND) write a ASCII command and read data from a instrument device. Inputs ...... DEV - connected device COMMAND - ASCII command Outputs ....... DATA - ASCII data read See also: readline, writeline.  File: instrument-control.info, Node: General, Next: GPIB, Prev: Common Functions, Up: Function Reference 3.2 General =========== 3.2.1 instrhelp --------------- -- : instrhelp () -- : instrhelp (FUNCNAME) -- : instrhelp (OBJ) Display instrument help Inputs ...... FUNCNAME - function to display help about. OBJ - object to display help about. If no input is provided, the function will display and overview of the package functionality. Outputs ....... None 3.2.2 instrhwinfo ----------------- -- Function File: [LIST] = instrhwinfo () -- Function File: LIST = instrhwinfo (INTERFACE) Query available hardware for instrument-control When run without any input parameters, instrhwinfo will provide the toolbox information and a list of supported interfaces. Inputs ...... INTERFACE is the instrument interface to query. When provided, instrhwinfo will provide information on the specified interface. Currently only interface "serialport","i2c" and "spi" and is supported, which will provide a list of available serial ports or i2c ports. Outputs ....... If an output variable is provided, the function will store the information to the variable, otherwise it will be displayed to the screen. Example ....... instrhwinfo scalar structure containing the fields: ToolboxVersion = 0.4.0 ToolboxName = octave instrument control package SupportedInterfaces = { [1,1] = i2c [1,2] = parallel [1,3] = serialport [1,4] = tcp [1,5] = udp [1,6] = usbtmc [1,7] = vxi11 } 3.2.3 resolvehost ----------------- -- Loadable Function: NAME = resolvehost (HOST) -- Loadable Function: [NAME, ADDRESS] = resolvehost (HOST) -- Loadable Function: OUT = resolvehost (HOST, RETURNTYPE) Resolve a network host name or address to network name and address Inputs ...... HOST - Host name or IP address string to resolve. NAME - Resolved IP host name. RETURNTYPE - 'name' to get host name, 'address' to get IP address. Outputs ....... NAME - Resolved IP host name. ADDRESS - Resolved IP host address. OUT - host name if RETURNTYPE is 'name', ipaddress if RETURNTYPE is 'address' Example ....... %% get resolved ip name and address of www.gnu.org [name, address] = resolvehost ('www.gnu.org'); %% get ip address of www.gnu.org ipaddress = resolvehost ('www.gnu.org', 'address'); See also: tcp, udp.  File: instrument-control.info, Node: GPIB, Next: I2C, Prev: General, Up: Function Reference 3.3 GPIB ======== 3.3.1 @octave_gpib/fclose ------------------------- -- Function File: RES = fclose (OBJ) Closes connection to GPIB device OBJ 3.3.2 @octave_gpib/fopen ------------------------ -- Function File: RES = fopen (OBJ) (dummy) Opens connection to GPIB device OBJ This currently is a dummy function to improve compatibility to MATLAB 3.3.3 @octave_gpib/fprintf -------------------------- -- Function File: fprintf (OBJ, CMD) -- Function File: fprintf (OBJ, FORMAT, CMD) -- Function File: fprintf (OBJ, CMD, MODE) -- Function File: fprintf (OBJ, FORMAT, CMD, MODE) Writes string CMD to GPIB instrument OBJ is a GPIB object CMD String FORMAT Format specifier MODE sync 3.3.4 @octave_gpib/fread ------------------------ -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from GPIB instrument OBJ is a GPIB object SIZE Number of values to read. (Default: 100) PRECISION precision of data COUNT values read ERRMSG read operation error message 3.3.5 @octave_gpib/fscanf ------------------------- -- Function File: RES = fscanf (OBJ) -- Function File: RES = fscanf (OBJ, FORMAT) -- Function File: RES = fscanf (OBJ, FORMAT, SIZE) -- Function File: [RES,COUNT] = fscanf (OBJ, ...) -- Function File: [RES,COUNT,ERRMSG] = fscanf (OBJ, ...) Reads data RES from GPIB instrument OBJ is a GPIB object FORMAT Format specifier SIZE number of values COUNT values read ERRMSG read operation error message 3.3.6 @octave_gpib/fwrite ------------------------- -- Function File: fwrite (OBJ, DATA) -- Function File: fwrite (OBJ, DATA, PRECISION) -- Function File: fwrite (OBJ, DATA, MODE) -- Function File: fwrite (OBJ, DATA, PRECISION, MODE) Writes DATA to GPIB instrument OBJ is a GPIB object DATA data to write PRECISION precision of data MODE sync 3.3.7 clrdevice --------------- -- Function File: clrdevice (OBJ) Send clear command to Clear GPIB instrument. OBJ is a GPIB object 3.3.8 gpib ---------- -- Loadable Function: GPIB = gpib ([GPIBID], [TIMEOUT]) Open gpib interface. GPIBID - the interface number. TIMEOUT - the interface timeout value. If omitted defaults to blocking call. The gpib() shall return instance of OCTAVE_GPIB class as the result GPIB. 3.3.9 gpib_close ---------------- -- Loadable Function: gpib_close (GPIB) Close the interface and release a file descriptor. GPIB - instance of OCTAVE_GPIB class. 3.3.10 gpib_read ---------------- -- Loadable Function: [DATA, COUNT, EOI] = gpib_read (GPIB, N) Read from gpib interface. GPIB - instance of OCTAVE_GPIB class. N - number of bytes to attempt to read of type Integer. The gpib_read() shall return number of bytes successfully read in COUNT as Integer and the bytes themselves in DATA as uint8 array. EOI indicates read operation complete 3.3.11 gpib_timeout ------------------- -- Loadable Function: gpib_timeout (GPIB, TIMEOUT) -- Loadable Function: T = gpib_timeout (GPIB) Set new or get existing gpib interface timeout parameter. The timeout value is valid from 0 to 17. GPIB - instance of OCTAVE_GPIB class. TIMEOUT - Value of 0 means never timeout, 11 means one second and 17 means 1000 seconds (see GPIB documentation (ibtmo) for further details) If TIMEOUT parameter is omitted, the gpib_timeout() shall return current timeout value as the result T. 3.3.12 gpib_write ----------------- -- Loadable Function: N = gpib_write (GPIB, DATA) Write data to a gpib interface. GPIB - instance of OCTAVE_GPIB class. DATA - data to be written to the gpib interface. Can be either of String or uint8 type. Upon successful completion, gpib_write() shall return the number of bytes written as the result N. 3.3.13 spoll ------------ -- Function File: OUT = spoll (OBJ) -- Function File: [OUT,STATUSBYTE] = spoll (OBJ) Serial polls GPIB instruments. OBJ is a GPIB object or a cell array of GPIB objects OUT GPIB objects ready for service STATUSBYTE status Byte 3.3.14 trigger -------------- -- Function File: trigger (OBJ) Triggers GPIB instrument. OBJ is a GPIB object  File: instrument-control.info, Node: I2C, Next: Modbus, Prev: GPIB, Up: Function Reference 3.4 I2C ======= 3.4.1 @octave_i2c/fclose ------------------------ -- Function File: RES = fclose (OBJ) Closes I2C connection OBJ 3.4.2 @octave_i2c/fopen ----------------------- -- Function File: RES = fopen (OBJ) (dummy) Opens I2C connection OBJ This currently is a dummy function to improve compatibility to MATLAB 3.4.3 @octave_i2c/fread ----------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from I2C instrument Inputs ...... OBJ is a I2C object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA data values. COUNT number of values read. ERRMSG read operation error message. 3.4.4 @octave_i2c/fwrite ------------------------ -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to I2C instrument Inputs ...... OBJ is a I2C object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.4.5 @octave_i2c/get --------------------- -- Function File: STRUCT = get (I2C) -- Function File: FIELD = get (I2C, PROPERTY) Get the properties of i2c object. Inputs ...... I2C - instance of OCTAVE_I2C class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_i2c/set. 3.4.6 @octave_i2c/set --------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of i2c object. Inputs ...... OBJ - instance of OCTAVE_I2C class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the i2c socket. 'REMOTEADDRESS' Set the remote address for the i2c socket. Outputs ....... None See also: @octave_i2c/get. 3.4.7 i2c --------- -- Loadable Function: I2C = i2c ([PORT_PATH], [ADDRESS]) Open i2c interface. Inputs ...... PORT_PATH - the interface device port/path of type String. If omitted defaults to '/dev/i2c-0'. ADDRESS - the slave device address. If omitted must be set using i2c_addr() call. Outputs ....... I2C - An instance of OCTAVE_I2C class. Properties .......... The i2c object has the following properties: name Name of the object remoteaddress the slave device address port The interface driver port (readonly) 3.4.8 i2c_addr -------------- -- Loadable Function: i2c_addr (I2C, ADDRESS) -- Loadable Function: ADDR = i2c_addr (I2C) Set new or get existing i2c slave device address. Inputs ...... I2C - instance of OCTAVE_I2C class. ADDRESS - i2c slave device address of type Integer. The address is passed in the 7 or 10 lower bits of the argument. Outputs ....... ADDR - If ADDRESS parameter is omitted, the i2c_addr() shall return current i2c slave device address. 3.4.9 i2c_close --------------- -- Loadable Function: i2c_close (I2C) Close the interface and release a file descriptor. Inputs ...... I2C - instance of OCTAVE_I2C class. Outputs ....... None 3.4.10 i2c_read --------------- -- Loadable Function: [DATA, COUNT] = i2c_read (I2C, N) Read from i2c slave device. Inputs ...... I2C - instance of OCTAVE_I2C class. N - number of bytes to attempt to read of type Integer. Outputs ....... The i2c_read() shall return number of bytes successfully read in COUNT as Integer and the bytes themselves in DATA as uint8 array. 3.4.11 i2c_write ---------------- -- Loadable Function: N = i2c_write (I2C, DATA) Write data to a i2c slave device. Inputs ...... I2C - instance of OCTAVE_I2C class. DATA - data, of type uint8, to be written to the slave device. Outputs ....... Upon successful completion, i2c_write() shall return the number of bytes written as the result N.  File: instrument-control.info, Node: Modbus, Next: Parallel, Prev: I2C, Up: Function Reference 3.5 Modbus ========== 3.5.1 @octave_modbus/get ------------------------ -- Function File: STRUCT = get (DEV) -- Function File: FIELD = get (DEV, PROPERTY) Get the properties of modbus object. Inputs ...... DEV - instance of OCTAVE_MODBUS class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_modbus/set. 3.5.2 @octave_modbus/maskWrite ------------------------------ -- : DATA = maskWrite (DEV, ADDRESS, ANDMASK, ORMASK) -- : DATA = maskWrite (DEV, ADDRESS, ANDMASK, ORMASK, SERVERID) Read holding register at ADDRESS from modbus device DEV apply masking and write the change data. writeregister value = (readregister value AND andMask) OR (orMask AND (NOT andMask)) Inputs ...... DEV - connected modbus device ADDRESS - address to read from. ANDMASK - AND mask to apply to the register ORMASK - OR mask to apply to the register SERVERID - address to send to (0-247). Default of 1 is used if not specified. Outputs ....... DATA - data read from the device See also: modbus. 3.5.3 @octave_modbus/read ------------------------- -- : DATA = read (DEV, TARGET, ADDRESS) -- : DATA = read (DEV, TARGET, ADDRESS, COUNT) -- : DATA = read (DEV, TARGET, ADDRESS, COUNT, SERVERID, PRECISION) Read data from modbus device DEV target TARGET starting at address ADDRESS. Inputs ...... DEV - connected modbus device TARGET - target type to read. One of 'coils', 'inputs', 'inputregs' or 'holdingregs' ADDRESS - address to start reading from. COUNT - number of elements to read. If not provided, count is 1. SERVERID - address to send to (0-247). Default of 1 is used if not specified. PRECISION - Optional precision for how to interpret the read data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. Outputs ....... DATA - data read from the device See also: modbus. 3.5.4 @octave_modbus/set ------------------------ -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of modbus object. Inputs ...... OBJ - instance of OCTAVE_MODBUS class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the stored string name of the object. 'TIMEOUT' Set the timeout value. 'NUMRETRIES' Set the numretries value. 'BYTEORDER' Set the byteorder value 'WORDORDER' Set the wordorder value 'USERDATA' Set the userdata value Outputs ....... None See also: @octave_modbus/get. 3.5.5 @octave_modbus/write -------------------------- -- : write (DEV, TARGET, ADDRESS, VALUES) -- : read (DEV, TARGET, ADDRESS, VALUES, SERVERID, PRECISION) Write data DATA to modbus device DEV target TARGET starting at address ADDRESS. Inputs ...... DEV - connected modbus device TARGET - target type to read. One of 'coils' or 'holdingregs' ADDRESS - address to start reading from. DATA - data to write. SERVERID - address to send to (0-247). Default of 1 is used if not specified. PRECISION - Optional precision for how to interpret the write data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. Outputs ....... None See also: modbus. 3.5.6 @octave_modbus/writeRead ------------------------------ -- : DATA = writeRead (DEV, WRITEADDRESS, VALUES, READADDRESS, READCOUNT) -- : DATA = writeRead (DEV, WRITEADDRESS, VALUES, READADDRESS, READCOUNT, SERVERID) -- : DATA = writeRead (DEV, WRITEADDRESS, VALUES, WRITEPRECISION, READADDRESS, READCOUNT, READPRECISION) Write data VALUES to the modbus device DEV holding registers starting at address WRITEADDRESS and then read READCOUNT register values starting at address READADDRESS. Inputs ...... DEV - connected modbus device WRITEADDRESS - address to start writing to. VALUES - data to write to the device. READADDRESS - address to start reading from. READCOUNT - number of elements to read. SERVERID - address to send to (0-247). Default of 1 is used if not specified. PRECISION - Optional precision for how to interpret the read data. Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. Outputs ....... DATA - data read from the device See also: modbus. 3.5.7 modbus ------------ -- Loadable Function: DEV = modbus ('tcpip', DEVICEADDRESS) -- Loadable Function: DEV = modbus ('tcpip', DEVICEADDRESS, REMOTEPORT) -- Loadable Function: DEV = modbus ('tcpip', DEVICEADDRESS, NAME, VALUE) -- Loadable Function: DEV = modbus ('serialrtu', SERIALPORT) -- Loadable Function: DEV = modbus ('serialrtu', SERIALPORT, NAME, VALUE) Open modbus interface using a specified transport of 'tcpip' or 'serialrtu'. Inputs ...... DEVICEADDRESS - the device ip address of type String. REMOTEPORT - the device remote port number. If not specified, a default of 502 will be used. NAME, VALUE - Optional name value pairs for setting properties of the object. SERIALPORT - the name of the serial port to connect to. It must be specified when transport is 'serialrtu'. Common Input Name, Value pairs .............................. Timeout timeout value used for waiting for data NumRetries number of retries after a timeout UserData Additional data to attach to the object Serial RTU Input Name, Value pairs .................................. BaudRate Baudrate for the serial port DataBits number of databits for serial port Parity Parity for serial port ('odd', 'even' or 'none') StopBits number of stopbits for serial port Outputs ....... The modbus() shall return instance of OCTAVE_MODBUS class as the result MODBUS. Properties .......... The modbus object has the following public properties: Name name assigned to the modbus object Type instrument type 'modbus' (readonly) Port Remote port number or serial port name (readonly) DeviceAddress Device address if transport was 'tcpip' (readonly) Status status of the object 'open' or 'closed' (readonly) Timeout timeout value used for waiting for data NumRetries number of retries after a timeout UserData Additional data to attach to the object  File: instrument-control.info, Node: Parallel, Next: Serial (Deprecated), Prev: Modbus, Up: Function Reference 3.6 Parallel ============ 3.6.1 @octave_parallel/fclose ----------------------------- -- Function File: RES = fclose (OBJ) Closes parallel connection OBJ 3.6.2 @octave_parallel/fopen ---------------------------- -- Function File: RES = fopen (OBJ) (dummy) Opens parallel interface OBJ This currently is a dummy function to improve compatibility to MATLAB 3.6.3 @octave_parallel/fread ---------------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from parallel instrument Inputs ...... OBJ is a parallel object. SIZE Number of values to read. (Default: 1). PRECISION precision of data. Outputs ....... DATA The read data. COUNT values read. ERRMSG read operation error message. 3.6.4 @octave_parallel/fwrite ----------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to parallel instrument Inputs ...... OBJ is a parallel object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.6.5 parallel -------------- -- Loadable Function: PARALLEL = parallel ([PATH], [DIRECTION]) Open Parallel interface. Inputs ...... PATH - the interface path of type String. If omitted defaults to '/dev/parport0'. DIRECTION - the direction of interface drivers of type Integer, see: PP_DATADIR for more info. If omitted defaults to 1 (Input). Outputs ....... The parallel() shall return instance of OCTAVE_PARALLEL class as the result PARALLEL. 3.6.6 pp_close -------------- -- Loadable Function: pp_close (PARALLEL) Close the interface and release a file descriptor. Inputs ...... PARALLEL - instance of OCTAVE_SERIAL class. Outputs ....... None 3.6.7 pp_ctrl ------------- -- Loadable Function: pp_ctrl (PARALLEL, CTRL) -- Loadable Function: C = pp_ctrl (PARALLEL) Sets or Read the Control lines. Inputs ...... PARALLEL - instance of OCTAVE_PARALLEL class. CTRL - control parameter to be set of type Byte. Outputs ....... If CTRL parameter is omitted, the pp_ctrl() shall return current Control lines state as the result C. 3.6.8 pp_data ------------- -- Loadable Function: pp_data (PARALLEL, DATA) -- Loadable Function: D = pp_data (PARALLEL) Sets or Read the Data lines. Inputs ...... PARALLEL - instance of OCTAVE_PARALLEL class. DATA - data parameter to be set of type Byte. Outputs ....... If DATA parameter is omitted, the pp_data() shall return current Data lines state as the result D. 3.6.9 pp_datadir ---------------- -- Loadable Function: pp_datadir (PARALLEL, DIRECTION) -- Loadable Function: DIR = pp_datadir (PARALLEL) Controls the Data line drivers. Normally the computer's parallel port will drive the data lines, but for byte-wide transfers from the peripheral to the host it is useful to turn off those drivers and let the peripheral drive the signals. (If the drivers on the computer's parallel port are left on when this happens, the port might be damaged.) Inputs ...... PARALLEL - instance of OCTAVE_PARALLEL class. DIRECTION - direction parameter of type Integer. Supported values: 0 - the drivers are turned on (Output/Forward direction); 1 - the drivers are turned off (Input/Reverse direction). Outputs ....... If DIRECTION parameter is omitted, the pp_datadir() shall return current Data direction as the result DIR. 3.6.10 pp_stat -------------- -- Loadable Function: STAT = pp_stat (PARALLEL) Reads the Status lines. Inputs ...... PARALLEL - instance of OCTAVE_PARALLEL class. Outputs ....... The pp_stat() shall return current Status lines state as the result STAT.  File: instrument-control.info, Node: Serial (Deprecated), Next: Serial Port, Prev: Parallel, Up: Function Reference 3.7 Serial (Deprecated) ======================= 3.7.1 @octave_serial/fclose --------------------------- -- Function File: RES = fclose (OBJ) Closes SERIAL connection OBJ 3.7.2 @octave_serial/flushinput ------------------------------- -- Loadable Function: flushinput (SERIAL) Flush the pending input, which will also make the BytesAvailable property be 0. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. Outputs ....... None See also: srl_flush, flushoutput. 3.7.3 @octave_serial/flushoutput -------------------------------- -- Loadable Function: flushoutput (SERIAL) Flush the output buffer. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. Outputs ....... None See also: srl_flush, flushinput. 3.7.4 @octave_serial/fopen -------------------------- -- Function File: RES = fopen (OBJ) (dummy) Opens SERIAL interface OBJ This currently is a dummy function to improve compatibility to MATLAB 3.7.5 @octave_serial/fprintf ---------------------------- -- Function File: NUMBYTES = fprintf (OBJ, TEMPLATE ...) Writes formatted string TEMPLATE using optional parameters to serial instrument Inputs ...... OBJ is a serial object. TEMPLATE Format template string Outputs ....... NUMBYTES - number of bytes written to the serial device. 3.7.6 @octave_serial/fread -------------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from serial instrument Inputs ...... OBJ is a serial object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA The read data. COUNT values read. ERRMSG read operation error message. 3.7.7 @octave_serial/fwrite --------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to serial instrument Inputs ...... OBJ is a serial object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.7.8 @octave_serial/get ------------------------ -- Function File: STRUCT = get (SERIAL) -- Function File: FIELD = get (SERIAL, PROPERTY) Get the properties of serial object. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_serial/set. 3.7.9 @octave_serial/serialbreak -------------------------------- -- Function File: serialbreak (SERIAL) -- Function File: serialbreak (SERIAL, TIME) Send a break to the serial port Inputs ...... SERIAL - serial object TIME - number of milliseconds to break for. If not specified a value of 10 will be used. Outputs ....... None See also: serial. 3.7.10 @octave_serial/set ------------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of serial object. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'BAUDRATE' Set the baudrate of serial port. Supported values by instrument-control: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your serial port may be different. 'BYTESIZE' Set the bytesize. Supported values: 5, 6, 7 and 8. 'NAME' Set the stored string name of the serial object. 'PARITY' Set the parity value. Supported values: Even/Odd/None. This Parameter must be of type string. It is case insensitive and can be abbreviated to the first letter only 'STOPBITS' Set the number of stopbits. Supported values: 1, 2. 'TIMEOUT' Set the timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds). 'REQUESTTOSEND' Set the requesttosend (RTS) line. 'DATATERMINALREADY' Set the dataterminalready (DTR) line. Outputs ....... None See also: @octave_serial/get. 3.7.11 @octave_serial/srl_baudrate ---------------------------------- -- Loadable Function: srl_baudrate (SERIAL, BAUDRATE)\ -- Loadable Function: BR = srl_baudrate (SERIAL) Set new or get existing serial interface baudrate parameter. Only standard values are supported. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. BAUDRATE - the baudrate value used. Supported values: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600 19200, 38400, 57600, 115200 and 230400. If BAUDRATE parameter is omitted, the srl_baudrate() shall return current baudrate value as the result BR. Outputs ....... BR - The currently set baudrate This function is obsolete. Use get and set method instead. 3.7.12 @octave_serial/srl_bytesize ---------------------------------- -- Loadable Function: srl_bytesize (SERIAL, BSIZE) -- Loadable Function: BS = srl_bytesize (SERIAL) Set new or get existing serial interface byte size parameter. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. BSIZE - byte size of type Integer. Supported values: 5/6/7/8. If BSIZE parameter is omitted, the srl_bytesize() shall return current byte size value or in case of unsupported setting -1, as the result BS. This function is obsolete. Use get and set method instead. Outputs ....... BS -the currently set byte size. 3.7.13 @octave_serial/srl_close ------------------------------- -- Loadable Function: srl_close (SERIAL) Close the interface and release a file descriptor. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. This function is obsolete. Use fclose() method instead. Outputs ....... None 3.7.14 @octave_serial/srl_flush ------------------------------- -- Loadable Function: srl_flush (SERIAL, [Q]) Flush the pending input/output. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. Q - queue selector of type Integer. Supported values: 0 flush untransmitted output 1 flush pending input 2 flush both pending input and untransmitted output. If Q parameter is omitted, the srl_flush() shall flush both, input and output buffers. Outputs ....... None 3.7.15 @octave_serial/srl_parity -------------------------------- -- Loadable Function: srl_parity (SERIAL, PARITY) -- Loadable Function: P = srl_parity (SERIAL) Set new or get existing serial interface parity parameter. Even/Odd/None values are supported. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. PARITY - parity value of type String. Supported values: Even/Odd/None (case insensitive, can be abbreviated to the first letter only) If PARITY parameter is omitted, the srl_parity() shall return current parity value as the result P. This function is obsolete. Use get and set method instead. Outputs ....... P - The currently set parity 3.7.16 @octave_serial/srl_stopbits ---------------------------------- -- Loadable Function: srl_stopbits (SERIAL, STOPB) -- Loadable Function: SB = srl_stopbits (SERIAL) Set new or get existing serial interface stop bits parameter. Only 1 or 2 stop bits are supported. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. STOPB - number of stop bits used. Supported values: 1, 2. Outputs ....... If STOPB parameter is omitted, the srl_stopbits() shall return current stop bits value as the result SB. This function is obsolete. Use get and set method instead. 3.7.17 @octave_serial/srl_timeout --------------------------------- -- Loadable Function: srl_timeout (SERIAL, TIMEOUT) -- Loadable Function: T = srl_timeout (SERIAL) Set new or get existing serial interface timeout parameter used for srl_read() requests. The timeout value is specified in tenths of a second. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. TIMEOUT - srl_read() timeout value in tenths of a second. A value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds). Outputs ....... If TIMEOUT parameter is omitted, the srl_timeout() shall return current timeout value as the result T. This function is obsolete. Use get and set method instead. 3.7.18 serial ------------- -- Loadable Function: SERIAL = serial ([PATH], [BAUDRATE], [TIMEOUT]) Open serial interface. Inputs ...... PATH - the interface path of type String. BAUDRATE - the baudrate of interface. If omitted defaults to 115200. TIMEOUT - the interface timeout value. If omitted defaults to blocking call. Outputs ....... The serial() shall return an instance of OCTAVE_SERIAL class as the result SERIAL. Properties .......... The serial object has the following public properties: name name assigned to the object type instrument type 'serial' (readonly) port OS specific port name (readonly) status status of the object 'open' or 'closed' (readonly) timeout timeout value used for waiting for data bytesavailable number of bytes currently available to read (readonly) stopbits number of stopbits to use requesttosend request to send state - 'on' or 'off' parity Parity setting 'none', 'even', 'odd' bytesize Number of bits to a byte (7 or 8) baudrate Baudrate setting dataterminalready state of dataterminal ready - 'on' or 'off' pinstatus current state of pins (readonly) 3.7.19 seriallist ----------------- -- Function File: LIST = seriallist () Returns a list of all serial ports detected in the system. Inputs ...... None Outputs ....... LIST is a string cell array of serial ports names detected in the system. See also: instrhwinfo("serial"). 3.7.20 srl_read --------------- -- Loadable Function: [DATA, COUNT] = srl_read (SERIAL, N) Read from serial interface. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. N - number of bytes to attempt to read of type Integer. Outputs ....... The srl_read() shall return number of bytes successfully read in COUNT as Integer and the bytes themselves in DATA as uint8 array. 3.7.21 srl_write ---------------- -- Loadable Function: N = srl_write (SERIAL, DATA) Write data to a serial interface. Inputs ...... SERIAL - instance of OCTAVE_SERIAL class. DATA - data to be written to the serial interface. Can be either of String or uint8 type. Outputs ....... Upon successful completion, srl_write() shall return the number of bytes written as the result N.  File: instrument-control.info, Node: Serial Port, Next: SPI, Prev: Serial (Deprecated), Up: Function Reference 3.8 Serial Port =============== 3.8.1 @octave_serialport/configureTerminator -------------------------------------------- -- Function File: configureTerminator (SERIAL, TERM) -- Function File: configureTerminator (SERIAL, READTERM, WRITETERM) Set terminator for ASCII string manipulation Inputs ...... SERIAL - serialport object TERM - terminal value for both read and write READTERM = terminal value type for read data WRITETERM = terminal value for written data The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. Outputs ....... None See also: serialport. 3.8.2 @octave_serialport/flush ------------------------------ -- : DATA = flush (DEV) -- : DATA = flush (DEV, "input") -- : DATA = flush (DEV, "output") Flush the serial port buffers Inputs ...... DEV - connected serialport device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed Outputs ....... None See also: serialport. 3.8.3 @octave_serialport/fprintf -------------------------------- -- Function File: NUMBYTES = fprintf (OBJ, TEMPLATE ...) Writes formatted string TEMPLATE using optional parameters to serialport instrument Inputs ...... OBJ is a serialport object. TEMPLATE Format template string Outputs ....... NUMBYTES - number of bytes written to the serial device. 3.8.4 @octave_serialport/fread ------------------------------ -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from serial port instrument Inputs ...... OBJ is a serialport object. SIZE Number of values to read. PRECISION precision of data. Outputs ....... DATA The read data. COUNT number of values read. ERRMSG read operation error message. 3.8.5 @octave_serialport/fwrite ------------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to serial port instrument Inputs ...... OBJ is a serial port object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.8.6 @octave_serialport/get ---------------------------- -- Function File: STRUCT = get (SERIAL) -- Function File: FIELD = get (SERIAL, PROPERTY) Get the properties of serialport object. Inputs ...... SERIAL - instance of OCTAVE_SERIALPORT class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_serial/set. 3.8.7 @octave_serialport/getpinstatus ------------------------------------- -- Function File: STATUS getpinstatus (SERIAL) Get status of serial pins Inputs ...... SERIAL - serial object Outputs ....... STATUS - a structure with the logic names of ClearToSend, DataSetReady, CarrierDetect, and RingIndicator See also: serialport. 3.8.8 @octave_serialport/read ----------------------------- -- : DATA = read (DEV, COUNT) -- : DATA = read (DEV, COUNT, PRECISION) Read a specified number of values from a serialport using optional precision for valuesize. Inputs ...... DEV - connected serialport device COUNT - number of elements to read PRECISION - Optional precision for the output data read data. Currently known precision values are uint8 (default), int8, uint16, int16, uint32, int32, uint64, uint64 Outputs ....... DATA - data read from the device See also: serialport. 3.8.9 @octave_serialport/serialbreak ------------------------------------ -- Function File: serialbreak (SERIAL) -- Function File: serialbreak (SERIAL, TIME) Send a break to the serial port Inputs ...... SERIAL - serialport object TIME - number of milliseconds to break for. If not specified a value of 10 will be used. Outputs ....... None See also: serial. 3.8.10 @octave_serialport/set ----------------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of serialport object. Inputs ...... SERIAL - instance of OCTAVE_SERIALPORT class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'BAUDRATE' Set the baudrate of serial port. Supported values by instrument-control: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your serial port may be different. 'BYTESIZE' Set the bytesize. Supported values: 5, 6, 7 and 8. 'NAME' Set the stored string name of the serial object. 'PARITY' Set the parity value. Supported values: Even/Odd/None. This Parameter must be of type string. It is case insensitive and can be abbreviated to the first letter only 'STOPBITS' Set the number of stopbits. Supported values: 1, 2. 'TIMEOUT' Set the timeout value in tenths of a second. Value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds). 'REQUESTTOSEND' Set the requesttosend (RTS) line. 'DATATERMINALREADY' Set the dataterminalready (DTR) line. Outputs ....... None See also: @octave_serialport/-get. 3.8.11 @octave_serialport/setDTR -------------------------------- -- : setDTR (DEV, TRUE_FALSE) Set the state of the DTR line Inputs ...... DEV - connected serial device. TRUE_FALSE - state to set the line. Outputs ....... None See also: serialport, getpinstatus, setRTS. 3.8.12 @octave_serialport/setRTS -------------------------------- -- : setRTS (DEV, TRUE_FALSE) Set the state of the RTS line Inputs ...... DEV - connected serial device. TRUE_FALSE - state to set the line. Outputs ....... None See also: serialport, getpinstatus. 3.8.13 @octave_serialport/write ------------------------------- -- Function File: NUMBYTES = write (OBJ, DATA) -- Function File: NUMBYTES = write (OBJ, DATA, PRECISION) Writes DATA to serialport instrument Inputs ...... OBJ is a serialport object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.8.14 serialport ----------------- -- Loadable Function: SERIAL = serialport ([PATH], [BAUDRATE]) -- Loadable Function: SERIAL = serialport ([PATH], [PROPNAME, PROPVALUE]) Open serial port interface. Inputs ...... PATH - the interface path of type String. BAUDRATE - the baudrate of interface. PROPNAME,PROPVALUE - property name/value pairs. Known input properties: BaudRate Numeric baudrate value Timeout Numeric timeout value in seconds or -1 to wait forever StopBits number of stopbits to use Parity Parity setting 'none', 'even', 'odd' DataBits Number of bits to a byte (5 to 8) FlowControl Number of bits to a byte 'none', 'hardware', 'software' Outputs ....... The serialport() shall return an instance of OCTAVE_SERIALPORT class as the result SERIAL. Properties .......... The serial object has the following public properties: Name name assigned to the object Type instrument type 'serial' (readonly) Port OS specific port name (readonly) Status status of the object 'open' or 'closed' (readonly) Timeout timeout value used for waiting for data NumBytesAvailable number of bytes currently available to read (readonly) NumBytesWritten number of bytes written (readonly) StopBits number of stopbits to use Parity Parity setting 'none', 'even', 'odd' DataBits Number of bits to a byte (5 to 8) BaudRate Baudrate setting FlowControl Number of bits to a byte 'none', 'hardware', 'software' PinStatus current state of pins (readonly) UserData user defined data 3.8.15 serialportlist --------------------- -- Function File: LIST = serialportlist () -- Function File: LIST = serialportlist ("all") -- Function File: LIST = serialportlist ("available") Returns a list of all serial ports detected in the system. Inputs ...... 'all' - show all serial ports (same as providing no arguments) 'available' - show only serial ports that are available for use Outputs ....... LIST is a string cell array of serial ports names detected in the system. See also: instrhwinfo("serialport").  File: instrument-control.info, Node: SPI, Next: TCP (Deprecated), Prev: Serial Port, Up: Function Reference 3.9 SPI ======= 3.9.1 @octave_spi/fclose ------------------------ -- Function File: RES = fclose (OBJ) Closes SPI connection OBJ 3.9.2 @octave_spi/fopen ----------------------- -- Function File: RES = fopen (OBJ) (dummy) Opens SPI connection OBJ This currently is a dummy function to improve compatibility to MATLAB 3.9.3 @octave_spi/fread ----------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from a SPI instrument Inputs ...... OBJ is a SPI object. SIZE Number of values to read. (Default: 10). PRECISION precision of data. Outputs ....... DATA data values. COUNT number of values read. ERRMSG read operation error message. 3.9.4 @octave_spi/fwrite ------------------------ -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to SPI instrument Inputs ...... OBJ is a SPI object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.9.5 @octave_spi/get --------------------- -- Function File: STRUCT = get (SPI) -- Function File: FIELD = get (SPI, PROPERTY) Get the properties of spi object. Inputs ...... SPI - instance of OCTAVE_SPI class. PROPERTY - name of property. Properties .......... 'NAME' Name for the spi socket. 'BITRATE' The bitrate for the spi object. 'CLOCKPOLARITY' The clock polarity for the spi object of 'idlehigh' or 'idlelow'. 'CLOCKPHASE' The clock phase for the spi object of 'firstedge' or 'secondedge'. 'PORT' The device port name. 'STATUS' The device status of 'open' or 'closed' Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_spi/set. 3.9.6 @octave_spi/read ---------------------- -- Function File: DATA = read (OBJ) -- Function File: DATA = read (OBJ, SIZE) Reads DATA from SPI instrument Inputs ...... OBJ is a SPI object. SIZE Number of values to read. (Default: 10). Outputs ....... DATA data values. 3.9.7 @octave_spi/set --------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of spi object. Inputs ...... OBJ - instance of OCTAVE_SPI class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the spi socket. 'BITRATE' Set the bitrate for the spi object. 'CLOCKPOLARITY' Set the clock polarity for the spi object of 'idlehigh' or 'idlelow'. 'CLOCKPHASE' Set the clock phase for the spi object of 'firstedge' or 'secondedge'. Outputs ....... None See also: @octave_spi/get. 3.9.8 @octave_spi/write ----------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) Writes DATA to SPI instrument Inputs ...... OBJ is a SPI object. DATA data to write. Outputs ....... returns number of bytes written. 3.9.9 @octave_spi/writeAndRead ------------------------------ -- Function File: DATA = writeAndRead (OBJ, WRDATA) Writes and reads DATA from SPI instrument Inputs ...... OBJ is a SPI object. WRDATA Data to write. Outputs ....... DATA data values read. 3.9.10 spi ---------- -- Loadable Function: SPI = spi ([PORT_PATH]) -- Loadable Function: SPI = spi ([PORT_PATH], [PROPNAME, PROPVALUE]) Open a spi interface. Inputs ...... PORT_PATH - the interface device port/path of type String. If omitted defaults to '/dev/spi-0'. PROPNAME,PROPVALUE - property name/value pairs. Known input properties: name Name of the object bitrate Numeric bitrate value clockpolarity Clock polarity: idlehigh or idlelow. clockphase Clock phase value: firstedge or secondedge Outputs ....... SPI - An instance of OCTAVE_SPI class. Properties .......... The spi object has the following properties: name Name of the object status Open or closed status of object (readonly). bitrate Numeric bitrate value clockpolarity Clock polarity: idlehigh or idlelow. clockphase Clock phase value: firstedge or secondedge port The interface driver port (readonly) 3.9.11 spi_close ---------------- -- Loadable Function: spi_close (SPI) Close the interface and release a file descriptor. Inputs ...... SPI - instance of OCTAVE_SPI class. Outputs ....... None 3.9.12 spi_read --------------- -- Loadable Function: [DATA, COUNT] = spi_read (SPI, N) Read from spi slave device. Inputs ...... SPI - instance of OCTAVE_SPI class. N - number of bytes to attempt to read of type Integer. Outputs ....... The spi_read() shall return number of bytes successfully read in COUNT as Integer and the bytes themselves in DATA as uint8 array. 3.9.13 spi_write ---------------- -- Loadable Function: N = spi_write (SPI, DATA) Write data to a spi slave device. Inputs ...... SPI - instance of OCTAVE_SPI class. DATA - data, of type uint8, to be written to the slave device. Outputs ....... Upon successful completion, spi_write() shall return the number of bytes written as the result N. 3.9.14 spi_writeAndRead ----------------------- -- Loadable Function: RDDATA = spi_writeAndRead (SPI, WRDATA) Write data to a spi slave device and then read same number of values. Inputs ...... SPI - instance of OCTAVE_SPI class. WRDATA - data, of type uint8, to be written to the slave device. Outputs ....... Upon successful completion, spi_writeAndRead() shall return the bytes read.  File: instrument-control.info, Node: TCP (Deprecated), Next: TCP Client, Prev: SPI, Up: Function Reference 3.10 TCP (Deprecated) ===================== 3.10.1 @octave_tcp/fclose ------------------------- -- Function File: RES = fclose (OBJ) Closes TCP connection OBJ 3.10.2 @octave_tcp/flush ------------------------ -- : DATA = flush (DEV) -- : DATA = flush (DEV, "input") -- : DATA = flush (DEV, "output") Flush the tcp socket buffers Inputs ...... DEV - connected tcp device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed Outputs ....... None See also: serialport. 3.10.3 @octave_tcp/flushinput ----------------------------- -- Loadable Function: flushinput (TCP) Flush the pending input, which will also make the BytesAvailable property be 0. Inputs ...... TCP - instance of OCTAVE_TCP class. Outputs ....... None. See also: flushoutput. 3.10.4 @octave_tcp/flushoutput ------------------------------ -- Loadable Function: flushoutput (TCP) Flush the output buffer. Inputs ...... TCP - instance of OCTAVE_TCP class. Outputs ....... None. See also: flushinput. 3.10.5 @octave_tcp/fopen ------------------------ -- Function File: RES = fopen (OBJ) (dummy) Opens TCP connection OBJ This currently is a dummy function to improve compatibility to MATLAB 3.10.6 @octave_tcp/fprintf -------------------------- -- Function File: NUMBYTES = fprintf (OBJ, TEMPLATE ...) Writes formatted string TEMPLATE using optional parameters to TCP instrument Inputs ...... OBJ is a TCP object. TEMPLATE Format template string Outputs ....... Number of characters written 3.10.7 @octave_tcp/fread ------------------------ -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from TCP instrument Inputs ...... OBJ is a TCP object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA data read. COUNT values read. ERRMSG read operation error message. 3.10.8 @octave_tcp/fwrite ------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to TCP instrument Inputs ...... OBJ is a TCP object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.10.9 @octave_tcp/get ---------------------- -- Function File: STRUCT = get (TCP) -- Function File: FIELD = get (TCP, PROPERTY) Get the properties of tcp object. Inputs ...... TCP - instance of OCTAVE_TCP class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_tcp/set. 3.10.10 @octave_tcp/read ------------------------ -- Function File: DATA = read (OBJ) -- Function File: DATA = read (OBJ, SIZE) -- Function File: DATA = read (OBJ, SIZE, DATATYPE) Reads DATA from TCP instrument Inputs ...... OBJ is a TCP object. SIZE Number of values to read. (Default: 100). DATATYPE datatype of data. Outputs ....... DATA data read. 3.10.11 @octave_tcp/set ----------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of tcp object. Inputs ...... If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the tcp socket. 'REMOTEHOST' Set the remote host name for the tcp socket. 'REMOTEPORT' Set the remote port for the tcp socket. 'TIMEOUT' Set the timeout value in seconds. Value of -1 means a blocking call. Outputs ....... None See also: @octave_tcp/get. 3.10.12 @octave_tcp/write ------------------------- -- Function File: NUMBYTES = write (OBJ, DATA) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE) Writes DATA to TCP instrument Inputs ...... OBJ is a TCP object. DATA data to write. DATATYPE datatype of data. If not specified, it defaults to "uint8". Outputs ....... returns number of bytes written. 3.10.13 tcp ----------- -- Loadable Function: TCP = tcp () -- Loadable Function: TCP = tcp (IPADDRESS) -- Loadable Function: TCP = tcp (IPADDRESS, PORT) -- Loadable Function: TCP = tcp (IPADDRESS, PORT, TIMEOUT) -- Loadable Function: TCP = tcp (IPADDRESS, [PROPERTYNAME, PROPERTYVALUE]) -- Loadable Function: TCP = tcp (IPADDRESS, PORT, [PROPERTYNAME, PROPERTYVALUE]) Open tcp interface. Inputs ...... IPADDRESS - the ip address of type String. If omitted defaults to '127.0.0.1'. PORT - the port number to connect. If omitted defaults to 23. TIMEOUT - the interface timeout value. If omitted defaults to blocking call. PROPNAME,PROPVALUE - property name/value pairs. Known input properties: name name value timeout Numeric timeout value or -1 to wait forever Outputs ....... The tcp() shall return instance of OCTAVE_TCP class as the result TCP. Properties .......... The tcp object has the following public properties: name name assigned to the tcp object type instrument type 'tcp' (readonly) localport local port number (readonly) remoteport remote port number remotehost remote host status status of the object 'open' or 'closed' (readonly) timeout timeout value in seconds used for waiting for data bytesavailable number of bytes currently available to read (readonly) 3.10.14 tcp_close ----------------- -- Loadable Function: tcp_close (TCP) Close the interface and release a file descriptor. Inputs ...... TCP - instance of OCTAVE_TCP class. Outputs ....... None 3.10.15 tcp_read ---------------- -- Loadable Function: [DATA, COUNT] = tcp_read (TCP, N, TIMEOUT) Read from tcp interface. Inputs ...... TCP - instance of OCTAVE_TCP class. N - number of bytes to attempt to read of type Integer TIMEOUT - timeout in ms if different from default of type Integer Outputs ....... COUNT - number of bytes successfully read as an Integer DATA - data bytes themselves as uint8 array. 3.10.16 tcp_timeout ------------------- -- Loadable Function: tcp_timeout (TCP, TIMEOUT) -- Loadable Function: T = tcp_timeout (TCP) Set new or get existing tcp interface timeout parameter used for tcp_read() requests. The timeout value is specified in milliseconds. Inputs ...... TCP - instance of OCTAVE_TCP class. TIMEOUT - tcp_read() timeout value in milliseconds. Value of -1 means a blocking call. Outputs ....... If TIMEOUT parameter is omitted, the tcp_timeout() shall return current timeout value as the result T. 3.10.17 tcp_write ----------------- -- Loadable Function: N = tcp_write (TCP, DATA) Write data to a tcp interface. Inputs ...... TCP - instance of OCTAVE_TCP class. DATA - data to be written to the tcp interface. Can be either of String or uint8 type. Outputs ....... Upon successful completion, tcp_write() shall return the number of bytes written as the result N. 3.10.18 tcpip ------------- -- Function File: TCP = tcpip (HOST, [PORT], [PROPERTYNAME, PROPERTYVALUE...]) Matlab compatible wrapper to the tcp interface. NOTE: tcpip has been deprecated. Use tcpclient instead Inputs ...... HOST - the host name or ip. PORT - the port number to connect. If omitted defaults to 80. PROPERTYNAME, PROPERTYVALUE - Optional property name, value pairs to set on the tcp object. Properties .......... Currently the only known properties are "timeout" and "name". Outputs ....... tcpip will return an instance of OCTAVE_TCP class as the result.  File: instrument-control.info, Node: TCP Client, Next: TCP Server, Prev: TCP (Deprecated), Up: Function Reference 3.11 TCP Client =============== 3.11.1 @octave_tcpclient/configureTerminator -------------------------------------------- -- Function File: configureTerminator (TCP, TERM) -- Function File: configureTerminator (TCP, READTERM, WRITETERM) Set terminator on a tcpclient object for ASCII string manipulation Inputs ...... TCP - tcpclient object TERM - terminal value for both read and write READTERM = terminal value type for read data WRITETERM = terminal value for written data The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. Outputs ....... None See also: tcpport. 3.11.2 @octave_tcpclient/flush ------------------------------ -- : DATA = flush (DEV) -- : DATA = flush (DEV, "input") -- : DATA = flush (DEV, "output") Flush the tcpclient socket buffers Inputs ...... DEV - connected tcpclient device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed Outputs ....... None See also: serialport. 3.11.3 @octave_tcpclient/get ---------------------------- -- Function File: STRUCT = get (TCPCLIENT) -- Function File: FIELD = get (TCPCLIENT, PROPERTY) Get the properties of tcpclient object. Inputs ...... TCPCLIENT - instance of OCTAVE_TCPCLIENT class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_tcpclient/set. 3.11.4 @octave_tcpclient/read ----------------------------- -- Function File: DATA = read (OBJ) -- Function File: DATA = read (OBJ, SIZE) -- Function File: DATA = read (OBJ, SIZE, DATATYPE) Reads DATA from TCP instrument Inputs ...... OBJ is a TCP object. SIZE Number of values to read. (Default: NumBytesAvailable). DATATYPE datatype of data. Outputs ....... DATA data read. 3.11.5 @octave_tcpclient/set ---------------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of tcpclient object. Inputs ...... If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the tcpclient socket. 'USERDATA' Set user data for the tcpclient socket. 'TIMEOUT' Set the timeout value in seconds. Value of -1 means a blocking call. Outputs ....... None See also: @octave_tcpclient/get. 3.11.6 @octave_tcpclient/write ------------------------------ -- Function File: NUMBYTES = write (OBJ, DATA) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE) Writes DATA to TCP instrument Inputs ...... OBJ is a TCPclient object. DATA data to write. DATATYPE datatype of data. If not specified, it defaults to "uint8". Outputs ....... returns number of bytes written. 3.11.7 tcpclient ---------------- -- Loadable Function: TCPCLIENT = tcpclient (IPADDRESS, PORT) -- Loadable Function: TCPCLIENT = tcpclient (IPADDRESS, PORT, [PROPERTYNAME, PROPERTYVALUE]) Open tcpclient interface. Inputs ...... IPADDRESS - the ip address of type String. PORT - the port number to connect. PROPNAME,PROPVALUE - property name/value pairs. Known input properties: Name name value Timeout Numeric timeout value or -1 to wait forever EnableTransferDelay Boolean to enable or disable the nagle algorithm for delay transfer. UserData User data value. Outputs ....... The tcpclient() shall return instance of OCTAVE_TCPCLIENT class as the result TCPCLIENT. Properties .......... The tcpclient object has the following public properties: Name name assigned to the tcpclient object Type instrument type 'tcpclient' (readonly) Port remote port number (Readonly) Address remote host address (Readonly) Status status of the object 'open' or 'closed' (readonly) Timeout timeout value in seconds used for waiting for data NumBytesAvailable number of bytes currently available to read (readonly) NumBytesWritten number of bytes currently available to read (readonly) ByteOrder Byte order for data (currently not used) Terminator Terminator value used for string data (currently not used) UserData User data EnableTransferDelay Bool for whether transfer delay is enabled. (Read only)  File: instrument-control.info, Node: TCP Server, Next: UDP (Deprecated), Prev: TCP Client, Up: Function Reference 3.12 TCP Server =============== 3.12.1 @octave_tcpserver/configureTerminator -------------------------------------------- -- Function File: configureTerminator (TCP, TERM) -- Function File: configureTerminator (TCP, READTERM, WRITETERM) Set terminator on a tcpserver object for ASCII string manipulation Inputs ...... TCP - tcpserver object TERM - terminal value for both read and write READTERM = terminal value type for read data WRITETERM = terminal value for written data The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. Outputs ....... None See also: tcpport. 3.12.2 @octave_tcpserver/flush ------------------------------ -- : DATA = flush (DEV) -- : DATA = flush (DEV, "input") -- : DATA = flush (DEV, "output") Flush the tcpserver socket buffers Inputs ...... DEV - connected tcpserver device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed Outputs ....... None See also: serialport. 3.12.3 @octave_tcpserver/get ---------------------------- -- Function File: STRUCT = get (TCPSERVER) -- Function File: FIELD = get (TCPSERVER, PROPERTY) Get the properties of tcpserver object. Inputs ...... TCPSERVER - instance of OCTAVE_TCPSERVER class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_tcpserver/set. 3.12.4 @octave_tcpserver/read ----------------------------- -- Function File: DATA = read (OBJ) -- Function File: DATA = read (OBJ, SIZE) -- Function File: DATA = read (OBJ, SIZE, DATATYPE) Reads DATA from TCP instrument Inputs ...... OBJ is a TCP Server object. SIZE Number of values to read. (Default: NumBytesAvailable). DATATYPE datatype of data. Outputs ....... DATA data read. 3.12.5 @octave_tcpserver/set ---------------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of tcpserver object. Inputs ...... If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the tcpserver socket. 'USERDATA' Set user data for the tcpserver socket. 'TIMEOUT' Set the timeout value in seconds. Value of -1 means a blocking call. Outputs ....... None See also: @octave_tcpserver/get. 3.12.6 @octave_tcpserver/write ------------------------------ -- Function File: NUMBYTES = write (OBJ, DATA) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE) Writes DATA to TCP instrument Inputs ...... OBJ is a TCPServer object. DATA data to write. DATATYPE datatype of data. If not specified, it defaults to "uint8". Outputs ....... returns number of bytes written. 3.12.7 tcpserver ---------------- -- Loadable Function: TCPSERVER = tcpserver (IPADDRESS, PORT) -- Loadable Function: TCPSERVER = tcpserver (PORT) -- Loadable Function: TCPSERVER = tcpserver (..., [PROPERTYNAME, PROPERTYVALUE]) Open tcpserver interface. Inputs ...... IPADDRESS - the ip address of type String. PORT - the port number to bind. PROPNAME,PROPVALUE - property name/value pairs. Known input properties: Name name value Timeout Numeric timeout value or -1 to wait forever UserData User data value. Outputs ....... The tcpserver() shall return instance of OCTAVE_TCPSERVER class as the result TCPSERVER. Properties .......... The tcpserver object has the following public properties: Connected boolean flag for when connected to a client (Readonly) ClientPort connected client port number (Readonly) ClientAddress connected client address (Readonly) Name name assigned to the tcpserver object Type instrument type 'tcpserver' (readonly) ServerPort server port number (Readonly) ServerAddress server address (Readonly) Status status of the object 'open' or 'closed' (readonly) Timeout timeout value in seconds used for waiting for data NumBytesAvailable number of bytes currently available to read (readonly) NumBytesWritten number of bytes currently available to read (readonly) ByteOrder Byte order for data (currently not used) Terminator Terminator value used for string data (currently not used) UserData User data  File: instrument-control.info, Node: UDP (Deprecated), Next: UDP Port, Prev: TCP Server, Up: Function Reference 3.13 UDP (Deprecated) ===================== 3.13.1 @octave_udp/fclose ------------------------- -- Function File: RES = fclose (OBJ) Closes UDP connection OBJ 3.13.2 @octave_udp/flush ------------------------ -- : DATA = flush (DEV) -- : DATA = flush (DEV, "input") -- : DATA = flush (DEV, "output") Flush the udp socket buffers Inputs ...... DEV - open udp device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed Outputs ....... None See also: udp. 3.13.3 @octave_udp/flushinput ----------------------------- -- Loadable Function: flushinput (UDP) Flush the pending input, which will also make the BytesAvailable property be 0. Inputs ...... UDP - instance of OCTAVE_UDP class. Outputs ....... None See also: flushoutput. 3.13.4 @octave_udp/flushoutput ------------------------------ -- Loadable Function: flushoutput (UDP) Flush the output buffer. Inputs ...... UDP - instance of OCTAVE_UDP class. Outputs ....... None See also: flushinput. 3.13.5 @octave_udp/fopen ------------------------ -- Function File: RES = fopen (OBJ) (dummy) Opens UDP connection OBJ This currently is a dummy function to improve compatibility to MATLAB 3.13.6 @octave_udp/fprintf -------------------------- -- Function File: NUMBYTES = fprintf (OBJ, TEMPLATE ...) Writes formatted string TEMPLATE using optional parameters to UDP instrument Inputs ...... OBJ is a UDP object. TEMPLATE Format template string. Outputs ....... NUMBYTES is the number of bytes written to the device 3.13.7 @octave_udp/fread ------------------------ -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from UDP instrument Inputs ...... OBJ is a UDP object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA data values. COUNT number of values read. ERRMSG read operation error message. 3.13.8 @octave_udp/fwrite ------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to UDP instrument Inputs ...... OBJ is a UDP object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.13.9 @octave_udp/get ---------------------- -- Function File: STRUCT = get (UDP) -- Function File: FIELD = get (UDP, PROPERTY) Get the properties of udp object. Inputs ...... UDP - instance of OCTAVE_UDP class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_udp/set. 3.13.10 @octave_udp/read ------------------------ -- Function File: DATA = read (OBJ) -- Function File: DATA = read (OBJ, SIZE) -- Function File: DATA = read (OBJ, SIZE, DATATYPE) Reads DATA from UDP instrument Inputs ...... OBJ is a UDP object. SIZE Number of values to read. (Default: BytesAvailable). DATATYPE datatype of data. Outputs ....... DATA data read. 3.13.11 @octave_udp/set ----------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of udp object. Inputs ...... OBJ - instance of OCTAVE_UDP class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the udp socket. 'REMOTEHOST' Set the remote host name for the udp socket. 'REMOTEPORT' Set the remote port for the udp socket. 'TIMEOUT' Set the timeout value in seconds. Value of -1 means a blocking call. Outputs ....... None See also: @octave_udp/get. 3.13.12 @octave_udp/write ------------------------- -- Function File: NUMBYTES = write (OBJ, DATA) -- Function File: NUMBYTES = write (OBJ, DATA, DESTINATIONADDRESS, DESTINATIONPORT)) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE, DESTINATIONADDRESS, DESTINATIONPORT) Writes DATA to UDP instrument Inputs ...... OBJ is a UDP object. DATA data to write. DATATYPE datatype of data. If not specified defaults to uint8. DESTINATIONADDRESS ipaddress to send to. If not specified, use the remote address. DESTINATIONPORT port to send to. If not specified, use the remote port. Outputs ....... returns number of bytes written. 3.13.13 udp ----------- -- Loadable Function: UDP = udp () -- Loadable Function: UDP = udp (REMOTEIPADDRESS, REMOTEPORT) -- Loadable Function: UDP = udp (REMOTEIPADDRESS, REMOTEPORT, [PROPERTYNAME, PROPERTYVALUE ...]) Open udp interface. Inputs ...... REMOTEIPADDRESS - the ip address of type String. If omitted defaults to '127.0.0.1'. REMOTEPORT - the port number to connect. If omitted defaults to 23. LOCALPORT - the local port number to bind. If omitted defaults to 0 PROPERTYNAME, PROPERTYVALUE - property name/value pair Outputs ....... The udp() shall return instance of OCTAVE_UDP class as the result UDP. Properties .......... The udp object has the following public properties: name name assigned to the udp object type instrument type 'udp' (readonly) localport local port number (readonly) localhost local host address (readonly) remoteport remote port number remotehost remote host status status of the object 'open' or 'closed' (readonly) timeout timeout value in seconds used for waiting for data bytesavailable number of bytes currently available to read (readonly) 3.13.14 udp_close ----------------- -- Loadable Function: udp_close (UDP) Close the interface and release a file descriptor. Inputs ...... UDP - instance of OCTAVE_UDP class. Inputs ...... None 3.13.15 udp_demo ---------------- -- Function File: RESULT = udp_demo () Run test SNTP demonstration for udp class See also: udp. 3.13.16 udp_read ---------------- -- Loadable Function: [DATA, COUNT] = udp_read (UDP, N, TIMEOUT) Read from udp interface. Inputs ...... UDP - instance of OCTAVE_UDP class. N - number of bytes to attempt to read of type Integer TIMEOUT - timeout in ms if different from default of type Integer Outputs ....... The udp_read() shall return number of bytes successfully read in COUNT as Integer and the bytes themselves in DATA as uint8 array. 3.13.17 udp_timeout ------------------- -- Loadable Function: udp_timeout (UDP, TIMEOUT) -- Loadable Function: T = udp_timeout (UDP) Set new or get existing udp interface timeout parameter used for udp_read() requests. The timeout value is specified in milliseconds. Inputs ...... UDP - instance of OCTAVE_UDP class. TIMEOUT - udp_read() timeout value in milliseconds. Value of -1 means a blocking call. Outputs ....... If TIMEOUT parameter is omitted, the udp_timeout() shall return current timeout value as the result T. 3.13.18 udp_write ----------------- -- Loadable Function: N = udp_write (UDP, DATA) Write data to a udp interface. Inputs ...... UDP - instance of OCTAVE_UDP class. DATA - data to be written to the udp interface. Can be either of String or uint8 type. Outputs ....... Upon successful completion, udp_write() shall return the number of bytes written as the result N.  File: instrument-control.info, Node: UDP Port, Next: USBTMC, Prev: UDP (Deprecated), Up: Function Reference 3.14 UDP Port ============= 3.14.1 @octave_udpport/configureMulticast ----------------------------------------- -- : DATA = configureMulticast((DEV, ADDRESS) -- : DATA = configureMulticast((DEV, "OFF") Configure udpport device to receive multicast data Inputs ...... DEV - open udpport device If ADDRESS is 'off' disable udp multicast. Otherwise it is the multicast address to use. Outputs ....... None See also: udpport. 3.14.2 @octave_udpport/configureTerminator ------------------------------------------ -- Function File: configureTerminator (UDP, TERM) -- Function File: configureTerminator (UDP, READTERM, WRITETERM) Set terminator for ASCII string manipulation Inputs ...... UDP - udpport object TERM - terminal value for both read and write READTERM = terminal value type for read data WRITETERM = terminal value for written data The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. Outputs ....... None See also: udpport. 3.14.3 @octave_udpport/flush ---------------------------- -- : DATA = flush (DEV) -- : DATA = flush (DEV, "input") -- : DATA = flush (DEV, "output") Flush the udpport socket buffers Inputs ...... DEV - open udpport device If an additional parameter is provided of "input" or "output", then only the input or output buffer will be flushed Outputs ....... None See also: udpport. 3.14.4 @octave_udpport/fprintf ------------------------------ -- Function File: NUMBYTES = fprintf (OBJ, TEMPLATE ...) Writes formatted string TEMPLATE using optional parameters to UDP instrument Inputs ...... OBJ is a UDPPort object. TEMPLATE Format template string. Outputs ....... NUMBYTES is the number of bytes written to the device 3.14.5 @octave_udpport/fread ---------------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from UDP instrument Inputs ...... OBJ is a UDP port object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA data values. COUNT number of values read. ERRMSG read operation error message. 3.14.6 @octave_udpport/fwrite ----------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to UDP instrument Inputs ...... OBJ is a UDP port object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.14.7 @octave_udpport/get -------------------------- -- Function File: STRUCT = get (UDPPORT) -- Function File: FIELD = get (UDPPORT, PROPERTY) Get the properties of udpport object. Inputs ...... UDPPORT - instance of OCTAVE_UDPPORT class. PROPERTY - name of property. Outputs ....... When PROPERTY was specified, return the value of that property. otherwise return the values of all properties as a structure. See also: @octave_udpport/set. 3.14.8 @octave_udpport/read --------------------------- -- Function File: DATA = read (OBJ) -- Function File: DATA = read (OBJ, SIZE) -- Function File: DATA = read (OBJ, SIZE, DATATYPE) Reads DATA from UDP instrument Inputs ...... OBJ is a UDP object. SIZE Number of values to read. (Default: BytesAvailable). DATATYPE datatype of data. Outputs ....... DATA data read. 3.14.9 @octave_udpport/set -------------------------- -- Function File: set (OBJ, PROPERTY,VALUE) -- Function File: set (OBJ, PROPERTY,VALUE,...) Set the properties of udpport object. Inputs ...... OBJ - instance of OCTAVE_UDPPORT class. PROPERTY - name of property. If PROPERTY is a cell so must be VALUE, it sets the values of all matching properties. The function also accepts property-value pairs. Properties .......... 'NAME' Set the name for the udpport socket. 'USERDATA' Set the user data of the object. 'TIMEOUT' Set the timeout value in seconds. Value of -1 means a blocking call. Outputs ....... None See also: @octave_udpport/get. 3.14.10 @octave_udpport/write ----------------------------- -- Function File: NUMBYTES = write (OBJ, DATA) -- Function File: NUMBYTES = write (OBJ, DATA, DESTINATIONADDRESS, DESTINATIONPORT)) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE) -- Function File: NUMBYTES = write (OBJ, DATA, DATATYPE, DESTINATIONADDRESS, DESTINATIONPORT) Writes DATA to UDP instrument Inputs ...... OBJ is a UDPPort object. DATA data to write. DATATYPE datatype of data. If not specified defaults to uint8. DESTINATIONADDRESS ipaddress to send to. If not specified, use the previously used remote address. DESTINATIONPORT port to send to. If not specified, use the remote port. Outputs ....... returns number of bytes written. 3.14.11 @octave_udpport/writeline --------------------------------- -- : writeline (DEV, DATA) -- : writeline (DEV, DATA, DESTADDR, DESTPORT) Write data to a udpport including terminator value Inputs ...... DEV - connected device DATA - ASCII data to write DESTADDR - Destination address DESTPORT - Destination port Where the address and port is not specified, the previously used address and port is used. Outputs ....... None See also: flushoutput. 3.14.12 udpport --------------- -- Loadable Function: UDP = udpport () -- Loadable Function: UDP = udpport (PROPERTYNAME, PROPERTYVALUE ...) Open udpport interface. Inputs ...... PROPERTYNAME, PROPERTYVALUE - property name/value pair Known input properties: Name name assigned to the udp object LocalPort local port number LocalHost local host address Timeout timeout value in seconds used for waiting for data EnablePortSharing Boolean if the socket has port sharing enabled (readonly) Outputs ....... The udpport() shall return instance of OCTAVE_UDP class as the result UDP. Properties .......... The udp object has the following public properties: Name name assigned to the udp object Type instrument type 'udpport' (readonly) LocalPort local port number (readonly) LocalHost local host address (readonly) Status status of the object 'open' or 'closed' (readonly) Timeout timeout value in seconds used for waiting for data NumBytesAvailable number of bytes currently available to read (readonly) MulticastGroup multicast group socket is subscribed to (readonly) EnableMultcast Boolean if the socket has any multicast group it is subscribed to (readonly) EnablePortSharing Boolean if the socket has port sharing enabled (readonly) Terminator Terminator value used for string data (currently not used)  File: instrument-control.info, Node: USBTMC, Next: VXI11, Prev: UDP Port, Up: Function Reference 3.15 USBTMC =========== 3.15.1 @octave_usbtmc/fclose ---------------------------- -- Function File: RES = fclose (OBJ) Closes USBTMC connection OBJ Inputs ...... OBJ is a usbtmc object. 3.15.2 @octave_usbtmc/fopen --------------------------- -- Function File: RES = fopen (OBJ) (dummy) Opens USBTMC connection OBJ This currently is a dummy function to improve compatibility to MATLAB 3.15.3 @octave_usbtmc/fread --------------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from usbtmc instrument Inputs ...... OBJ is a usbtmc object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA The read data. COUNT values read. ERRMSG read operation error message. 3.15.4 @octave_usbtmc/fwrite ---------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to an usbtmc instrument Inputs ...... OBJ is a usbtmc object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.15.5 usbtmc ------------- -- Loadable Function: USBTMC = usbtmc (PATH) Open usbtmc interface. Inputs ...... PATH - the interface path of type String. If omitted defaults to '/dev/usbtmc0'. Outputs ....... The usbtmc() shall return instance of OCTAVE_USBTMC class as the result USBTMC. 3.15.6 usbtmc_close ------------------- -- Loadable Function: usbtmc_close (USBTMC) Close the interface and release a file descriptor. Inputs ...... USBTMC - instance of OCTAVE_USBTMC class. Outputs ....... None 3.15.7 usbtmc_read ------------------ -- Loadable Function: [DATA, COUNT] = usbtmc_read (USBTMC, N) Read from usbtmc slave device. Inputs ...... USBTMC - instance of OCTAVE_USBTMC class. N - number of bytes to attempt to read of type Integer. Outputs ....... COUNT - the number of bytes successfully read as an Integer. DATA - the read bytes as a uint8 array. 3.15.8 usbtmc_write ------------------- -- Loadable Function: N = usbtmc_write (USBTMC, DATA) Write data to a usbtmc slave device. Inputs ...... USBTMC - instance of OCTAVE_USBTMC class. DATA - data, of type uint8, to be written to the slave device. Outputs ....... Upon successful completion, usbtmc_write() shall return the number of bytes written as the result N.  File: instrument-control.info, Node: VXI11, Prev: USBTMC, Up: Function Reference 3.16 VXI11 ========== 3.16.1 @octave_vxi11/fclose --------------------------- -- Function File: RES = fclose (OBJ) Closes VXI11 connection OBJ 3.16.2 @octave_vxi11/fopen -------------------------- -- Function File: RES = fopen (OBJ) (dummy) Opens VXI11 connection OBJ This currently is a dummy function to improve compatibility to MATLAB 3.16.3 @octave_vxi11/fread -------------------------- -- Function File: DATA = fread (OBJ) -- Function File: DATA = fread (OBJ, SIZE) -- Function File: DATA = fread (OBJ, SIZE, PRECISION) -- Function File: [DATA,COUNT] = fread (OBJ, ...) -- Function File: [DATA,COUNT,ERRMSG] = fread (OBJ, ...) Reads DATA from vxi11 instrument Inputs ...... OBJ is a vxi11 object. SIZE Number of values to read. (Default: 100). PRECISION precision of data. Outputs ....... DATA The read data. COUNT values read. ERRMSG read operation error message. 3.16.4 @octave_vxi11/fwrite --------------------------- -- Function File: NUMBYTES = fwrite (OBJ, DATA) -- Function File: NUMBYTES = fwrite (OBJ, DATA, PRECISION) Writes DATA to vxi11 instrument Inputs ...... OBJ is a vxi11 object. DATA data to write. PRECISION precision of data. Outputs ....... returns number of bytes written. 3.16.5 vxi11 ------------ -- Loadable Function: VXI11 = vxi11 (IP,INSTR) Open vxi11 interface. IP - the ip address of type String. If omitted defaults to '127.0.0.1'. INSTR - the instrument name of type String. If omitted defaults to 'inst0'. The vxi11() shall return instance of OCTAVE_VXI11 class as the result VXI11. 3.16.6 vxi11_close ------------------ -- Loadable Function: vxi11_close (VXI11) Close the interface and release a file descriptor. VXI11 - instance of OCTAVE_VXI11 class. 3.16.7 vxi11_read ----------------- -- Loadable Function: [DATA, COUNT] = vxi11_read (VXI11, N) Read from vxi11 slave device. VXI11 - instance of OCTAVE_VXI11 class. N - number of bytes to attempt to read of type Integer. The vxi11_read() shall return number of bytes successfully read in COUNT as Integer and the bytes themselves in DATA as uint8 array. 3.16.8 vxi11_write ------------------ -- Loadable Function: N = vxi11_write (VXI11, DATA) Write data to a vxi11 slave device. VXI11 - instance of OCTAVE_VXI11 class. DATA - data to be written to the slave device. Can be either of String or uint8 type. Upon successful completion, vxi11_write() shall return the number of bytes written as the result N.  File: instrument-control.info, Node: Copying, Next: Index, Prev: Function Reference, Up: Top Appendix A GNU General Public License ************************************* Version 3, 29 June 2007 Copyright © 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. ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. Copyright (C) YEAR NAME OF AUTHOR 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: PROGRAM Copyright (C) YEAR NAME OF AUTHOR 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 .  File: instrument-control.info, Node: Index, Prev: Copying, Up: Top Index ***** [index] * Menu: * Basic Usage Overview: Basic Usage Overview. (line 5) * clrdevice: GPIB. (line 81) * Common Functions: Common Functions. (line 5) * configureMulticast: UDP Port. (line 9) * configureTerminator: Serial Port. (line 9) * configureTerminator <1>: TCP Client. (line 9) * configureTerminator <2>: TCP Server. (line 9) * configureTerminator <3>: UDP Port. (line 31) * copyright: Copying. (line 6) * fclose: GPIB. (line 9) * fclose <1>: I2C. (line 9) * fclose <2>: Parallel. (line 9) * fclose <3>: Serial (Deprecated). (line 9) * fclose <4>: SPI. (line 9) * fclose <5>: TCP (Deprecated). (line 9) * fclose <6>: UDP (Deprecated). (line 9) * fclose <7>: USBTMC. (line 9) * fclose <8>: VXI11. (line 9) * flush: Serial Port. (line 34) * flush <1>: TCP (Deprecated). (line 15) * flush <2>: TCP Client. (line 34) * flush <3>: TCP Server. (line 34) * flush <4>: UDP (Deprecated). (line 15) * flush <5>: UDP Port. (line 56) * flushinput: Common Functions. (line 9) * flushinput <1>: Serial (Deprecated). (line 15) * flushinput <2>: TCP (Deprecated). (line 38) * flushinput <3>: UDP (Deprecated). (line 38) * flushoutput: Common Functions. (line 27) * flushoutput <1>: Serial (Deprecated). (line 35) * flushoutput <2>: TCP (Deprecated). (line 58) * flushoutput <3>: UDP (Deprecated). (line 58) * fopen: GPIB. (line 15) * fopen <1>: I2C. (line 15) * fopen <2>: Parallel. (line 15) * fopen <3>: Serial (Deprecated). (line 54) * fopen <4>: SPI. (line 15) * fopen <5>: TCP (Deprecated). (line 77) * fopen <6>: UDP (Deprecated). (line 77) * fopen <7>: USBTMC. (line 20) * fopen <8>: VXI11. (line 15) * fprintf: GPIB. (line 22) * fprintf <1>: Serial (Deprecated). (line 63) * fprintf <2>: Serial Port. (line 57) * fprintf <3>: TCP (Deprecated). (line 86) * fprintf <4>: UDP (Deprecated). (line 84) * fprintf <5>: UDP Port. (line 79) * fread: GPIB. (line 35) * fread <1>: I2C. (line 24) * fread <2>: Parallel. (line 24) * fread <3>: Serial (Deprecated). (line 81) * fread <4>: Serial Port. (line 75) * fread <5>: SPI. (line 24) * fread <6>: TCP (Deprecated). (line 104) * fread <7>: UDP (Deprecated). (line 102) * fread <8>: UDP Port. (line 97) * fread <9>: USBTMC. (line 27) * fread <10>: VXI11. (line 22) * fscanf: GPIB. (line 52) * Function Reference: Function Reference. (line 6) * fwrite: GPIB. (line 68) * fwrite <1>: I2C. (line 48) * fwrite <2>: Parallel. (line 48) * fwrite <3>: Serial (Deprecated). (line 105) * fwrite <4>: Serial Port. (line 99) * fwrite <5>: SPI. (line 48) * fwrite <6>: TCP (Deprecated). (line 128) * fwrite <7>: UDP (Deprecated). (line 126) * fwrite <8>: UDP Port. (line 121) * fwrite <9>: USBTMC. (line 51) * fwrite <10>: VXI11. (line 46) * General: General. (line 5) * get: I2C. (line 67) * get <1>: Modbus. (line 9) * get <2>: Serial (Deprecated). (line 124) * get <3>: Serial Port. (line 118) * get <4>: SPI. (line 67) * get <5>: TCP (Deprecated). (line 147) * get <6>: TCP Client. (line 57) * get <7>: TCP Server. (line 57) * get <8>: UDP (Deprecated). (line 145) * get <9>: UDP Port. (line 140) * getpinstatus: Serial Port. (line 139) * GPIB: GPIB. (line 5) * gpib: GPIB. (line 89) * gpib_close: GPIB. (line 103) * gpib_read: GPIB. (line 112) * gpib_timeout: GPIB. (line 126) * gpib_write: GPIB. (line 143) * I2C: I2C. (line 5) * i2c: I2C. (line 123) * i2c_addr: I2C. (line 154) * i2c_close: I2C. (line 175) * i2c_read: I2C. (line 192) * i2c_write: I2C. (line 211) * Installing and loading: Installing and loading. (line 6) * instrhelp: General. (line 9) * instrhwinfo: General. (line 31) * Loading: Installing and loading. (line 63) * maskWrite: Modbus. (line 30) * Modbus: Modbus. (line 5) * modbus: Modbus. (line 216) * Off-line install: Installing and loading. (line 54) * Online install: Installing and loading. (line 43) * Parallel: Parallel. (line 5) * parallel: Parallel. (line 67) * pp_close: Parallel. (line 88) * pp_ctrl: Parallel. (line 105) * pp_data: Parallel. (line 125) * pp_datadir: Parallel. (line 145) * pp_stat: Parallel. (line 173) * read: Modbus. (line 62) * read <1>: Serial Port. (line 158) * read <2>: SPI. (line 112) * read <3>: TCP (Deprecated). (line 168) * read <4>: TCP Client. (line 78) * read <5>: TCP Server. (line 78) * read <6>: UDP (Deprecated). (line 167) * read <7>: UDP Port. (line 162) * readbinblock: Common Functions. (line 45) * readline: Common Functions. (line 66) * Requirements: Installing and loading. (line 18) * resolvehost: General. (line 78) * serial: Serial (Deprecated). (line 400) * Serial (Deprecated): Serial (Deprecated). (line 5) * Serial Port: Serial Port. (line 5) * serialbreak: Serial (Deprecated). (line 145) * serialbreak <1>: Serial Port. (line 184) * seriallist: Serial (Deprecated). (line 453) * serialport: Serial Port. (line 322) * serialportlist: Serial Port. (line 391) * set: I2C. (line 89) * set <1>: Modbus. (line 97) * set <2>: Serial (Deprecated). (line 166) * set <3>: Serial Port. (line 205) * set <4>: SPI. (line 130) * set <5>: TCP (Deprecated). (line 188) * set <6>: TCP Client. (line 98) * set <7>: TCP Server. (line 98) * set <8>: UDP (Deprecated). (line 187) * set <9>: UDP Port. (line 182) * setDTR: Serial Port. (line 265) * setRTS: Serial Port. (line 284) * SPI: SPI. (line 5) * spi: SPI. (line 206) * spi_close: SPI. (line 253) * spi_read: SPI. (line 270) * spi_write: SPI. (line 289) * spi_writeAndRead: SPI. (line 308) * spoll: GPIB. (line 157) * srl_baudrate: Serial (Deprecated). (line 226) * srl_bytesize: Serial (Deprecated). (line 253) * srl_close: Serial (Deprecated). (line 278) * srl_flush: Serial (Deprecated). (line 297) * srl_parity: Serial (Deprecated). (line 324) * srl_read: Serial (Deprecated). (line 472) * srl_stopbits: Serial (Deprecated). (line 351) * srl_timeout: Serial (Deprecated). (line 374) * srl_write: Serial (Deprecated). (line 491) * tcp: TCP (Deprecated). (line 246) * TCP (Deprecated): TCP (Deprecated). (line 5) * TCP Client: TCP Client. (line 5) * TCP Server: TCP Server. (line 5) * tcp_close: TCP (Deprecated). (line 303) * tcp_read: TCP (Deprecated). (line 320) * tcp_timeout: TCP (Deprecated). (line 340) * tcp_write: TCP (Deprecated). (line 363) * tcpclient: TCP Client. (line 153) * tcpip: TCP (Deprecated). (line 383) * tcpserver: TCP Server. (line 153) * trigger: GPIB. (line 168) * udp: UDP (Deprecated). (line 255) * UDP (Deprecated): UDP (Deprecated). (line 5) * UDP Port: UDP Port. (line 5) * udp_close: UDP (Deprecated). (line 305) * udp_demo: UDP (Deprecated). (line 322) * udp_read: UDP (Deprecated). (line 330) * udp_timeout: UDP (Deprecated). (line 350) * udp_write: UDP (Deprecated). (line 373) * udpport: UDP Port. (line 275) * USBTMC: USBTMC. (line 5) * usbtmc: USBTMC. (line 70) * usbtmc_close: USBTMC. (line 89) * usbtmc_read: USBTMC. (line 106) * usbtmc_write: USBTMC. (line 125) * VXI11: VXI11. (line 5) * vxi11: VXI11. (line 65) * vxi11_close: VXI11. (line 79) * vxi11_read: VXI11. (line 88) * vxi11_write: VXI11. (line 101) * warranty: Copying. (line 6) * Windows install: Installing and loading. (line 32) * write: Modbus. (line 143) * write <1>: Serial Port. (line 303) * write <2>: SPI. (line 172) * write <3>: TCP (Deprecated). (line 226) * write <4>: TCP Client. (line 133) * write <5>: TCP Server. (line 133) * write <6>: UDP (Deprecated). (line 228) * write <7>: UDP Port. (line 220) * writeAndRead: SPI. (line 189) * writebinblock: Common Functions. (line 84) * writeline: Common Functions. (line 116) * writeline <1>: UDP Port. (line 247) * writeread: Common Functions. (line 136) * writeRead: Modbus. (line 176)  Tag Table: Node: Top257 Node: Installing and loading783 Node: Basic Usage Overview2892 Node: Authors3160 Node: Available Interface3621 Node: Basic Serial4733 Node: Basic TCP7089 Node: Basic UDP9474 Node: Function Reference11675 Node: Common Functions12142 Node: General14563 Node: GPIB17331 Node: I2C21914 Node: Modbus26669 Node: Parallel34025 Node: Serial (Deprecated)38382 Node: Serial Port50517 Node: SPI60235 Node: TCP (Deprecated)66971 Node: TCP Client75809 Node: TCP Server80906 Node: UDP (Deprecated)86059 Node: UDP Port94663 Node: USBTMC102399 Node: VXI11105349 Node: Copying108099 Node: Index145628  End Tag Table  Local Variables: coding: utf-8 End: instrument-control-0.9.4/doc/instrument-control.pdf0000644000000000000000000133431314743226261017505 0ustar00%PDF-1.5 %ĐÔÅØ 1 0 obj << /Length 587 /Filter /FlateDecode >> stream xÚmTM¢@½ó+z&ÎÁ±?tBL$ñ°ăd4›½*´.‰<øï·_•è̀f’W¯_wƠ«îrđăc;̣ê`GæUOÛV×&³£øç¾öƒ¤Ê®[vïÖæ6ïWÛ7ñÑTÙÖvb¯“uYt/N¼.³ó5·½êÿ¢¥=åS‚> stream xÚmTM¢@½ó+z&ÎÁ±?tBL0ñ°ăd4›½*´.‰<̀¿ß~U¢Îf’W¯_u½ªîvđăc;ZäƠÁ̀«Ÿ¶­®MfGñÏ}í I•]/¶́̃­Ím̃¯¶o⣩²­íÄ0^'ë²è^œx]fçkn{ƠÿEK{*ʇuÄpg6;µ̃$4»¢;»µgZ8, ’ü²M[Tå›P¯RJG¤eWxm½ñ­÷E™7·¢â ̉"/²îÑ7»¸¦‘¼ưj;{Y—ÇÊ‹"1₫t‹m×|‘£o¼irÛåI É‘c¶×º>[T̉›ÏEnn#×Ûû₫bÅø¹‘û̉î«¶BS¬ØEVå¶­÷™möåÉz‘”s…«¹gËüŸµ)gÏR©đ133wÄ xAÄbêí;¬̉aGL6K& 0+‡}&ö"?‘á°(̉¦̉a/ ¡ć,•!£½¥‰î-fö3¤Ù*IĂx {aªùđ”sIC%̉đhSô¢¨7å£Å}­HÏ=ŤIYƒ¹(îƒêjŧ ÿZóéàü4{ÖØSOØá5˜‡áZ ä®ekxvKº·Ǭü÷…Ü@2aÂ> stream xÚmSÁnâ0½ç+¼$z Ø¨"¤€ÄaKU¢Ơ^C<ĐHàDN8đ÷ờV{Hôüæç=üúØS`¾Jñ m}u%Œ̉ßE Y]^/`»w¦¶oâĂƠå:1L·ÙÖVƯ‹omy¾èUÿ­àTÙ ÖĂ₫v¹Êó‘DM^ug{¦…Ç‚° ÉpmUÛ7¡^¥”X[“ÖôÚă{=1î+kܽ¨8 …@iaª²»¯è_^|Ó˜¼¿µ\¶öXq,ÆŸ>ØvîF^‚ñÎp•=‰!9̣̀₫Ú4gÀêBË¥0pôù̃̃‹ ˆñs#P~k@hZ+vQÖÚ¦(ÁöA,åRÄÑf€5ÿĦœq8>K¥Â_¸—X NˆHæĐÔ3$¤Ç˜{<Ư0*¢5cƠ~ÿP÷ơʯÂùƯ5WÂ42^!0^#rq‰xƘœE„3xÎü ñ ªz“)c̉gl1B̀î̉°ơ•?ŸXqû!̣NA‡¨W»A*dư1ùÔ)iȧΰÅç“Đó â9ç’†NVf¤¡–kô¯VäaUJü†ố?%Í5Ø»bÿTW£=ј«±®–¾Œ¿É5ëñ2éfè&p2pj³V^ócH£Mc†VYxLS7˜E=›₫1âj· ¾gÈÈ endstream endobj 6 0 obj << /Length 340 /Filter /FlateDecode >> stream xÚ…‘KOĂ0„ïù>:‡,Y¯_{åUQ!(œ‡ª¤PÑÆ"MáïcÇM…E²́ÑØóíE?N ç <9±Üơ¨ö/"oîg|ÚMqÿ§­|°₫çÑ*¦WÎ2xNÆÓ¦8¹ôJ¨¬ñF4«„gkW{Ñ<‹Gy»%¡üHK[V䌼*Qv»¡ßoÛ.ÉC–ÏB>ơa“…¦d-CÜ£ ›·ơÁVƒ.ŸyqÑïG´lØ€#?0Mçl}+VÅ]F6F`|¦fLÈÊ!(²Âx è\æ¾¥̣̣3F’–›ö#ÚÄE$×Gø(‹aÁGß*¶ï–IØ”Đ'Ô1’­²)ÁkǬÙÍĂÑôË1O¦±È˜—I _ˆƯ£̉V¥ •FÚÇ©ÙR¾8¯]nî> stream xÚSËnÛ0¼û+t”HE½|í#r* ßÚ‰–ˆH¢AQ.ú÷]r—~¤Fø îp¹;;;fQ?ƠyT7nó&₫kT?¸ƒƯ₫̃?Ge‘æ5´LyNy­ĂŸªâºVÂÓŒC뫼_+1ơ¶-+€\L}V±]’gy¹M8çñ³fw*â/zÖHd•IR•iƯ4Qª”̉ß]‚4“Z¥ƯËŒÇjqß<y[Ù!`5&LâƠ?CT̀ÂZ¬Q/«¥‹“{,Í‹°jB¤ƠG%̀Ö*:¨%”=]1b|ܲØhW䤺3‡AâmKr'~¸ Æâ)+uÙWeÖVµuAºRcî%oTxûÆHÊ4r‘æä§ïđ.ä‹qÄ™i½§v‘¡ÚđEµR¯6|Ă !}8œƠ•$B“öƒt ¬S„2HÖ¸†ÔÉ+ï ¡÷̣¯s'›fGz{s§îm©4,ê  ¨kØ}^íÓ(jîÚ€ Ú!aÁÎmƒ°ø[;¡0ÊP KXG E0®ê²₫¸@›WŒq#Á@®Ơ†LỗLmܺÚô6ưA×ÀLD¼ä ¿S¸ºxOỊ̈cV0Lr±Ó4è¦1éÊ.€¢]¼)®₫œ.j,£8ï®Áñü!7¶pJbWj$`ÖẢ¾G1÷«èåĂ=1ÏvâA×"^Ä$ĂÿŒx8yInôÿÛÀk[{7_÷›™å endstream endobj 19 0 obj << /Length 1100 /Filter /FlateDecode >> stream xÚ•VKÛ6¾ï¯Đ­2ÑâK"{KÓn¢h‹Â=9h%Ú&j‹†Dí6ÿ¾C¤•¼̃l &9ü4ÏoH̉$‡MJ–”Åˤ>ßåQÚœüơñ8!9‘‚Ăü›°L2qÙBëO»»í½b „‹‚%»}4Ë ’K‘́äsú³í}go]»ù²ûu{/eBs¢sM>O2ª e ợ™Qè‚Ä)@#äăïßRF 0:‚₫¨}µa*} f“qY¦ŸZpe8›vĂÊÔY‘~¯á;wBĐn£xê6Ưé;Âl?ÔK“T1¢ËÙ±}g̀MÏ(Qy1¡z·÷ÁäSø«:C6™¤2½vƒ‚èÅ5¥àE+Ε÷¦Ă¹Û££ó—dL B©‚́rB%EÛCoº₫‡M&r½mÜ"4O»¡ƯĐô,˜Nkw æ¿n”˜D V0ƒ7£¬÷CóŒQỉ{¬‚¢ƒAµUÛ {¾tnY—hü8Ân¤¦(p"gSµ±‘6!0ŒË«P¨\¦w_ĂàZƒ̉˜8÷˜à\Ä€ƒ22BFÑïf —3¼3« ¬?*ű6¯l‹†j×66¿‡h—¯0œkA+ßæx®W8Ë.XN$åë²/ˆ¯"ñ•¼"¾Â¤‰… {œ¶ÎCu¹VéÑÍ ¹.!×qØÙB9Ăä2<œls`¤$p]ëôS4 °,°9­³‡ćMÓ ̣fÔÙ™UáÇа70ׄºÔ1Ó(‰å€ÑúQĐ,¢è3Ka{£Ó·ồ&ÓÛC‹¾åH MÛˆ  R© W°CÓnTơdO§[Q×g¤ư\ơƠyÍ ÷È_˜`ª`2Sù ’g¡Ö OaÍ2Œ^`Cr)÷.©ídñ™Ù7:²®BöO"« .önˆn l‘¿ÙºG7ÈüdZÓU'ÔúçD=°ô›­¡Ff2ƒ†Yíα6=.Ÿ,¤ä1N|ŸKêƠK¼¹êÅØ´¼àD ½æÄºA9¿nP`͹˜¢ ¢SïÆÙå‚©¯"û@bă|÷Ën¾ÔYQN.pỦø€’œä₫(‹Oµdù&˜¾Ï â›à:+k31¾÷“À¢ÑÁ÷8|₫0¶=|y‡^ªp—„ƯB\Ge!9§«(^ÇLè7|¾V}&c½„D´ ”ëñå2=x§]<$Û“«”T8̀Wj\…K;Œ·G™ L¼E8I8/_#ăÓ«ºưØ>ßÁîbA0ÇP"Í ù —“©zƒGÛ[ÿ¢ï?©)9ûß<¾Ï °&Ū&Wfđ́ô₫̣ăvë ôG3¨ä¨oÙP½ºÚ́]w0¤5~k§Nôe! ÛưQ2"$TđöUo1kBg ø­n¸Rú̀¬`ú?AOí{ endstream endobj 125 0 obj << /Length 3538 /Filter /FlateDecode >> stream xÚí_sÛ6Àßó)øh?˜%ˆ?$ïéổIçfÚKƯ¹‡^[N4'K‰d'_ÿH-@Μa:SËÊ »”÷‡]. )*øM]4--[Ú7÷/ª₫ƯĂûB½xûó ¢å®@đ I¾¼~ñĂkÎ R•]Ơ‘âú®àu]rBÇñ®o‹?/6—]ỵ̈â×ă@¼æ%g4Rë í¨në‚4eM8“ªåUÔ¢¬äoRëơeÇ.Vï¶ëË+Úđ‹ưúùj¿»¤äâa­~mÛ`Ѳ²"uoVÉáí²êàđ´Ï|Ç₫zĐgGYI™¨µƒ@o#¹¼ê*qñfw|Xm·›Ư{eăjw«^l÷«[ù®ecÍDÉ3 ÿ₫iÇ6RµØ¸W%ă´đo—WD4ê‡0~ûÆ7́ÿh íÚ¤…/¯Kö¡áóG²Ơhor8Ú.̉OíJÂxVÂë¯6½e×»™hJ̃Đ™BK BÊđ@UuñvưéqsXßœu;'i`z© ¤Ás=ZرGPliXY7Â4èÉụ̀3Cï9ip˜©3ÈǾ `ưù¶9€Uè‹sxFÛ’w Đ’đt~9+YâW i~kÅï¿7»Û½D÷Ë¥Ù!’wä4Jd-íXf‘ÜB2ó—aZ†ï»Ô0-̣§4h½¾o« @åÜ&´$Z6u€Z-¤©¥Ú_wz®°?Aø½y¯À{I.dH“'®+fŒHBµ´c§Ép]5ƒ6¦¡™ág«aSä3iœz½ƯVà4Êă´náŸH€S-¤9eÓÿT„^X ® /EC ¤É›%+iÇ0;MnUŒ-Ëịh˜CyWÂ^l5„£\}©üîĂ»&D°̉sEđ?§ë9p×]6pcFö«¥C,bY[6’XlI&6kˆH£‘¦±íEÄV`; Æ©*S9v“T»åP&k[6_»zƒkU»}¹:nnTµöăê½®6ÿúYV—ׇϛơ·zÛ•P^CÚ¼ÅÛ^رͩƯ’²«;ÓÂ\»M«Ưâ¿LRíÖïH¶íM3µÛ87YªvËE kÜÛ!eøP»ưññáĂ₫à–laơ¡ªxFöÆ6%íâÆ¶¶kLKr°È±-Û°&Å6?"¶9¸Ul‹ƒb¡¼•s^Ö]ˆm-¤ÙÖuƯ?_rq±Úlơz*‡̃¨%ơánu³>ºÅ!XÓµD¤Ó[R̉‰vq®_FNlcÆè¹Ï+s "×IƠëﶨQ~¼Tˆ3ˆªŒHƠBT]Ë̉Q(ư¾>lVnuH€mµ(_<Ö̉IV<¬„å)ä f®™@#KÚ‹…­&t”ûẶM)8O@`kÛV^C[vƯܺ̉ 6H H©ơ É…a 4¶d-í˜b‘̀;Ù4aX’cVn‘˜9^Đ^*l5 £(0₫ /[äYK<טçßd½?<¸ë7m)˜(ïú’vL²×o:(SÓ¤ ÅGcä]iđz°Ơô₫FgárơÅ̉ëª.Eh•„4»̀I¯¯_ưæF䮄H7"+iÇ;·†Kb­iP†-‡äIª‘ç¥QíeĂV : ƒÅrlÖBêÊH &R×C=‰3´M³륹v¬°Ók^R(aVdn³O¤Æ₫—Ä´ [Mï’lé8–cº¥ZỊ̂!­„F¢ëÑ}¤~µƯè n2,— VœÔxÛ•°m”Ư…ÜÊhlSF̣œz‘/¥ÑêsyKI€Ơ¯^hq‰A¡¸T¬µŒæ”;ơ?¹!’_*Úâ4¼·X­„mć|–æ$lMN§óƯ± ñÉß̉ öá`)é=ÏBăùËÅ[®L \-5<äĐSCZÜ@§8DKiÇ7‹nHcÚ‘Î|D#LCÚ‹†­&u ËQM!Ó6Dµ–©®OT÷ñy¾`-׌XÔx ÖJÚ±ÊΣ¡x+φU™ñïYĂ¹È­̉Èơº¿­&@n”/Ñ̀*Q¶œ̀w#º×w#¿–‡^<în6p̀E߉üv-7đƯ­ëƯÍÚiÓª¡»˜H•¯KK ;†Ù­ÈîÁ¹i]îD^°=ÿµ’Ú“ưe«éÿ€Í\{rœë˜íÉṃ]&íàˆØ>).dnJ„±Wûûû ˆd¯/[:`2Ñ»‹Q°o)óö.*iÇ6wc«́X6ŒË‘ëÙj˜‰UØg’b•ßĂm5slªXçÀ‹e™´óDÈ2©Îá̃ö¶̣Çă‡ÍîăădG„¼-DưM¤mÛÑRË œ`†9v‘w¥±ëÀV`7ÊƠ—jg¢Đ¿KH]-5¢[èî¦Ømy¿j‚Tx×X”´c‘»ÈRƠ¦A¬sZeÁ×åm5X£|{¹@ Ơ£N„©‘V½Cà°^Ư¾Ûôë¡ï¶ûË+øy#ù¯Cn'Ot¬@ê|äjiÇ:‹Üà¦q9¾G|E~”†¬×ïm5d£œz9d)Ü₫‰UB#°́l苳6ÚªÈ:í]mu`5-±×F;uë‹,É)ñÙi˜øähiüú °”èqùåà­ Z¤F|uƒĂ—Ăæapa%*¬HŸ7à*iÇ<;à6e#sel^æá;™‚æHE”†ª×åm5½Oµ³°F¹ób·²È«‚°j©V` ¶p˜0)Đàƒ‡‰k‰{îp%„iI¦ǽ;ø±‹¥¡ëÀV@7Êß ´u×Bk^¨OaÙm»2Y:±M†ˆ(¥kÜ)¤Ê†5¹ó½½Å̃•®ßûm5~pă\}© u5TmaÓ¿,;ilk½,ûóz·>Lln‡sÏ:HĐĐ̃c£”´c‰Ư7X•mc™’‰ÊÂaûaƯ^Fl5½gv³tGA±TF g#ĂSuPTÖR̃Ăº®<¤øđa½ư8•Q÷Qù4| §VQÙ²ÆÍª)̀h†5™đóI"æđEN–†¯[Mß(_.«æp2F%Büj©‘ßóÛ?Óc³»Û»Ë»°ßÈị̈®’vlrŸäÁà4SæŒÅ9­ïbJÖëơ¶°Qν°̣€oÎCÀj©Øq}÷¸ß~–À®?́S̃0¤#đäv,²qeư!q†E¦³À‡e†;}]O²ú|Àçm5êÄđj–×(ç^hç«́wUàXƠAHĂJ‡›ßß̃¼tï|A)å×{竤3́“¡í «Í™÷X´‘¦¡íÄVB;åB1é`3 …b-5Đ=î9ø»^î}XÉx¬‚̣peŸŒút ½r¡v₫ùWUÜÂ?₫¶±¦ø̉K̃æá˜ƠªØ¿¿ø×¤EĐÔÜ™ö¼ÿ¸y÷ĂƯÍvt·ÿP(7'ùÀN-í|)ÖNù‚ƒø #̣TóÄ̀ƒyB́^`l5!Ø£ür9Øa/­B‡:R#́ú0 W[¡¾vl‚}ÿ±·½q€‡ÊC]èJ½À+i狱‡j$µ¾˜¬Ÿ†9̉‘ ¤‘î¥ÅV"=Ê!—ªhË&dÂC R#è4 t9 mƯ°G₫ñ úÊî\̉9‡K t©^̉•´óÍØ¤Ă¦Xó6,ɤ?q̉± $‘îÇÅV =Î!‹é¤*´³iQgi¨Ă0ÀȨc{êS-rG~GI.2°_J;߉ 9¤ù²!g×Ï#ÇÆº—[b}öÑ}q~¹ëÂ<×`†uÍÖy뢱ëØÅúñfµ›ˆè0`Ç t•̃ˆ®¤/ÅÍƯÛ†›FdØŸêjö€ŸH=d ÜK­&Dy”C.–»ĂÑ:M„\K‹4Èa˜̣ Çö(ÈûvƠ)È9´¹ « @.¥/ņÎj!Ä4"'ƠO=mG.¹—[Ṃ(‡\.”Ëe­Đ ¸o4ă7ÛĂíúóæfblăăCgJضÅ=EDnăÀ¶dÇ?§Í‘G'ŸJ£Ơçñ–’«1uÓ·\XƠR#¬­†UC÷ĐXX5'§…Ủ%vó·|fpgZ’}ÿ\'ƒ9Œ‘Ë¥q́ÅÁV"9 €ÅRk07"YK$w$2R(ä ƒđ1Ö̉oJ¥T¦àdBÂɅí¾Ï–Đ…ºRAÚùÜ®Ty˜§¡>ăư}M sÓr¤´iÁË–­&4-D¹ơr^T]h[æ uj‚©TCj`^€Á‘œ‹̀ ؂ɠp¦4í?;^wZP̉ÎơÛÓÜyPK{Fê¬nƠ‘?¥Í^Âl5jv˜}jœw/6;@T́Xhw˜:Í $fn€S₫Â%¦¬ÿas¿̃OT[fÅÉÔĐá+JؾzûĐ_8XÖ?°öŒÚ³ƯfèG“¿ KIư(ß]êv¡QÏjñƒ¯…Nà×1àCù½¢d đ±₫É»> stream xÚµ›[·…ßçWđÑy‡÷K °-(†¤I„}PÖEˆ²#¬VưïóU›äYÄÉ™íîiö9uÈêbñ²Ù8“L¯Æă‹7̃›PœñÍÄÏ&eî“k3!‚ ÎtGÉjź’ñ.TĂÇׯ±ñ4€¡SÔèLđ`ECrà”“‰Ñ„Tº‰É„Ü¢‰æ̃±!Ï  Sœ=Ü₫'ơöë[à₫üáø?ÚÈ[Eđ¶>K,s·ëơæ=7oüđ»?ưù/ké8ƒ¹ûüáĂÍ/{“8¥Ỵ̈û9}Ox’÷†ü3÷ ñI₫Ôæ ö†íơNu;¨áQmêÛQß¿¨~ƠDE‰’%)JR”¤(IQ’¢$EI’%)JV”¬(YQ²¢dEÉ’%+JV”¬(EQ¢E)R¥(JQ”¢(EQ¢TE©R¥*JU”ª(UQª¢TE©̉¥)JS”¦(MQ¢4Eỉ¥)JW”®(]Qº¢tEé̉¥+JW”®(̉êÑcÇ8iGœseë8¶qx~àùçx#|û=nÀù„ˆ)Kó6đj‘ñÙ„kbD¯éb°ô† _Ä–}³^d§̀¡XG“,¤lÅvỤ=0KB—­ m‰ÆàTÓ`œ=Ă:Ê]cN6Ñ> stream xÚí[Ư¶Çßư)ôè}°"ñ*ö©è P M ä!ÉĂÚ{́dov´Ÿ¾C‘’†¤D̉1=keN’}Óơ |7cÚơd“߬”gth¹RûÀï?;öA´éĐ{̉Đ­ƠddétûØưùcÀ-O\4¨Ø·Ö:ˆÂă–‚b(醱çü.3›&[ £¬,=J‹ï&z#sG=‚^̃O ¥ZÉi¢Ÿ¬&̉Û̃²₫ûW¯Èđ̣íéú ~ü[ÿv˜*öË‚¿äí ØXŒ‚âÀÙ÷?vÍ üçדͯ£å‡†¶DRøÓmóí‹®F$¡7#yûƠ»··~“  Dƒ*ỉÉ:hWv±€á‚ĂNÙezØ 'Dñql|7 âó̉Ó%¾?yè¾EGRÈ[«yR†<c;ÎDÇ3"ÿñn äđóö’-—¤±×ÖA»„ØKÎÜ8öú2=la¢ û(:¾ƒ=ƯÄ>+=ëa/bS@ {k5cO˰‡b ~°ÇñŒØß®oBâ 4̉}xc4‰O†ç$}NÖc^ƒ+x埀̃ZÍÔ‹2ê)á:ŸzÆ₫a {̉viP £Üë A|đơ,£× ;äOÈĂ– ,)S€(H¾£lS²r¶ÚPŸtíÀ’`­f V€¿`Æ©V0Ñ ’c3vÖ:Ä›±ă^*7½g>âØâe^ÏQ(|7)³8¨×©w²jHm­f ‡hÔ‡sè¨Á«¾JQzVÎá=VÀơÍM¸`GÚÇô¥>1‘ÓcºW}OFäĐ’¹̃w.¿d)Ü̉”Veå̀wc4‚ojDV’WÓ®àÙÉ„FLV³F¨ĐWÉÔĐ'€Ơiz½¢}ƒ*” mÔ? =»â¸ß‡_²‡ ‘ÀiU$qĐ|7 ‘ÈḲZ|èÇ5r °VẸ̈Î,Ăk\¥ÂÔĐÀÚŸ~ÿ îQ}¢a¬ƒêûz-½êïx}ÉánIJ«2‰ˆræ»IIDV’×GN3‘̉kµhDŸ£pú*XÔ]¾́Uƒ* cÔß ¸¸̃w¬¿H[â€̉©L¢€ùnRâ•ܵöp=©âñ}“‘•†i>ñïffáæÍ§‡€T̃ƒGÑ âc¤Zë ÿí"ø–Ê g§̣™{Ø‚e^ÔQ2|7j± uƠ ti,µL`²¨nmŸ;ahŒ´0ăw̃„¡à€>,Ⲻb€ö­ÔZ°T56uh­ƒ–ñ¦)¬TÔ d'öi¬À™P|”ßM ø¬¼¬7Ä'0ÖU©Ư¸“ƠL<)"¨¶#uˆÇaâ?\?üôƯƠÀ^®. „‡-¨̉1ö­uĐFûºv‚»!í¸₫F¶Fw´Œá(¾›ĂYùUáĂ{j§̃d53L‹†R9Ta„^]ÇOaǾlPU£½öh4Œ.ƒÆEeîöE/ßÅ·¾ ñ(&¾›âY‰Xm\̃‘–©$áÖj&œ¥H"«„¯-郭ư‚,•Hn¬ƒ– Çå}/Ư@ögơ'̣êeBđQj|7x¹ |V^VëÓÙ ZÊR[q'«™x^B¼.…Ë*Ä;aâ×·êÀ³ïdƒ*c̃Zmăwë°Ú‰(7”ù‹›|Ç7½ï8"¾›̃y)XoXª̉«Ô¼ÉjÆ[á ¥0"ªà đ₫fmÜ.x«TƯè·¶ ÚÆĂÎä̉ÛsœPv¼ÿ¿Ûø~–±ÍßawØd7+»jÅ™ mÇ’èZ«]iĐư™ú‚÷MºÈAô;cÄaGaE¬Ï̃W=Ÿ—i[£$+#8ï&EpVÊ׺f°'ePñ™kkcñ¶ÄưCwµ×÷×··‡Ûµ}1z.z)=±-fœ¸öbñç­ơqwn0; »‡×Kö•acĂsb V›Pç€PoDMá&Úè6YM\W§‹Q²ÂfW';«,[gÖ1ÑR(Ơ4ú´l¬ƒ†ñŸ–Ơ¸̉Ơ d—“Ë9kßí2¢£`ønRLgå^=¨¡ >¤6»MV3ÔẻébB+@ăY ̃>•På°ªƠ6¶¶'[*/˜½ă½ °ÑƯ.; ‡ï&vVîU{††@a4ŸâÚZÍ\—8§‹óµ*păY¸^®f̀¼Ù^*EÙ7Û^»øHC/½{½¼7Û覗‘ÅĂw3¦é6ÉÎJÁj]6lO-Ø©}e“ƠŒvÙÙrºNÈùh;ñ,hòZÁ›7hXTÓ(ÛÆ:hmxÔçđi'½3½œîßí"¨ă`ønPçå^=¨ØƠESÁ&«êi¿ÇƯÖ+3ÙĂœ:kPñÑmYÆ:ˆÆß» {Đ„̀̉ó=ö'W¸Ñä÷Ư¤ÀÍJơZăl SÀjHrk­fn§×Ưww+]¯~s Ÿh$ä̀ư›æJÀ<·^j<7ÖAå}… ă©Ï÷¹gàaK(Pv• E6ß~S(²r½PÀ[*1¤¶MV³P 9B©^UQ ́ÿæ̃#c ³– U':–0ÖAíñ®ó²g¸hgU™BD)óƯ¤"+Ç«=mÀfiN“a­fP9¡÷a‹:ưk¸9†‡S ¬PWT£˜FXë üób½Âñ¿kÄ—¥B[ª€̣¨L¢hùnRª•ƠơÆ ưKPS›×&«ee=i.* p‘è‡*²€ư?œ®O«/+¥hPuR/+¥k¿̣²×ñ¾ơŒßV¢́*S(m¾£›ßŸ̀ËơZëriÇÇÏ­GæNFV'¦×ßî×·W ”ôåï₫t¸»?¼½>nào(„“9ŒÍàă l­¬…U}OTÏè̃sc4‹¿÷\gÑ;á¸^ø¾œE˜ÇYñƯ$0ÏKÈj#uŸêÔœ[«™ó²å¶ …;Rsåü‡®çŸ₫uüùîSx̉̀Jè?ªmŒvk4¿-UŸ%Ü`vs¾¿e(GqđƯ¤PÎʶz(Ă^j™Z`kfËÖ×!Ú®¯đ½GËñÇO§5[®Jm-צ~«øĂÎXÿĂØûëGùbº§e䯲ßs’â6'½ª ´á3h"ơ¦̀ÍÔ–-Ơ¥èŸçS‹Â™FÙÛ[]¨Ù•¶T41Đ·°yͳYÇ8vl/|5-ºÿe€Ç@ñœ¤ÏIÅzư2UÀXj›êd53^ö%f]Œ́k0ă™ ¿»?₫¬8½ WÈĂ·­ oPe£+äuĐ6₫îh›¹±́^ꔾ÷eˆGIñƯ¤ ÏÊÄz”½S+9ü¶V3åe_^ÖÅpQa›ÏDùúa¬đ­gëÙV3Úë Uü~\è%4Nûô¥¿.CPFy”ß¡|óóêyùXm°®¯O?c[«rY9Ăú ;Ưœx&È×÷¹ÁÀz±OŸ¸¬Â& \Ö^tBØû×KÆw¾Œí( ¾›ÛYyX¯ïÀ€¤¶±NV3ÜCÜP 5àÆñX¸×¾BàˆTÖ :ÆĐ6ÆA‹xlƒôêă&œv¶Ÿđ(Ê€Bă»IŸ•Ơ€ïa}É S[å&«xU¼^1Ú÷ưùÀ;ñXàÍ70pÿ)|c̃û^Pe£/ÍuĐ6₫{s6~GÁ‰eïtå‹„øÆ!ÇÀwcf[ç¥Y­ñ¸^K)I’`kµ¬Ré>ïPeK0£*L^;á̀¯ôØĐF(úT—m¬ƒ& ûl=áåݳö¤úlœeÀG©ñƯ¤€ÏJÏz}¶Đ‡¦¤¶®NV ñ}ñP̀P£ËÆáLÄ/ZÀĂÄDÇăà¼ë]×o®?ƯÜ_¯}$ Öåèë—ÆŒup/¤IÉƯö1ÂoäaK+Đ-Ó(o¾£›Ÿ+Î˯zZÁ`˜¤6§MV‹V"­€bWÄÇ“%ç{Ơû~£küŸÓááøßĂÚ: JDMœX£­ƒ;â?UÀÇ ˜Åù£,ÇÁ7¶L8¢đùnR‘•fơ„CO_ÉÔ¢œÉjZ$TŸ9TO–pœïý{ă(k5 ¼Am] `¬ƒ[á¡×ä®ûưaărưà»]&#Q}7)Éʽj/'Hÿ—Tkµ¨+R(Î̃© "8,9ßó¬"Ø·]¼©#Këféˆw36t°ëÈéºÛe:…ÑwctdóK°y¹Wo8ûL•LíÅ›¬!áEB̉Áæ—®Â^<',!9ßó,$Ø7Ez<Ï2á¶ ØRÙ‹5pt[±%°6 öi:1́O1—đ2Ưæ2‰‚è»I‰HV̉U¥?‘Úçg %¢xÛñ %89ßï¤çÓÇ»7ÇÓĂê+5·YÆ̃†• Øư>Fx”YUtW‹¤"›ç$!Y Vë¡e€ù™’ k´È„,‘ (EudG“#çûd{>?>®mX„û"›¥Y£"1Úú÷ Ôѹ÷`ïûå)º©EeÍsb4bó[ÖYùUm,ß¡å©Çc³HÄ`$Âå '‹ƒù\pô _cëEáÖN+ÄÎȳ l`»$Yµ±äw]$˜ÍIöjȳ+©=ˆÖhVaho§µSú>_™>¤_ûÁøçăÁ âp¬fGë«‹rªÔhÊ{N ª›«¥÷ÿ4ë¨ endstream endobj 139 0 obj << /Type /ObjStm /N 100 /First 913 /Length 2171 /Filter /FlateDecode >> stream xÚµ›]‹Ç†ïϯèËä¦OWuW€0Ø̣M ẨEá E>³kV+p₫½ß©©„°œ0^µvÔó¾ưô×T˜¨§’ˆ{"jHk"©‰›₫àwø™KÿHT‹>Á/Mÿà¢YơJÔEE8ÑèưB ¿̀É1ÑZxµqâÍ@…¹âߡεÁ¶ ¬ºfî‰eh摸/Í<Ỏ̀+ñb(Ă¥@f¡TIY8Um+v­K ƠR•e‘T»Jzª£jæ‘êÍ‘4ÖḮipÑ'#ª­7g­‚-=Dê…- äEi ¼J(îXEÛ³¦YĐk-4©êI“Ñh´zµE¨‘Ù†¾>Ó”¥¯¯4aáRºÚZs¡ƒh¥¯‚–áRÓ̉*aô³Å(‹–rµ¢OzZBúd¤Ơ«¾>°ôơ•Ö́ăÂè(èkU;Z¢R`ÍÚ …IŸ¡T¥¢›³öẨÔXk®ê˜§ô®o£Œ©ÏP娯‚¿iỵ̈…µÏUtf­6bí ÚjTÑ5Xú,̃`(‚ê`b‘¾¡Cl²¾¡ƒjéĐ~6}CGựêƠåú₫_¿Ü̉ơ뇇ÇçËơƯ—¿?o¿ÿù§‡^®ß<>ưx{J †mùárư₫öé9}j¹c0ÊÊKüdÁPë+£|Èơuzơ*]ߥë·ïÓơuúñÓW_]đŸ:¾N@ÉïÓơ/ư:Úe´ÁĂ—Ÿ₫áÈöæñáySzƒ±5÷́oĐç†ư•¿iOà=̃¿¾}züôî†Â¦ëÛ×ỏơưí×çä̉;óÛÿ¸]®‚Ííáùó6áu¥üüøåéÓMñ₫è»Û?}üæñ×½*ĐÉ2c̀̀F(5ˆß~|‚pϽUægx딦%̉mO×r±”,å=mö¼Ùóv<¯–6KÅ̉n©ù4óiæ#¦'¦'¦'¦'¦'¦'¦'¦'¦'¦×M¯›^7½nzƯôºéuÓë¦×M¯›̃0½azĂô†é Ó¦7Lo˜̃0½azÓô¦éMÓ›¦7Mõ4½izÓô¦é-Ó[¦·Lo™̃2½ezËô–é-Ó[»NH{J–²¥Ởf©XÚ-–NKMLLLLLLLÏú%[¿dë—lư’­_²ơKmöÔôØôØôl²@a¶´^5½jzƠôªéUÓ«¦Ww½ÿ°ÿË$…94OưÖpÍkû°ư÷Zsm¿c–úÿçÅẶ˜-gÏ:·cÎÏ }QSÖ1ŒOn®2c)ÍÓ)=ÆDp‘‹~W¹eºF¨i å<<3ĐÓ9gÍsr̀åP3â„—=ëIœæùïÏyœ§s’kl¹‹rÊRc9ÍÓ9=SF 6¹gÆ7Ñ_n3˜Ó<3ĐÓ9[Ë·8óVɵr,§y:g §sVB¨ËLÎE—A3b—=ÛIœæéœÎ‰9}êb´­ÜkbI˜é̃§́,NótÎ@OçÄœ̃×¶̃Ç'i€ÇSNâ4Oç ô<8sºè✠1Y/èC\C9Oç ôtǸéUwJ†lăSæ̀kp,§yœ‘Ή9u_k̀<Ă x¥s§szZx+˜̉‹ńeƯ=”paÜ™úúI˜æé˜̃œ[(Xa¹”–´"Eyc9ÍÓ9=aPéºñ:Ñu†îXb¨s§sz:§.‘°äÆr¡5¬a³Äb¥cz˜m­<°ăƒƠ~Æ×e@zïK6Îá<<3ĐÓ91á+]AÂês  ˆ°9˜Ó<ÎHOç57Ưcî’qb1[ÆÆËó$JstÊ@O§́5=3Â$¤û{ ëBœ}Är§szÚ·³µmg]#xưt6¬ q¬ô²ă:‰r·tÈ@KòÚ²ˆ!0Á&̀°(\L±˜æéœÎ©‹#l¾+§ Øl[¤‹i–gé”X RʶO´4ñayÑ’ËI”fé”q–eƠ…‚ƒ†ùG‹`˜¬PJ³tÈ@K§œØ"ÑĂÏA¹--ºÅ6æáypFz:'>#Së±̉¥XÅ’L:År§sz:§(_Ó#¼-Ø«Ưñ¤“8ÍÓ9=Ûk¢‡ÊÛ‹XîVá|gYt¦Y:fœ¥ṢBM²€æ‰CE\jɸˆ‹iè霄=½÷£³‘+kz9Àä“Oç ô´`¯boM^X%î*a¾Q‹¥4K§ ôé$÷đ<8#=;jz |)7a±œæéœÎ‰Mµ©7‚± ÓÛ›º‹9äçI'‡§sz:'¶€pk ª̃ÇR°—ËiÎèéœØUưŸtŸV¯Àc-ØDb9ÍÓ9=ûjuư'ƒµÜñ<éĹđtÎ@OçÄ Œơ»‰¾³ƯøÇb·­c9ÍÓ9—çoêöJ² endstream endobj 369 0 obj << /Length 4063 /Filter /FlateDecode >> stream xÚíKwƯ¶€÷₫\Z 1Ä‹»ê#mO³Jmí’,\[Nï©-©̉uó÷;$ÀËÁ€`vt-œăØ̉3ç<ˆXÓÁ¬Ñ¼ÑF´FèæíÇƯôÓû_û—WÁœÜ%^"É?_½øîoJ5¬k‡n`ÍƠûF±¾•j)ïê]óÓËĂápñËƠ/₫zu*JqƠ*)2ơJ.Ú]*Ư“t«à—m7ÀŒOù?ÁϳµÆ˜±}Û)¹aü,6KMÆ‹V·¼»¸́»îåĂư‡¹"ÿ=•Τi{秸Ʋú¥k̃Á/S¤n~›$?6¢åZÀß>4¯_üsƠÅ[Í߀ûë7ïhó1-ZÏ¢úDo–ªß O»–­ ÊÿpqÉzmÿ×{ÿZưa†È#¸k¨_e“ɶ̉s®Ï¡m~>AU3ù7›‘"ËƠO‘‚‰–)öˆHÁ8X*R‘ÂI-‘‚åDÑ8aªD lÀo÷‡ău*úv€‡P…¢¡ÂJơ§¡j"¸¯~‡ï[Ö°$[•‰(hTM*Hd9¹¦UĂà‚Äg›n –÷ĂĐjµe¹“…\„0Đœ âĂëëûĂ›—Bˆ—?^pọ́ö₫ÛCÜ™鉑뤳¹½n¥ä¾];WÏGĂÇØÉ8Ó@Ơ$8Îsùj}°öOtö³ÔŒrË̀¼½¸„ßߌ$ÿoüăz¥÷ת5½œqSẫ_íàÛó0”»Éˆ%ß½½½ù¹c̣×O÷×WF¾¼¾ÿx¸ys¼½§M.¸n…Q jƒH“Ï̉A“ùQFpÓ¤ÅöáA„>ÔøeôE=˜ªIÑ—å ơèƒé©´ÄèsR'úx}P Ô¯}ØJ §>=ü›60WĐTL4¨Æ‘¥ƒ̣YăJµ̉0ß }Øư55lQ^sƠQ2¨Kơ°Iu–ÓùT?꾃áhj'u‚Z”A Å(Qjl…úưƯưáf´äø>ëƠRŸØN:h$vÏÚ^“FÚÁ₫=g»øư–Å‚ªIåmơúi©]Hˆm…N@Ë2 ¥f>hdNÀóÚÊ:WÖt³T6ÚC[aÚ4´ƒ†\x¶́ä}M [4/ï¸ æDI åw«G²°Ê;¤PvR'–UËB¶\È ,c{˜W¿¹2“nTá(ÎV:hÚ/ƒơ}ïÛ³÷Ë¿k¿Œ̃oÊQ"¨KD· s–·Uió®52 ³“:ÁÜ—Á̀YÛ™0c{(̀¿^‹á\ª¾c7¨¶1’tĐ8„d ½đÙI₫ư4lá^z̃QF¨̃Y.X¯³îtÛ&Å·“:ñ­Ëø†b!*đíYáûîpóp|süô€n`éX°U;º“Z‰€>ÀLI«öé/đ ½µ2R£̃NƠ¤HỊ́¡j¤ª¦ƒR'H¥N¤"RÇb´á'Ơ³‡’º>Ef-w¸êFƠV:h:I†ßª̃·f'ô ̀’ñk.B:Uc±`[Hç9]­±µ2 ¶D&‰vR'¢‡2¢¡˜qSƠă‰ÆöP¢í¿ÿ`ÿ'́zY;ô¬Aµv½V:h$¶‘đÙÁ·i§î‹ •ñ»+£5ệTMÖ,Oª×÷°€#û®NjÙÇá¶w&®P̀øƯơñ¸b{B\W¦Â²í8oPm£Sa+4N8îŒöÙןÜT¿ô2¾£ŒP5)¾³\°ß°Ơ¡RŸ f©…oVÄ7Sc&́™³‚÷÷W¯ÂÏÉÆ°—úF?'7Â&ÍC×0æÄđ/¤a _ôFËđ"@ƠXø&¾Y₫Um0-aÀ(“ô:©…^^D¯ä°ơ­`̉·kÇøËjØ¢½Ø2£HP5)³Ü¬^g {|ơÊ¥œ¥œEÎ|€Ql œ±=çoÈ=—̃2„MîZù¦́á'°a¿ä2£LP5– ±És–ËƠ㙩¶—©ŒÇYjáYºŒGŸ¥ ™ V́èBZbÉLN:0$3™1±YúFí$=§¼%́OeÈFƯªI!›åƯƠÔoå$ÖI-ĪUb?Bj‡¾eP̉£ÖI†jøÆçoG¯üG@£è¦_TlŒF'XAh„ÍjFÎ{ºkøÜÁ3öÊ"Đă´P5 Đó©6x–Úv}ñ®x–Q/̀ ‹‘¼Bº“gÏĂƯá»÷o?Ü>„3`ßÜ{Ư JÆæÀN:h2 ævï¥gĂw¦†-ä‘C”!ņªI!Ÿåµß²m'“Ä;©ñeYËc1\Wẹ̑́™ˆ¿µ€ë›5êáó6ªgzĂÂV ™×FúV́]ëy1ü¡Œù(8TMù,ï¬×ÍË¡5©T 'tB¾,§YªÑŒÈ#s&âW÷tr{ØRÁ(́V˜6…]µZøÍ±ăyV'"o(C=† Q’=Ç1ëq. £IĐÔ‰ô²d籘AWÈ©̣́™P_ÿ ½đx(ªdv+´ ¥]Ă₫míÛ°“}^];rˆ2̃£ØP5µI|–{ÖC R&•f5K/ˉ‹1¼Âæ2ÏùµÔIh>ÈƠ0Æ»“„đ=Ă) ¾ûP₫Œ·¦a÷(£?JU“¢?ËY«MæÁP)’đ;©üe9Ôc1pSø±=#ü«#{6LG© *Fé·̉A‹Đ̃RUÀ`Ï‚Øs̀ØÄ~Q†}”ªÆ²ÓobŸå¥Ơ:}ÈM3ûSù]³Ô‰û²Üê±Å+äwyöŒÜ¯%‰ÀIÈ Ơ0½•„vúbêô=öNÿü?̉c/) q¨DÈóÙzA2™HeÍR§ P–¶=#t…¬1Ï1l̀ơÅ”ư…êë[é I•=C,Ø£ÀYMơ±?”…†ªIŸåµû¡“äƯIx/KêÖáđ¿¼c{N¼ÿéæƯ«µA?œ̣?®Đ£ªF3O¬tĐ2aYG4x–́¨~ƯY:~£eàF½Ÿª±̃¯7ÁỊ́¯z=5ÜÿeD*ƒl–ZvÙ̀×wƯ÷1ø¬ »¾A%ǶÔ9éÀ²¥.ç1ưà²wÏ|KƯĐÈóÊ€BAƠ¤€Îâ Đp8AoR9d³Ô4 €F=¯º×ñ¡=̣:>ØÉ6¬u‡Ü|mªOÎ%[´úë—lyêẉŸáñ¦Ø­ÊbD”3ªÆr¶y=H“W­ HÉᤖÁ3B<¤û:!ë_¿±SÙơ¸¥:Ñ¡Üz©=0pïHíw~Ÿc„@nU!¢˜Q5©‘åäơF .1©<¸Yj "#DÀC=3UBÖ¿qU'$ü™¨>Ña¥ƒêÓY8Z×S¿S,ö§²àŒªI‡,ï®:‡ú§îö›¥–à 3‚<${]%8`ưÑ•=>¦ë-¤ôGé Â}ùŒißë³Ú«‹¢ ̣((TM ̣,÷¬t/øtrR4Ívr„Ïk‚WùÑ̃Âûs§ºï¯ïî¯ß¾9^¿ƒ‡̃qÈî:Ơ u1ôœt`A¯ƒÑûÖísüomƠ»Lœq§j¬o^6”çÀƠz`®íưñx–:ñù¹É±ăQ³l,:ï₫qɱFM[̃=“oï¶̉cÇeˆ£zÆâ‚“…ÄÁáèzáÛ°w˜çq3ö„2Ü£ÈP5)ܳü²îp¡Nm¥uB ́¼ v8 ±cª ́È¢‘ơ­+|áP. '̃.µŒ¿­0m:Ü©Ä{Ï‚½ƒ>ă˜‘”ƒ…(Ia㑵Vå9|âîS+nNh\”A>}N—U G!È7wŸk—uÍRÑÄMƯCĐ(á5ƯFû&́½í8ô½á2„c(%)„sœ­^G- cU§’\g©…bYF1”£Y±IăÛOÇ5ÇËÁa•U7q7÷tz m•»¹a}Ă3e'đ«hØâ½ß2£X Ú=“&Ú׳Qá¬éqrêíƠ­tĐ,÷ñómØûÜ'̃«c(â<Î U“à<Ï!kà™­æÌÔ‚ùP†9”3TùîY4R¾vØï¦ m¨ÑƯJMB÷§ñ–w¤IvÏñ¸́eÜGá¡j,÷›÷—æyi½₫}\\Ö©üƠY í„ù¼ gđ¡S§{Çà¯åaQîzF•L+9Jm+Ùk̉&;—guÖvˆ2䣨P5)ä³Ü³̣RĂ] ©ôµY !χrz5Ta›42¿zÈÔàÉfœ-7µ)i“•³åàÓgÀ>ă>ËÎùEùQz¨ùY^Z|!'Öä;)D>/"_Œ‰$¦ ùؤ‘ü¹<¬¿T3:—·̉A«„Kw÷-ØÑ?­pØÊ`CƠXØ7/CÎsËj3zè³O²î¤ë.( ’Aá–à-%’At` =™ÆÀÉmƒoÉØ>`÷IF.WFrª&Erơºín'Ơ©|ÑY ¡,”qÂ(ŒË!ă†u²—1 ;ÏÆĂÚ< Ö¥Sơ ½¬A5^¹l¥ƒ éär‡´¯~çûÛ [q9RY\ˆ²EƠظ°y×r[W‹ \pÆSIlNE•5«X!(`ư«§Đ> ñ—ÊD#‚¦Uï`¯éÀªw–Ó§<äLEQ!JQ’ˆ Y~]kĐ3ï^§"‚B¡Ïˆă™-]•ˆ€ơ¯o?­\̣gÜ,¦¦îx·Â´ö4«~ÛqOûNÙÙ¶ đ‘Ăˆ(I€Ÿå»ƠÆ=[‘!XĽÎà̉JƠà©_?kÊØ-³§ªDn{­_ïpb0†ï<>‹ºÅ…¢@ &_E"ä¸rµÙœ¢OåÎ9!̀)¿1™”.EǘtÂÔ%´ ‡S$°!;•χû b‘‡!u~¢ÄB»y¯k̀Ùỵ̈²N: endstream endobj 260 0 obj << /Type /ObjStm /N 100 /First 907 /Length 2176 /Filter /FlateDecode >> stream xÚµ›M‹G†ïư+̣h_²3"̣+@¬ÚË„¥ƒ½BYnŒX3³ŒF`ÿ{¿Q•Â0Í.¦4ʬ÷Í'++?"³YJ*‰…QCÊø±ß%I¤5Ơ6¶Ô†]ï©O»>̉P\¯-)RNÚÊIúLT¨#>hÇ_D—+·“Z^»Zps»ÿơ¸áîÍ~đ[Ç Ă ;̣ÍÙO e)Åë„™ñg±̣ $̉y0J½Ưâ·‰̀£&éj™[’I–¹'QC#ƠR¡Ưưçt~qÿđËå!½³¶¼?¸||Lï@™'r.joNÍ¢öJ.Eí»ốY:¿Iç̃¿½Oç—éîߦçÏOø÷÷,ƠÜQqnÙ¸åf´–;å˜YíEè’Ñ3LͳƯ0Ç0ºáÎè¸#ö™Q§̀HGG÷PÄ«áNh¸¶–Ñ)' • `F·§ç1ˆî¸3₫ß/Ó;ëwKú!üéßè4Q?hî¾üöÛû=Û«û»ÇMéºyÍ₫ £›ũö ²_?Ü|sA™̉ùơËWéüọ̈ûczÿW´×~½œÎÿ€Úåîñ³\v»Á|¾ỵ̈đñb—Æở÷—_>}xqÿû•¸iË6rÍV€½₫đ ¼’×Ü[}†·ËV"–·´Oévñ´zÚ<íO]§»Îpá:¨©kêzĂơ†ë ×®7\o¸̃t½ézÓơ¦ëM×›®7]oº̃t½ézêzêzêzêzêzêzêzêzêzzƠ³áö’§́©xZ=mvO‡§ÓS×#×#×#×#×#×#×#×#×#×#×c×c×c×c×c×c×c×c×ó–k£Û–ë‰ë‰ë‰ë‰ë‰ë‰ë‰ëy»owâíN¼ƯÙ¸yM]¯º^u½êzƠơªëU×k®×\¯¹^s½æzÍơë5×k®×\¯»^w½~Ơ{ÀÆèaQ’­8C0–Ih÷·[®>>ÎrQúX¼ „ñDñ̉ .¹ÅtÏ…è9…6ÚUó@#›vÙÔ¹ŒŒw&s÷\˜_'%’§Íe^ès»Ö¬Åkb9Ưsqz.Îbû(´ơ¶ơzt,Ï2c9ƯsqzújŒmed‡N,Ø̣ÇñTơĂAÛ »ç ôÜ'mdÆÑ̃æ\̉¶MËé;g¤çâDx­4[¦`‹ªnJºåXN÷\œ‹ƒ¦Ä´íNƯ6'Q,¥;.Ê@ÏE‰đÚh¼yY ± ́=˜Ó=g çâD'‹“Ăv{›Úb#Áñ'-ëA›F»åÂŒ³\”®U;ª̃¶y3¡ÔXÊ«å‚ ´Ü)IqĐNºmÿáŒ5úÀXÈ«ăb t\Œˆ«aÚnß6Ø̃KÂ)Æ̉f,¥{®CË‹<Ô¾„€È…}›ÀBđ8₫´çAc»çâ ô\œ8à1íË zÙa ,ưĐsºçâ ô\œ¬uûö‹…ƒÜĂyt‚ưx₫ „ Dc endstream endobj 494 0 obj << /Length 4104 /Filter /FlateDecode >> stream xÚíOoƯ6Àïù:Ú+â?QêiÑtwº÷Ôöu^²â8ûl·_‡¢d‡ÉĐÜơK"hÓ—gHͤHÎ5üĂÍ=ˆvº¹ºyÑM¿ß7öÿüû 6Ë]€à’ü₫̣ÅË¿)Ơ°®»‘5—ïÅúVĂO‹ÔåÛæ×³ë?οüñÅ_/KR\µJLµR ­ÇæB阤[Ùv#ü‹ñé1ÿüüĐ·£”Æü¾í”Ü0}–Z„&ËEËØùEßug—¯~>¿Bœ½úp}øxÎơÙ=­ë‡V ̉©Ó,ØÔ lëÇV áơƯ9<­ízïỵ̈,}î_Ø× ¡^a”&Û^HÏÇ>‡„åù TÍävRnRœåñ’‹¶= ¨Ŕ³mgk‡aÛKÅ†í‹Ø"ơÈq;“ü—Ûó >œ]Ư¿9‡ÿüa₫uXjö³VíĐCkÅ`”ưú{×¼…¿ül“ºùs’¼iD˵€?}h^¿øÇªEzlGßû«OÖÛ™ g÷/¯n?₫Ö1ù₫áx¸<ÄÙáxsưñÍưí‘¶º€v\5¨"­¾H­æw4‚ËVñ̃·rïÜ[ ¢—PbÔ™©ˆY.áƒXÎa?0Ö§8\¤‡¼„CS̀8TàĐ³g…C€P=Üư›61—#ôq¼A•4ñ"´‘OW¬í€:Ϧ}x xă·]„wœª&wïUg{˜÷Oñ=K9¾EßP̀ü%đD¾±=+|¿?܇lĂ䀉U8ʶ•Ú‡°-yË;̉>;yÏ®a‹tôîËH̉BƠX̉Ơ&éYXt-Zi ˆ‘>K9̉eéP Ô¯éØ̉‡7oCÔ5P)Tă(êV:h :ŒCÓÂỤ̂ ÚA|†Â¶àFo» î( TM î,ß«6Kï»VtI¶g)Ƕ*bQ¢ÛضïVFqö¬A¡=KíCGq¯–ûö́3ô“ÅÑ»/=J U“=Ëëâ0ZÙ"ºrœ÷EœC)bP8Gæ¬`₫çñú₫€Ăí WƯæV–¶Mø>rÏ–Àúw/ºŒéD‰%ºß$:Ççê-D;¾W‚èYÊ!­-̉!OÁ•Ö°ê+¤(¶e5Kv‘=+=´ü­g×îí_óƠ¸È­ÊÈ@Ơ¤ØÍṛǽæ²i÷²ƠÜs3îŒñ­æEh!—“­æ×‡ă<_°³c¸Ư<ÂgÄØ UÑưf+XFáå­”Ü7mŸï~Ă3jä]e GI j,Ăz“á,_¯7wºíÇ!5ÏR—í4›bF!*̀©±=0 ¸[º‘ăçl2«–ÏFÍ-Ưd¶̉AƒÑMf=ͳ±};—öPă—±ơ_ª&Å^–+TcOp"Aê{‹”c¯hwÙ£₫tö<{|ö¶6–á u„"P}ß³F:h•/Ú±÷ÍÙQ;iü¶‹ĐăAƠ$ĐÎó½Z+̉j€=â1Iö,åÈ.ÚW6Řܧ“íñÉ^ƯRÓT×è>“•†.F«iWĐ3e§úä¾{ñK/ƒ;JUcá6áÎrÁză6læ²OÑ=K9º‹ö’M1r`èÆöøt¯o#-3më*›8 f¤ƒ¶Y9 Ǵ=[vøNhĐFo»Œë(TMë,߫ǵR Ú^Z¤×EûȦ˜ŸÂ9>ÖwëçÀÜ3éS`cØ*á€mÎwzf́>Ÿ†-°Ñ+/; U“;Ë«ÍÆ#Ë$׳”ăºhßXÁ¡H ³ØǾ=c̃jíK}e[é qè€ ½“¾1;|'–_sĐQ*¨ ô¸ t–ÓƠ©ùĐêQ¦ˆ¥ÑnÛØÑîĂ6’Ùéˆî[éÀ$²é4À²Ư(|“v/ÿ¦ÖĂ?•uzª&l–wû[Ŭx¯X1XÖ‘"¾W¼-¸Î‹a¿ü0ïÿÖ©î‡Ă§ăáêÍưá-ü †ÀïyƒÔņÀY:° „~ÂOy; _†-.‘³”qunªfrƠmr™åºƠfÆ€€Sñ‹Ô#˜f÷—±ü©±Yc¶ÍŸ5À|~̣Lzxûé廫·wáœXÈÖÎP5£ç¥'á QHw úiµƯ³`‡ơÔ_äeGI¡jRgùcµÙ²ÆVÈT”ă"å(çE”›r”®B¹g’¡|kƒY@ –îTÑ(çV:h :¬́Iæ±û_Æ₫ö„"̃ằP5 ̃óü²ïºoÙ˜‡Z¤w(G̣¾ ïØ$ÄûơÇOáR¶‚ÏÁTÛèz—•‡®w0¾%ûØûœGÄđû-C9U“B9ËÛjÍÏe§&d’äYÊ‘,ËHî ©ª ÉØ$ḌíĂưÊ ­`ÿU7†̣,´A¹‡7{Í)ûPư,ñMøÅ–1ª± ³M†³Ü¬̃p g#†TˆÓ,äVe›8}^adÑô…}kc­ Đ*˜~«él—«htöm…i³„_Ù& 6bŸ{ŸøG6zÿeÇ@!JRˆç¸b=·$â³”c¼/cʵ¬Â86i‚üÓñÚR¾[K>Đq̃ Ê&’é mÂä ~̣ Ù™~v [„£w_†x”ª&y–'Ö£ RC*Tj‘r”ë2Ê¡œ‹*”c“&ÊW|Âz—I‚ªåÛJ­BÇqƠê´Ê₫µ{ê9r2̀£¨P5)̀³²Ú'7*E’̣YÊQ>”Qå@²¤*”c“&Ê׉A§9}k»zF1ïçom̉,s=åÖơlØG̃Sǹ@æQV¨‹9ßÄ<Ë!«æ/̣̉!¢µH9ÎÇ"ÎM9óœ{&Î×b³L— ©FQ%cÏ̉A›È!:“Ú7`ÿ(ÿ¢&đØ!cCƠ$ÏsÏzÈNÅm-Rè´K÷YÁä¡¡Yä±IùƠù;Û;ûS̀[é QèÀ±¥Lû́D~›àØÊ`CƠ¤`Ị̈ËZÓx¡ÁĐ!Éú,…XgE¬kÈùÏë°M2¬¯Eqq>å&D•Œ¢n¥ƒ6¡Ă»Ư/ó ØG̣ÓÔ°EÜk×ÙĨ¨Î9iTi­§QớÙG̉ç«ñû-:U“:ÏÛjMÀ™†,L<Éó,åx.ËÜdÊ«äCö,̣p̃¸béQ]×ñ‚pĐ24;¬s1æÛ±Cvr—ûáw^Ævª&Åv–Ö¬á؆̉©°ÏEÊÁ]–°É”3Ô«±EÜ[×ñ|k¨¶‰ëx§́l´qÂëxÍƯÂ)ûôût24á·]vªÆ‚½ykgïƠ[j¸X '¶H9°Ë24™rz5V!›ä‘½z#/ŸNu¢ÚFÁ¶̉Aă„·̣JA,ÙY<½½ô2¾£ŒP5)¾³\°ßpßשC‹:ơQ”É”£º¡ ߨ$ï‹yí}¨¾‰•³)ă"mpåLCzXÏ–¿Øé¯¹Œé(TMé,§«ö¡Í!7O"=K!¤‹².™r K¤±I!̉`§‹…dC‚Ad¨Ú1²gé •Ùz”c“öIùÿbôFË ’@ƠXˆ7/ëÍó¯zs§á‚TˆƠ"…(æÑü„ñ°G§h¼ƒ•L o×Ö÷MÚ‡ªoévḿOeÀFªI›åƯµÂFsè‰ÅĂf™Ö9eÂ/¯¿¿üéUóIÉaÙו z°ÂÔ0êb±»os6ØE~V„nÔÿ‰’ÉơúÍëư²\¾Öl¦±½N1ÎBà¶Ÿ7UÖju€RÆîi{R9zÖ<Üưë₫æjëæmX̉úñÔª–¦-îF—‰mØ;‘“ aBo¼ˆæ(DI‚æ,ç«6mîa4OM­Œƒ™—À …h¥32fayû?³ ‘Ç•ŒâleI‹P5ÄPhlÄ>Ä̀îu±CÂW‘ 9Çíª K«¢O…BÍBeQ‚2”̉ẉé(ck–×·‘Åt~ËU1qHd:́Edåˆd ûHzr[Mè¡…‚(IÀs¾ÿåÊ endstream endobj 384 0 obj << /Type /ObjStm /N 100 /First 908 /Length 2176 /Filter /FlateDecode >> stream xÚµ›_‹¹Åßï§Đc̣¢«*U©$0 »1ÎKfí‡lŒï–,3a<†Í·Ï©îj-{aÙ´ÀF3íîsôÓ•ä*=•Te$¢–ª–Ä•‘u¤œ¤ ̉´ă=•Ô†¿§©“¿×̉`Ej‰Jí—ªB₫µB‘ưÓVUƒV£D2đQăD­@ÅđOÆmøÜđ…Œ¨»`«‰Í  î].µiâ1àKx¤Ú!Êït<­b©GÁ§ux 7¿—¡\;áñê/k’"ơR$¤₫²%aóïI61ø‰"«R ‚Q…’XÅ‹¿t”‹ü­»X̉̉ư‰&¥Ñ/‚/µ’?±¤Â+=©;¤ E"T’A™Ó>ü §V?©©ăsB±sÍÔPøAe51ÙRÓî=5óLÑH­“£TVÅçLÉ ªX`„‚ˆw|Î’lçÖdJơ"Ü’5Ï*ÊÈ̀³Ê=Y÷¬â© Ïj-©”¨ ô;/-N½zVá×¥úI]½|*ÚJk(ÚR7/_ï^´xo0¡°Ó ˆ‰4(T¥¥á­@„ÓT¥HMCQ{"’†¢i µ\DĐ ‡øç̃‹ú÷hˆ…̀Đ ÷­&ñ“× …RQ …SA™â'´½bêÏ?u/'´s*Ăy´t¢ÙÛ:±ûo½²¿çưÇó,̃ÜI=̃̃©yyƒ'óJÑđ6„v ̣gđ`ªạ̊êƠåú₫?ÿ~H×oŸ^.×w_ÿñ²ư₫—Ÿÿu¹~÷ôüăĂsúPĐcËÇËơû‡Ï/郒ä†Â†}n¨IeͲB&2z̃û6½z•®ï̉ơÏOïŸ̉ơuúƒĐÓ7ß\đç÷y¢dsG÷C•Á«à(™·=S×<0kZQY‹ăBǃQkfŸÈà\0á4Îí̃H'ç0†ăÁø›_§µùṚûtưÛÇ꫈‘1ë>~ưùçÇko_6¥7¾‚Ü_Ó¶Ámû¯]ß>?}~÷€<¥ëÛ×ỏơưĂ//éăÿ¢½ưôχËơOP{x|ù‚ơ—øçóåéëóçÄû£¿>üøÓ§ï~Ù‰uhfĂBDPÂ`o?=CÂWpûë[¡}¹/>> stream xÚí›KoÜ6Çï₫:Ú‡¥ù~ô”hEÑ6nQ ÈÁY¯ ~¤ăøăw$Q+>$’Öê°¶öZr†Ôü₫CQ4©0|‘JÑJi†4SƠúú7Wï₫­Úk·Ă•cùîôàø!*‚‘Á†T§• )-·ưWŸ>Ÿ~8øùtÛ‘  Î ½rÊ7+¡ oÖX#DØÀ7B›f₫·=Ái­ëđ%‚„̃™uVMè øÑJb|øæöhEơáú₫́~<Ôß6ƯÈ₫Ûº#J -yÓ Ơ¦vöé3®Îá 6®ªåuÅU >]U₫ŒHdüx¾ûr½>¾øqwy¿ §•r…„T•3ÎÄ´vÖÑ´HæA†qp?ŒŸVDªö‡ô~¼X`²ăÅưíl>!D„#ɸw·Ÿ‚E×>ƒE覹ÿ’Œ"]”{[¤I ÙiB!R–CÚZơH‹é§p,DA¤o–KgÅâsD8®•ÖåesôjIơ/qëd×4n“¹ºÉq[”ë>·Ó±•– "‡mgƠc+‡°uk/ARÓ¦¡vª½)büÖW·ß¢ªKŒFfÎSJ-¬u4AƠ…)`̉÷¾ ül=ŒH€›2“$ ÍQè&#e <[é–Z"‰iN¬U¯ªP ¡}¶ØYÜî6gç±HÄ ­3¤¤´ÖÑ  P Lˆï}Áö¹{“'u¦IA§ĐMN y>)€µ1o;HIµê¥@J4„Í"n ƒá¤^{@#gLI-h­£)—Qxª̣Ü/ë·prf$A Ư´"@GE (ƒ9ÓH3ơ‘„Æđ:r‰Ăc‘[«Î¨Sû8đ÷?ïI$e„sp(+§ă‡Ö:#¨É\ £ôY{Ñ’‚ïäá4¶“„„nrlQ1_‡½æVRơ½5ÚÂÈ”}÷º¦Åîûîn8—„_ >ÿSk%º ?³énĂ Ê=ƒ­yN¼l÷|̃¹ÿÓøN18ÉÑ]’óÁͬaMnkƠăM'áÍ8¢ŒÏ€·åûökÊæfˆq­*g¤ÆÁ8—€qÓêô¹,%öz·̃½ơÓđNRºÉ^”ˆ³íÖSŒ4Ïn­zÀÙ$À).æÜÇ>´yj‚”êísp·ÖѤ„ê> stream xÚµYÛn7}߯à£ûPäpxŒ‰ RĈ]ô’úA±×©PEj%9Mÿ¾gv)¢‰$;hDÀWä̀œ9ĂËÎp}Ê(¢²6 MÊ‘C›ù¨|”1Bknj֩-©d-Z¯²9VÖxê| 0Ä" ‹.hR–²ÈfeÙ@8eƒƒƠd•$=NÙÄÀM¤l†K>yå }bålöO®™„¨œw†# ÂÙáX́I¹à•’"#&±âa6Æ=\!‚‡l½pä-+t€!"@²‹ø`dµx˜Ïo¶bËÅf°tä6âAN¸ñÄ&—«åíUŸÔạ̈üBM®ûuó)µË黾›œÁZ¿Ø¬¥–u!³^>¬nûơö]?ôw³é‹åÇ‘1rdÙ}*yD8ƒØåt¨XÂ(>m p)°Ä%©¯†6›̉Ú¡•âjl¹´¡´±´©´£¾”Uc[ô+-•¶ØsÅ+ö\±WB$ƠÔĐR±GÅ{T́Q±GÅ{T́Q±GÅ/öühïæÇ#-åóqxwF̣ÚÑ£Ïé *˜u—6Ĭ<­C₫Lc^m…·Ñ¸ h˳`V 1ë‘›3̣g)‹’vFÊáˆX·å¹Å¬<bVH¤>Æ=¦áeaLmỳẓ6Ĭ<#!–̉5Y–Û‹wé₫ú(¸#ñ,˜•gC̀’ó${¸*Ê$ƒs>„ˆ%ÅmìJ³!fNđóx›à¸ÓÁI†ÄȵåY0+φ˜•'Ê@‡CxâÆùÆ F[²̉lˆYi¢ ”»D‡7˜dñ¸ˆÓ†ó,˜•gC̀ÊÓx£đLÚ[¹HDUxàà£#Ñ,•f;ÈÊă§•G‹oZ¶T̉O]2|êÛ÷‹ơf:ŸÏï~3̃Lw̉̀—Ó;ô ^ŸXéyTlÇè˜ÀŸ¼îÿz˜­ú÷r‰qPè§Ùânù÷ŹÍFƒ¢¯p És˜½Ư|‘Îưư·[­§d_âóbºƯ…׸™‘‡WúƠ‡Yÿ÷¨è¤ë¡ƒÏ6¿/WëQ{ûcWêĂt6Ÿ¾÷ă lúƠưô¶/J{ÇÖø~Ơ¯fÓù¨ưyçÖ˜üœ¦ÿ_.W›Gp¯Ï.?•ùqœ<1&êgóVÔc³t₫9¢ốÈó(ôʨïgxñ°¸Ừ– ‘xƯß÷¸iÛÎIß₫ñ3gË÷ïG¡­BYûv´Çï—ÿk!; endstream endobj 623 0 obj << /Type /ObjStm /N 100 /First 838 /Length 849 /Filter /FlateDecode >> stream xÚ”ËjK†÷óµLVîêKU7„p8 ˜,!9p–F–Æö±Fhdçơó—$u+^ˆî™úêöWÄ{r$>B!áPG!e’à( Ó2Î@̀°ähf!NÚIÈÄjï qÁ{ؼŌ¼GĐ˜È'{̣bg&Ÿí}!_”$1‹›<…:Iµ oJ%¦L¡€O…¢ó$Â-®x₫)' Å#¿(%83¥€ú`K;ZJvE vû¾Ee_‹¨î±^ lÙ‘:ز'…"’iNP»&{RE=9“Z}¹Pvˆ2¤“â)£w‹•Q‹€É–=Ë_2ö:Gªc*ÑÎHE0—¨¨=ƒ«˜;¶Ñ8\ ®2ă"v 6"°è›Ù¥NĂa/V\¢ya<¬Ö‹³9¢9lÛ¤ÔĂƯÆ£ơĐ_¡ {1I½uØ—Ø)8ˆª¶ÁV%Øazj›ÄdB̉`úØn+KÁ65EƯá¡^1!N´}̉Ü)†É *(6„“ŸPjÂ~(~Ø5DÆ"q*ˆŒ*Y¬ ¬ KD©ˆÅbÙ1̃O 0´é1f‡7p·„*đRl€b[XM:HÎ+ö…³U±8[…H̀ÙÖă€r€±3\‚ë̃ƯOóð̃<í̃w>ĐƠºº₫›èê3½Ó÷ôñă™v—˜m¿XƯëÛqZ₫¼Ăº?̣øµv};̀)ơ÷8–휸î×ưv1¸—‡3ª́Ăz̃múqóâ×°¾›Îv/}ÏÓøÜ?LsEÀëo_₫=Vc·f¦ånñÜßÜo†Û«»å8Íư[áiÓ¯ßÊn¶ĂzwW¡¹F×5®³ór±~sàưÛđrÜ®úçay±8—­7-ư ÓèđÙ ưTû6^Q­̀¼™Æ±m̃m‡ûû~{|ñŸ„]î/â~Ù̃Pa«SCJƠĐ–ö¾¯ ÏÁù bLŒ7‹Ơj{™h©v‚48!V·Oó;̃ÏĂÈë÷\CŸ:û¸˜₫ß¾îÑèH«p}u¶µ¹M¯×rôxlÈöm?ø±?₫áÿy:S^g̃Éöç̉t¨3̃µøºÈG₫7*$©’ endstream endobj 779 0 obj << /Type /ObjStm /N 100 /First 849 /Length 882 /Filter /FlateDecode >> stream xÚ•UËnÜ8¼ë+úhŸ†Íg‚=r b ²GÎ «Œ gÙ¯ßêq̃,©Í 0 EVơ£X”R2”Ä,ùŒÁQÔÅ@˜%‰”=!æ„1[Œ™‰PÙGÓ%`Xá9gÄʉ,#X²6“&›¿‡åT.£̀§rg^†Ă¯£—u<”ç ̃ƠñëĐïỰX₫i¨µé«Ø—áåüq§?Ô±ëôđØŸök_m`ƒô¥ ÇñïËH-'Å&ăl‹¸ĐcùråXæåq,Ç )5Ieü<̀UĂ~å¼`+ụ̂zeƒD +¾B4́÷ăæ˜×̣óÛà¼Ö ûï†`wOóáyütZ‡»aư<ú2×^V¹Éoå£yk78u¹œi3̣mPª7x¿Œ}{Ÿ*&sÜ$6i6ß›¼ZGv s÷ñRÊÇ»Û Å5)­“q¯oĐR5²ó?cê7íöĂû¯7“f”ïµ-có{XÅÖ¿RUhă¬CÚ̉åûL:. endstream endobj 933 0 obj << /Type /ObjStm /N 100 /First 902 /Length 850 /Filter /FlateDecode >> stream xÚ•UËnI ¼ë+x´Ojö›@́"r 6̃›ÀÇÉF²¿¿Å¶V£æB>hÓ]ÅG‘­‘àÉ‘„H\±dŒ¥PÖM¡H¢#vØØG¬8êˆsÁ‰%®$Ṿ¬ïB̃ƒ—˜<Î$ỵ ÎS$_á'%̣â± œ°V <„ a3SȲ’‘ đ9Q À!VT?¹R,BR%?…)y]%ä$%R™”LIGA5 àdÔ ƠQκzÊxÔXâĂ.¼©hµRO©BEP¯0U­¹×V‚½ªùH¢Zt?`b²ÓÈ ƒ[U0Ô]TCư©®.«¸A­‚‡O+X+ªVH̉W†ø®úÿÀ̉hhs;Å+ 9i=ଠˆ˜2Đö́WT……_®ëÁ ^½¨Ó55 ‡¢1tX‚´SĐbË#ƒ¡ĐhbΈ¡ƒk+´¤é:¤‡â”´@uŸ,Ztv­h<²¦ë0Fœs³đÈUëĐK«#áµ´:0N\Vú(M+Œ×&¬ QƒzVWµ)„Ábí,a§10\,*‰Ëđ"¡"FW§V ¯½ƒ…!v^¹3ÿÚ­‚ àB5ïD- ¼g¯ÍóM-\„×Î`ä<׺ºùcÚ,¿†oûƯ¸₫>,·«hư•ÖŸ§û‰Öwṭ-}üø8O×!÷׺üg—¡-ôÏíÓ_ư, ;‡ơtømó2í‡ÿ‡u!¬´‡˜é̃ụ́€y}¸¹vó°y\†§‡ÛWrÿè2–¼•hÙ́ÖÏVq=́ËaÿăĐq»;,ïÀO‡¥Kˆ®C˜vĂöJèn·Ëó•à~'»P£¥‘/±Ư Óá;Èî…‰₫h¥y„̉9 §CküÏ!FÖgˆeü9LƯæ¬Lă 2î̀‹ñée¶Ë› qÜ2©´iĐơfÚ>ßóp?̀?Çíă2Íï¡7$&‹ĐŸ nèlâû3’-¸¥>é¿1= ₫u˜ ó›·.–‹,ö zeLºƠƒjú=0áFL|¿bÁ­È©{CÑ¿ï̀DÿèÂCúí_îđd ºØ¾ô&Ôø@$6đÖâHø¢ư= endstream endobj 1233 0 obj << /Length 1734 /Filter /FlateDecode >> stream xÚ­XQsÛ6 ~ϯĐƯ^仈)Q”úØuíe×­[®»kû [²£‹,¥’\7ûơR¢l'iÖ]b‚ Aß‚â^ÜSÂSiÄ̉Hy«íY¨¥ƯÆ£—¯Ï¸Ñ @1p4_\={%¥ÇC–…÷®Ö! ÓlÜïªđ>ú|ñùê׳_®Æ¤LÆÑwZµÚG¦SáqÅ—1F/DÂB‘Ơ@&‘±à~Óy]WÍfDJúySĐºÍ ”Âñ ½@¤,̀̀fW×%,‰`;Ø«ÛmËf!”?́çF©?tmM‚¡]Àj¿­o*£²Eơ]oFK=mv¬èteAC:\ûĂ5Ñ"<¦Æ­¶ˆaă²`è›'Œ›S_ ½Dú«wJgH]Ăz8Æ!cY" c–ÆöƠ¾₫ưư©`AØUœZ¥·«!Çx|]X[‰_T]¹ê;2µîÚ-É1PÊ_-‚uÛmÊs̀Rä·é/ä^$è…[ÛO!È}©ăđˆ3™áÆ%§o)]…IÈ×*7© è-iß̀̉wK°: z”9X‰SN0P(ÙâN8Zêi«¬Ó§áä­Qœh›•‘̃̉ÊFe¾Â}¯OäOÈ”‰${,€ô0¾/h¢/û¾jTæ mWØ# «($¡§€‹4aBEóˆ¯wÍj€ự"Vîiä3:²:fQœˆ‰‡ifr¦i-üK„Lùe¸B2FÂ'ƒ'x̀3Æ…ÉÍ+4„€’‚û¯ÿ¸xA¿úƯ-…´í’| eø¦̉,ß}#QÛÔw æçx‚Ô¯+ÍúƯ·`s[-IeÊ/ÆDâÀÁ©38ŸÏë"eǦĐ@i F aÉ—ƠTvØ"H¥‡ Ø¡O±}JɧX…~ƠÓL^÷­ùEy–‰ŸWu¾¬K¯1B¸b_5ˆ~åï{,)[F«®‰úĐ(4ôÑT{ló0ƒỆ¤‡,g₫˜äî«›ê9(Å1`Ëëp ª=fúù³g8 CFd0 <`P-]̀f¯œ/ă="’”ÅL$Y„wÈÇÏ¡WÀœƒÅÊÛk½­i¸†^í½;ûóÔ'”`1\C¸U(Ó£d›Bà@ÂÿăüY:7~Kàf!¡đmÊŸ.'bà™,£T/uoˆ‘qúư}Á9ưt x¹̣;BÓjS6Z’ĐU…Úuµ*;%U&ºÅ- ]N8sÄ gˆÆưÍ$îßGiq|'N§‰ÿÛÛ—/̃¿ĂßÊå ˜C¯¥HHܧz®ĐM{U,wừO˜uk»r‹x2ós3~NóD#Px"÷(›Â–MAeó’I“*&’Û c₫¡̣i€v±†º“¡f s0̉ùàê›'ÙăC$îï„c×Ù!ưÿ@• OmÆâÚ¬8è¾ ‰ûª®iîÚ©4—×]™w4m2S6sÛ…1€×TJ!̉RÍ«WAfË:„¦5Í^S–¶£kO´]̀:@èæ°c­áÂ¥an·Ùë¨t$¥ut)ë6rT?(é'{”ËYFQƒuXÍÁ0U{Ê.L¯ÚíÖt¤¶÷mWë;cz}°×˜ØĐ´À±9`4PÚ>7ÀHZ’y¥º½Ñ#4íƯ¯r¢Élé=¤B@[Íé̃"Ưbÿ¥nSŸÊ ˆdJ]§̀|j †²kÊfà€M¹¢û5fQ€0a Ωu=À/.¶ûNÈ© ¦´oȱ¡¦iK^i9²µÎUpêVvïx Œ™ ‹=¸úñ¯³T}O Èî)'¡p.áÎTsDø°yÓë÷Cp™'8B̃øö«ó¡́ »².ó̃>Øû휧„¦(̣ø8~mœ4¼­Ÿˆ#¾¯uĐOÏ" v¼ô„÷HY÷̉#÷ÔaOB©ØÂ¦Ö·” ưdÂ<±6vóúVæiÙvw4Ü£ƯIÈmv»¦qúFă(d*å`4°j3f̀±z>>Û)K'&¾ß>X‚ºø1Íö½µù^F2fI¢~€„ºÿ>IÄH èkåé:=ăá1÷؇Š̉lóÏcu{„°$¿Ñ5(‡,?đưÆ}÷]–›¼+̀¥¦ÄÏĐ¢ Ûr¸¦çz1×p{3”›ó6sÏa×̉ĂØj¡H?Œơ~ƒ9‚}÷fñx”.…NkyÜÎz ÷ Å"’7›I‘æ ˆzëơÿ©¨Î¾’<ùc™ë¡­µ|₫à*bIöcàGæó³O»"‹vA endstream endobj 1236 0 obj << /Length 1684 /Filter /FlateDecode >> stream xÚ­XƯoÛ6Ï_!ôIbF$ơYl¬R  ¶¸{iû Ët¬V=‰S ûßwÇ£Ëa¬(̣̣t¼/üÑ<ˆà™²\²\fAµ=‹¬´» hđçïgÜéÍAq~¤y¹8»ø-I±"*x°X‰ˆX”£½Å*øÙ§Å›³×‹ÑP"–Ạ̈™^íG®sđŒ Äè³)‹pF^çI*ĂË˾®fs™%áû¾¼U4¼¾›Iªî®V ́ÅLÆ©@{Q0!±,qæGƒ"|5›ópo6ºëiÙ´°ŒŒ‹œ–-6àNä2¼j{Óí·ª‰<4$«4Í:Ư`WV3‘…_fIÚ@­°Ó¨uW¯TO’F£ÖÁMÔ~VÎÄƠÅ5 Öû¶2µnƯµîhĐ«®.›s˜2¬EåFư®v£]Ù•M£SíÎ1Q›™d<á”Ùí®^‚”2¼»¯9wăưj‡ƒ8,Û•“ôK³­h\Sª[—fĂC6ÚNÏR²}eHư€y–½›tµ1P?;Ù–uÛ|¥ñµÜØ`½q°ÖMcëv¨Û[h5TJï°°÷ưKÚÂ4>̃œq2 ècÄ3ßnsÁRD¤ơª]uỡ…{³7åĐ!éñŒ3 ƯŸ|f–‰lĐ(É*ëÑà-/ ¥ehX¥·>?Đƒ ‡Î̀/¾TçN)›m’ÿŸloŒZ—n;̃–›ÎC*Y”̣ççº*«Bˆi·Û{¶R>ë€Eüíüx0™ËïÉï̃¸́~Ơ­¾Ư`ḯ½qdPìx~–ŸÁ2[$\+¥˜înư›ÊY'IO‘k.D8-,°•fâÀîf€Đ<å²qxxƠ"Gó™Đ&s€×eƯÔ3ùJ£ñ'ßi(ĵ<ÜĐlNÔÓÿ•£™… clg(hñt2¨[R»¾q-ÆÀ‡ĂÆDM½́Ê®VÎàÁønˆÔ©E×1uôºï$< 7 ¦kuó¥6”ơp̉‹_‹­vàHÔë)BÅ̃`p÷'éPµÛ·'«á^'Û­C]kÆ )îÊ8oËK_cA«dE1MŚ6à`­}ư0÷­¡®È̉ñ₫¡Ù¡nuẾ;'EËƯ¶|P₫›ÁJ¿ßXëΨƠ°jz‰ĐÛ0*;·t¨o2Ôk™ga_oã¹uÚ·íKº\½ơJ8Ë¢ü$w­›¥¾ÿ .›0—đgú18’>WnÍ»r«& 4lÙƠw04̃@œ'À¾ W8¶íjgËvƠ>‹\xùÇ 9g1"Çñ—üœ‡w¿Ç!(©"đ Ÿ/P”SÅt<¡Oµ‰Ăø#H|ªX‡'L§S} ;O(f«¦Æ=ñ†‘Oµ‘ùÍ¿,N´‰[=¡|²k–¦YƯùd›iÁ¿̃#îkó·º7S:‡hƯZ óĐQ Íè*Ù[Âb²CGc¹›ư”ôÚQ¸Á₫X–Öë­r÷&F¼Ăg‚©GP̀8‰ƒ¦ữ’ô»´tƯ©råĐzTUùù…̣täôÖ„ {W·ªqEBZtë8ÑĂáÙù¸†ÅgÛßă[ >@Ø"‘d Oñ%öáS¬à#4 ªq°Û@2‘I5ÁÍÙ¾—¢”ăynM‰Ü5íQ ư₫ñÅÀV„ÿ<}9ơ´o'”J̣ĪŸP*I”ệá…y3BÙ .}‚÷iæ°xxR̃Œh\ÊE¬HE:0¯Œ¥2F>.°Đ"ËÁctZYäcaâ˜3^L+3u†ïmG‹‹‚å]F—đ*†| X.¾á5B~‘‹d²Ù„C#O ,Æ»ëÅkßÁ„^î`¼œÁC="âG|¸¬P/±ÂágUl°¿QkùÀ3ñM‰ß€|vª*-ÏÀ¹åR¨»-¹Ei« IËƯWE>_kg«UöíªœØ‘ÀN®FĂ/Èt,$ËÇ\O~3˜O~.°hªm@ ˆ"á×{văÄ₫̃§‰FCh‡±̉ªƠ"½oƧº:¡™îú$?{ Øª&¶ª́qS`ÿÈ8₫ή˜ö"ü¨“,](l|PâÇ´₫‰Oî½ăDZe<ñ”₫J9v!Öë¤|Ơđjv4Óu÷£D«ÆÍ¹0À†ÉL‘ü)Frq÷fô1J¢đÓÈ…1_ßß\̣çô™ĐG|æCÅÿbí÷ endstream endobj 1088 0 obj << /Type /ObjStm /N 100 /First 943 /Length 1013 /Filter /FlateDecode >> stream xÚ¥VMoÛF½ëẀ1¹„ÜÙo ÚØp .ŒØ)’¸¡H+—€L •:ÿ¾ó–Jë8\ÙF/âpçÍ̀›·³Ôª:xªIƠ!ă'“³x O¼dĂ“̉ †¼Y&¥j‰ó†,G=C+‡C¬³ËÛĂû́’‚1¡j̉*LÚ ¡̉b¬,i¯`8̉™U S#\"Œ*…°©a0 02̃À°d@^±'«²+eiX bɺ(™µ!Q]ø:íE‚¼ÈE”:^!Ü(̣ƠE+ï²Ë f…áÆSĐàl" —­EKЬ±C«)rvYQŒEE­Ñ••å:·ê {îƠ ¢vF’;ƒ}É^;*&–I‹…Ÿ,e–1ïRÎP"qí÷Ö"¯l³WÂØ{©¤¤Æ.+°×YÀ ?Ú¸}*í³W^ù^Ébê\HØF](8îd68€M®Vm®%‹Í}`<¬H-$kX–ÄZ´À2d¢ ˆ×̣ăèb4j0fƠ¡c3\°3™Iåá`5åÑ/+ƒá…(é!,ClI=h0G`xeà¤{x!DÀT³ŒœồR»A—eèTÄYb-¯Ñ!‹L›Yb·€!d9*H ù9o1NŒäÆ9«åøˆVvuP³g¿t‹a₫5]í–›jƠmRû|ọ̈%UçT½é.:ªé™UÏéƠ«{ĐMß´Ăê‘à>Í—P€₫Ư7Czö: Ê럑ÛÉ”ÀM3BrĐyµXwÛĂñWËtÓM ́ˆB_wCs“ºƯpTèåưñÙỴ̈q8ëúaÄ̃](&¼#̉F€Ơ¢kWÍơ®O§»ơĐ,æÛ©X÷@́Eêov>tưăƒWëƯö¯'À‹í ơKđ̉ÄđÓæÁ*ôö)©K´ăøºi„́¡w₫úâôh?k£ưÆƠ÷ên¿ 7‹jU8O%øô‡®„–שitA±ïđö¿ô¸‡*0ă@B|x«öÙF³˜ç{‡_o¥ÊZO£ ROƒ ưèIpIè=:£pe₫t˜Ơˆ)9ê6ßözD₫Ïç›ßßçGjS?_çêî˺YÀú­Y¤vÏÛv™nÇ$£)ˆYuñm“¨:›_§YuÔµCj‡-₫íµ\ÀßͪwiÛíúEÚw¼v–ÍüuwK—µ,Èmç.ÏÁ¨!~I®^’‘+àRué2ß4d‰ª?‘\—¼‹Bín½₫üT܉p%´x"·Ô0ÂO‚`÷¦\Yỳ"ƠYß-ÎÓ@—̉êñ Uév s•4p˜ÿ­}¤‡qÿ>>Û endstream endobj 1242 0 obj << /Length 1209 /Filter /FlateDecode >> stream xÚíX[oÛ6~ϯ² ˆñ¢[=4Å6`/í÷©-Z–l ²åQJ‚₫ụ̂º8rê.Y CD“ç~<ׯ¡^ÿ¨—0/I9Iyâ廋Đ́ª‡‹÷¿\P+·ÁÅḤfyqưsy4$Y˜QoYM-×̃GÿÍVºB ιÏ^ !"ÿF¶U[Z¹)ôRøoï–ú…º¯‡`Áb– ŸŸ—¿^ü´́!D,"‘àgâủg€f1 # —[€Ä¢ÈÿR¡Ú¤’»¢ƒ#ê+ܪZüvNa]ÜW¹YÇ₫> ¾Üii{(÷ë©ÚÛ[ü¶øÂÓóJ_˜đÍm‘7NƠ˜ˆ+y·V²+ˆv8aAS’Ä)¾ë5ú¼®ô“´Ë›w¤öü} 1Vµ\ƠÁ¬%ÚBU²F)DÙ¨®Åß¹Ü£Đ §¡NUÆr‚wmµßài·l—wû¼«ư+bcÂR’Zô¢G(<ÊOb¸x¬đºÄ̀¡ŸcĐ̀Ơ•®‚¥$(úN Uû:¥̀íVO÷₫QäƯ•̃a₫A56Zª«Ö•G¦\èMtl®P´Igơ-̀̃w ú¶œïÀЦÄ]t9¡‘sO‡̃vnmmŒmñIµñt¾ ˜̀ó¢mÉ™¡tiù?âó)ŒÂËkxøu×}ùp{C/¯đ˜̉ˆ…!Ó j¦Vjb ̃¨ µV÷̉åó¥Ñ7{?ô’†ñº^8áï]Ó’^vAá>gTÖms¶yhư†§J(wÂ8[œaBë;îơº®°'Øê`¡ iW¥jv¸²)­•J}~¥Ó‘ú¥¶Pé·ªv#àϾ¯ó4!‚r/8´w¦»úÇÏ¡·†Cđ‰÷`$w',á°ª½Û‹ßæZ?Ï(‘±ÄC;³̀ŒZ=†!DB̉T¼ Q’±)Œ‘;ú’­ÏmÊJTƠ¿ “´Üum“ă¡QơúqYÙ[ợXx¦¬Êƒªö]y깑Ơ₫r\úă¹×ƒe\”Yû~l>® i¶;¸Ê±7™˜ÍÍñå‰ ¾¡tíû;tN;ù¨¿ëáX7-Î?1̀?hÎfר™Å|³$%Œ¦ˆ9á³’‹¥Œ70¦hl³Ëà˜O'ꈦù„À燥̀g‡ 9r„8âV‹@§G(óo 7ƒaX¼ 8ƠLbÎï:‚ ‰¹8̣¹´Û+Z­wmăzK7zVcFZO=¢2•ưv[ƠÜm¶«Ø›Q³×±·hjij`ù”peG؇»…¹;qvN¥›Ñû¯p¨Yhç«ôô4?€±3'úĹ?G¨³5¡NÇ„ZGúRưˆTÓïȪ_¦¿‘Yß@b¿³¦'¨µ³ü\jMç©uü%©ơ€ù»Rëó¸DO­MÆí×®/HÛZ5†áØjpÇí&é|æÿø₫!*9ó1Uû{L-{S[ơµ«÷ ©zâfÉÀxâ†ø@º3j¬Û\È” \Älô&ÎàïV‘#S©”ûûYùË7ïwü ïÛ̃ endstream endobj 1245 0 obj << /Length 1702 /Filter /FlateDecode >> stream xÚåXßoÛ6~Ï_!d/2P)"Eư*°‡¶k×öaí6ï©- Å’c –åQrÚ₫÷»ă(ÉV²,ͺC€ˆ<Ç»ÇNÂI¤“¤¡Ÿ†‰³ªÏ#ƠW5~ùñL°̃Hóẹ́́âE9"đ³ Îr=6µ,œwî³M¾ïJ½đÂ0tåă…§Tä>ÍÛjE¢ßÚüªÄ¦rß\/dê–úº*?-<ËL¹jñaùú́ù̉ºÉÈTxG{í§SéˆĐÀë̃iûA¤Èié+_,¼(–îrá ÷Ù[tăâ…“ùY,cœ8Hü8äIïö̃₫a]H?KR' R?–¸ü»SÀĐk'đĂ,u>ÅÚQJø"ƒæÖùớg̣rºnF¨ÈØR̉.̀,*ÁTæÄ lZ$·­82ơSW’IB#?L'Τ$œÔŸ̃,ŸSD¦É…¯@&[w¹)¹a4æcë₫^®:ḷ–0€(wÔ-ʽ.WyWØ—n¾[€ÚuhùB»†-åû=™È5 *6µLtÑl†Z[5;^ºYÓ·wakÇ›ñ'"¢U»¶Ó‡܃ٷj¨¡›-!¸k`ñÄm¶´G?û„ùW0·̀ B=zc+„Í*ø´›æ°e½C[R½¢%V{£½ÚVèFâv¤`b™˜ú§€@è„JƯSÂi‰c₫€{y#îQ1 ³‡₫Ѫb‚B£Œg3ˆ8qO(HEÈÜ"Ùç4äÜ`rLK»̉¦£Ú]q6}f0!F[Û U,Zvf‘Ḉi<öĂ ^F~ră% ¶ê~O°ó>ˆ‚s!a#đ'ÎÑ@€|~ó§6Íé a0¥Û:û\çuÙ•ˆ>M¢ª¥o×Oxơ–¾yQè²5£™A8 9€<¥1‡ÅÚ»¯En44ÇêP#¼/ ÚKm@mJ.GÁiƯ}¦0̀ù–SRƠesè(× (5ùöÀçg>Óù¶mfÄ{Ư ×UuÇlƒ+£83ÂêFóBũmóK†WSïó®ºÜ–S\PÏDf˜‚FîV0uˆ̣Ö­Ç•ÉY·-Ty?ưô™'Ùßáñjwđ}u4ª,Đˆ#„ c‚ßœ>›¦ív C½Æ(Amß³!Ô8”¨p¸!ªtưÂ#¤a×"-í3Hó2¹O¢bPÍ ¯wY_ákŸWº½­¨ ˜ê«J¾¶ÉVëæ<Øx† èÑ=<dĐ45J ¶JƯ¥^ç+îàG(‘èƒHwUÙ²ÚúÈTQ^WdCđA8l:­ñ¤ăù́¦.;]•×è†Ù6ˆúb †®ÊA}lbÙM Ÿ—†ƒÖñ˜˜C²Z8ü¿}rÏ|äk³-lơ‚ ¢¡–§Ÿ³Î¹±bDßYE^­đÀNĂ@Úx̀ă¾N¬¶Ö*¦qÆü8Ú₫Ü÷ņ©ñíÍkܵ4H©,Â$˜0C¡Ev>éªëJÉñˆ£®6́ EkƯÔÔbŒ‘Æ!DRÅî-đ<Ÿ˜Ơ S NAä¨PúÉ)qR‰¥1¡/“pÊbÈqÆ”J9—ƒÓv³~(•úa>„*’À¿²©6 j8e³GÆ #áG0}’<đù£11æËçO~ æ}^.—o/€í½¡̉øo7´ÎÇ'j ÷k¼Ö§‡̣#†m¼”nEÁ)üs@K½ï–"Ï“©qù¥ƒº÷wxT[o$«mÓR­Wƒ„jfä'Üñ4÷2~¼7Lx~Mî%À95†â8¥/æS-̉hºirÙ~¸ô§Oi•D¯i9}M{à‚û̀²poö®9üéÎF==£ˆM_=ë6º9\m®ez}¥ưë+u™d¿¾n`‡ÿØûăÄ¥¯{{Ưƒ½@¢çƒ2(3azóúÁđúˆ˜M€p‰oZC3yMh¸qÄĨÁaˆtÏH̀8>V²xđË>Vnwk-øªŸ#“sh¨%—1™ÄKơ@|î|RŸLoç“Ê¥ ₫ï|R|CBùuçê~´rù´rùÀ´rùïÑÊ»ƯÓ–V ́ø^ÑöG;¢•GuxÎû#˜KMvG´|+5ĂŸ₫ˬé̉>”Ăo»ö:·nt÷Ñ₫rÇèÓŒ»†ư ºîHh endstream endobj 1248 0 obj << /Length 1778 /Filter /FlateDecode >> stream xÚ½XKÛ6¾ï¯¶ˆ¤^ zHúB‚¢Ù¶Î) Å¢×jmËåƯößw†3¢%[̃u“ ØẲĂ™á¼ùQQ à/ R¤™ 3•‹Í•pÔæ6 Åo?]È7ÆYóåüêéqD"̀Eóe_Ơ¼ ̃M¾[»Ö4Ó™Rj"ŸMgZÇ“—…­Dzk‹[ƒK=ys7•ÙÄ4w•¹ŸÎd"s=‰§毯~˜{b‡±VÚÛqŸÉ ̉¡̉‰́Œ–I(bMFË0ÎâDzCÓx̣öû´…DU(ÀaX¦JyÉ0"Y/IäaÈ„¢4Lơ^Dªóñ/ox†yI…Yæ¬~÷A%́½D¨̣,¸wœ›@ë(ŒrX®ƒß¯~%ç†b ";eI–úcÅȱtåA¢ÓPdú¡cE ³0“qÿØ8B*8-Ià?œîNưåÍüɰhTj âÂ"éd¾2¸H\ ¥₫‘'˜EK„Ua‰6°t̀–èå4€p4ÙÁ¢1 \­)‰¹Ø–Ķ)°à₫!ê¶f¥ÅnGÚ†v*Öº…²tJd¨Ö~ت̃²ơ’[°¼ f́× ê%#̣®ÚÚ¶ÙoÀTĐƠÎ5-zM]ĐÖp:øº&ŸjÜư;¤¾y²¦(©sĐ·pî‘TÉ­dWơ~Í|{khf¹Ư=Ƈ½¬›–v]pÜđ´2°ˆ”ÖŸ[Ă„vK4fÿPŒ̣|`‹ä+ơÀѱÑX5Ît¬76ªc÷ WXŒDHÜbÙç,¼àZä¨r-mÏFµ½åL¯˜i_îh±ÜoÆglV̉7 £ &ÅPvàØä[úZ̃‹X\GRÑơÚÈĐÇ=íéäæºNf9FG7Cæb²+bcÜǽʹí˜_Ư¡(˦ë=ki¯,Ú‚V÷ƠzM|>FHnk,o%g[Ñ-/;ºWÆøÓuÓ~ƒ½ùɵ„i\9»¹ÛóóƠ’Bî†f£â  mïíªÉQ³T–„ÜĐpûkÔ»ª4ö +ä-̣W¥Yû5“¡ÏG“œvcđz,cq˜JÏá3=¦ z"sMq^YªDũU©B^Z!ë°æ\”½8á',¢Aœ€NMôCS Cµ*¶·®)P|I÷SpSX×-°Ñv7fS·fUÛöèlØp“°=L7I;c G»™¯Éä’iÚÊØđ‘Sô\×_^1ÏzöíÉơôùC‚;g|O0âù…ü‚ƒçTIøE‘„\làZ &ơ®X,ă.5`g5@Ê£‹K,´–æ®rêÁùâ!ÿ1¶w˲¬¸1mS‚%IRæGBskº «á»®#tÓÓ÷ ë[Ô[Ï÷¾kñÅÊøK²ÿĐÄ=¶¾^—mµ1ơ~˜Vp 5Y–¿fk§Æ‘¾ñŒ´è´đ€A¡ØÈ3Êt%t¢Ơz­˜ÄơĂÚóàØ1Ö\¬míϰç¹ôfR29¬©Àd̉+0øqßTmkx‡æ,‚N°Z6ơ†VƯ€qDØÇ¢‡X¢s$×ô JÑ0 T. ĐÊJÑ©)  „b”¡ËZÄ¡NR§*Ñ́ôÁæG̀Hrx„d_ÅT…)Œû½x`›Ñ¡óÈ:¨ׂöø̣Ñ©¬±\ú#Ơ}W¬›đ#F©¯!¾đ .4w;sY!¸s‹um Ăă`î8úpèÄ>Í“̀t˜æÜ(‡¤ä_’'™/*rª¤foœ)£ÁŸEÀ/€²ƯÅî³á —c° †Ậ¯\yxåº÷ñÍTEî® ûћׇfơfăîê-Ä«́‚ xoU»È3&©­ơ.2Ư]¬ºY’qđâOw™´ Ål÷jêưíêø9„G?ö:Æ/äu&³ëå¾ñ¾÷°ŸÏyï™t6%zx´ '±‰€RXºStÄú€é₫©w̃Z`d[©̣³ˆä¹î=rđ‡u–´,ÏfzÜ“îÑ—("¤Ć§¨uöh@êaØ£/„=úÂ::²íB”3ÿ,”#ÇQÎü+¡œä̀ÿ_óßo£Èé?cÿ}ˆAÎđ›ĂaÛ¿÷º«½_J£#lËñ+“…!ܵjỗ‚°KaÑ~ÁOü°…ÿ­éèË*èö6îơnYâà.°X®âE…_& «(˜um ’‚Ë–Ïë̀ơ_2ÜI1TÛ‹B÷¸‡gå…8æ †yṛÚc ®Åú†Ú(êp¿#j̃ø endstream endobj 1252 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚKO„0…÷ü.ÛEk‰›1jâÆÄÔ•º(¥g Œÿ̃2 ÎlL“>NÎ=ùNâq ”K”ŌʑÿHøQík—Ç»D,>tăÜÙäâVk$8+x!}ÛFÙ =ăëÆ}¡'T)…å%¡iªñÎ ­éipu˜¯)~˜ˆ48ôS¾•™,Rœ‘W{ŸÜØ_-5Ó©ú'ïê>‡Î¶Đ‚sfP.dTpO®#ó8¾‚£®záq3Ôiq*M̀ "cBa›%«0µ~iéƯÄ2vŒuáá»Ă*p”ó7|¯zp}»¯á56KÈ!k߃A˜ˆÎptº² lÁûSñœî å†ơ—?¸{$ endstream endobj 1256 0 obj << /Length 888 /Filter /FlateDecode >> stream xÚíWMoÓ0¾÷Wä6G"&₫$. †à̉èqHw‹&U öïy;m’…n Äv@=¤N_?ï×ó>v‰‡x’zR1¬˜ổí"́̃ÖWưrñ~Aœ]†ÁẠ̀Írṇ̃\„8câ-× !U|À[f̃W$ưoË‹wË  Îèµ·¾ăZQHL‰àƵɂF84+ă•ùˆ:÷cÚ2ṃªô&ºĐk]ë2Ơ&¬i¡PÀT‚,¯5lb ­Ä̃,9JÛ |ªPSÜZ‹Ä¬n|!P’ɪpó̉>‹ÄQSùàUÅ&ó›¤v¶™̃§u¾‚ß̉™}çVEeà¿c³ÉœcÆ#ÚǬ°ˆ”K“:Eo«í¶OÊÀĐ!‡Ă!d̃ƒDXö=æ2$¢Ư_çå®m\É" qpÏ dÎưºGá°¾‘‚†Å°§³½ Eè¬ä’cÊio”é›9$¢°¢C$2×Ï@JLˆôH•¸¦›']ÉË}S·>A[? ȵvß·Đ$c»ÑB5˜®YB†…r%ü`¶9COHÄŸ$8L™ê liU–:m,;¸Ù§=UíˆX×ÀE‰/«uO.c:xà\Ùđ#ëđsÛ â'âÿT•ư,É»f±+ÇíâL}ơj– ¬ø £íª. <vbCé¸ê†¸tD\‹đPæ­Ç„“óXü-ê²{™ jÇb₫G̀uÉü§î“P·Óßc.³̀­u’­àä`­@ùx¦f±™cÜ„ÅỶ$sdg€®̀|í›sµwN̉ÍScà åá<{¤\‘Â%–RXÿl2»gôb†P,Ạ̈hnwz.,¹HîƠG˜E±+±Ö&å₫̉–¡¨@G˜¦ÔŒÔf2R¦¦ñº®¶ƒỪ ÊÖ)ÉhXO(GôÏ•cÆÇA ˆ€á Dcr¹ƯÙ»ỐÛºưV;s]J çÖ• ´w„f_UöÙ÷bh856dËô:i WƠ³Ö6ªQgÇO”ÂvBßNVù8:ă2ó¡^SNtỲÈbàö=ѹÎ핾†ĂN›Ă./Y‘÷₫weq€û´7X*¸xÄ#I<üă¹û]ÿH‹6ËË+Ga]oó2íàÍ™Úêçuapÿ%Ÿ endstream endobj 1261 0 obj << /Length 1095 /Filter /FlateDecode >> stream xÚƯXMoă6½çWèEV\ñK¤‚vM-̉C ́è¡Ûƒ"Ó±°¶dÈr‚üûHêƒ c;Ûm»(|°$ß ß¼Œƒ>8$’"IEPl/ư´¹̀ÅÇŸ/°µ‹Á0X^-.̃~à<À Ê’ ‹Ơj± ₫¯×ù®UMSJCzÅŒñđC$Yx¨¶¬«î~T+Ơ¨ªPQLO³PF.~¹¸Y ¾9áˆ3zf ½ơ³h% 0E „ÛE+S„`’%œ™ˆ;´»C»ïüĂæ²éæ’ Æ¥ÔZ.ó6·f„!É2°ÖV±ÙûûO×·°9̃{½Xï½Qù̉ˆ)Llqb,IRƒöI)³>ß́ëKŸwƧ̃?'˜öëZo {—ƒ8MPB ±„¢Lr³Œ"Œxó”„MÙª»²(ï65xÇaÑƯ|±̃Óc”qN,E€“Jn¿Ö>M¦ÑJ&Çhyb­Ä•!ÂHo´T>ÏÀ’$Ă¾ßø`0AœÓgLŸ̉Á@÷ë€Ú§̣í'ˆ`<Ùöå,ÆYhÚå˜çØXÿIvÚŒ›¯Û››#&Aæa—Đ–Î|ƯÍóS½2ÖˇƒæÚÚÁ,«}Û¶ @DØZª‡²Đ{̉ºOaV÷Gœ­êf›·­ZZŸÖ!xØ÷¨ HVơù₫̉çá‡1/#Iê.,“?úhäHÑ[¼÷aH„å ¤w^H3ƒ'ÖæÊ‡"¦~ °̃æÚ"Å ×w^Y¤P…˜»Ü<®¡S^ú)́_ÊoÊ#¥;›·5­ŒĂVëC?7½Ÿ…E­jó²*«{cÜ®­´7ªºoׯĐ蕆»¼i}ƯơùÛ<#…Zƒ­@Œ0—î¿/ỎHỎ(4â<uù Î§ £‡Í´@·è Zµ÷ñL%JÇ>ø"̣¤ÈåœgÁQB_KóWÖ£Ö«²Ê›§ù|Œ¹½̀wL‚2á’·Ơ¹“Âpd¹ƒFẠ̀lP€ Wª[èІç>b»ÜáñU3ÉƯ@Ç ÇĂ^UK¿ë~4™¹nµ²v¦̣½Ó‰9çÜ8́J>Aưâç̀̉–ï½y²œD¹3?’©_ëJù†±ä?Ẳɶ)‡èNN]£­;‘À™’ĂÔ±‰‹₫s—’¸øé!)‘ˆeLJ¤qâ0̉aGÎFmVVÅæ°{ªj¶Pmm[çCÄ9$û |¹K₫_máåW•¾µÀü]̉6†WV=¯úÄ¿^}bR}ă‹+̣Yơ½ô^A1¢ăhơSÔ½¤>vêB0Đ;ÿV/Gôt¥0E½Ưæ•7( Ñ3U€ Sêëắm†ơZFklpllú MĐ́bƠÔ[ÊT¸~`äñ::V»́»­]'³)A˜¤GË—¹ëg²·GÊơ»ùä+k¿ïÂ7“ÎƠƯ£₫¦¿—ä endstream endobj 1264 0 obj << /Length 1432 /Filter /FlateDecode >> stream xÚµXKoÜ6¾ûW,z̉+>ô ĐKÓ8H)íÁñAÖr½LdIƠĂvĐ?ß!‡̉2m/A"J¿ùføq6tÁºIÙ&Í8Éxº)ïÎ"óµ»ƯààÓû3jíB0 –?_ưxÇ‘<Êéær¿tu¹Û\oE;ÈnrÎ₫f ÛLc]ª©ơŒ>ɽ́d]ÊmÈ̉8Ƀ|{}ùëÙ»Ëyï˜Å$üD “ơ´ÛPA¸HØ„–%$¢å„mĂ8aÁ{YË®¨4\ĂI!ê5Ñ&„%YÏKÅEªî‡î «—ÅɆR’Ç1›–q’ä—­l“hIb˃%ÆôsGđ—ú¼†Ö4€4¦ÿÉ·µJ—~aÀ5ÚCªêâNúÜÅa”.ÜùaR'çÿ³¹ùâóD3’±ÜƒĐ©Û0H&¨Kä/ªo«b˲à–©Ú̉@£ïd½ei0`]ƒxZ*œä9Cwêvz»{¾Ü iJ.|„»@đ(§pB°wÓĐà× ßâ4&Å>hA3ć'´»,ÓƠÜè*¾ø@Ñœˆ”­@M diiB\q“…¦p#´l†ĐyÈrÂÓ‰Ê=×Ö¥ª[p8ö­ÇÙ¶ktô÷j'wç–0;H/YăÁƒª*/oÀV½³!wúÙƯ+ù€Ó3 cØ·(uh_·~q+Ư•ĐwÆrBÙü6‹º‰_¨›M-}C$7Œ–%¯¢™5¬oƠsh^áZ£É–h0=>ƯªkU°àá J₫ÚØëºá1¥É@pY¾ªÍµˆYO“¥ [¶Ñ˜À؆gVȆ1nQ¥Ààûvºÿ1Ó‚kY©ÇÜB²Ơôé™¶3'Mg]d O 6;öcú yÔ£~h:‰fÛ¥ØZf̀s²À›aœ;‚lûY°́To¿²½ă± Ä>T>í ơ×ÛjUˆ§Sê¬OáưƯcq×V^}à c,uÉ_µ닦/‹ªè°“Đ ]£¦O¿Â ;ªVơ-¾Øz°W²ÚơoŒ;Øf̀üÊå‘ơyÙÀ×<₫ 7¨a|ÑrEDÈ‡Ă®ù¨È,4åPÜËE§£ïáP_ÿæÚ诺}~»?à#øaêkúi 0,JüÎwf®è9]5¨c«ưÀ¹vº£¨*YùökîZ[Ѷzí±®ưP¶ÏÆ®á¸kưp“•]3Ü•ÏøL]ÛûGEéôß/ÿV‘ß endstream endobj 1267 0 obj << /Length 1572 /Filter /FlateDecode >> stream xÚƯY[oÛ6~ϯđËPˆXñ.u°¶h»ÚµöæA±äD-i²Ü,ûï;I™t˜Ús̉m(D²Dóñœï\HáIx"ÉD¦¥TNæ«“dxÚ]NôÍûW'ØŒ‹a`́Œ|6;yü’ó NP–dx2[¸¢fÅä,z~•·}ÙMcJiDŸLcÆxôr²hSÏûª©Ơ½/eWÖór™ˆ,ÂÉô|öóɋ٨œ8£"µ£oĂ.\L%JSÀLJ8Ó˜ÿRª¿„ǘ¢†ª‘±àĂȘ ơH¢Ó˜ uåºY~R•Wͺ×"|ÛP"‘ñIL`7:{ÓäE~±,µ‰À4Ôæ\ r‚1Ê8'+%Ñóë|UeÂG1¢×Œúaă„'¥ƒP$.ÂŒ"J˜ôf„ 0DÀ²fĐ]¢À₫ Ñ…C&! C‚¿À̉˜j¥»9 aˆH±ÏfæqÔiH&ˆóqñyQ€E×!YŒ¢Œ˜Î§‘‡ºÆ TÊCü@̣ƒØçL9Æ øaˆÙlúư6~p^́qOwe¿éê₫¦-CÈAR°}æI’¢ŒßÂïuÊ iTê,˜kS×e¯^«M÷»~7¬G¿V́îÎ̀34ö#EzR¶saN=ÅQáϤ½dÈVœ›Ø|]·›̣̃=s—±D‚²[æ÷̃ ‹X£úɬƯZ^¿ ¬qƯwU}é®—Ù¬¬‰Bc£Ús“ |˜$y²ÓúKFeá‚££sôîP¯Ezê5·æÁă7-”?ņ"‰ăD”ºGZ³ơûeÙ‡@Æ|ă“́̀0,…‹ÇŒ·›₫@jüÇ6÷s¶_ 3¨™Ù”L' .F£í`1ÂƯJ·M‘~2ÎÀX»†¸ ÄHµi’ Ú&¸£V­]jƠUë…aX?N$ÂÛÖă₫Fʆ¸HèÜ2aú2ÓT½ø3_µK§Æ;,KQêóñ»ïtqb@Ư˜bTè_U«¯Ú́ê.¯Í«ÑêG³Đ×ëëktYoPÓ]*ưûæÆÄ¢3}Û8ʵ»ƠUí>&˜;rƠOUj¾·  {¥Àóđŕ@ëøûˆ§ö-æFŒ<#ưh\+¶ươ‡̉0=_®›'!Ê0è”Ø²ư¼5ynS´Nîbˆ2¡»Ñ¡ 1(ăv“BmÿêƯëgwUA Áăx„ơŒU%ѼϧpÑư¿Ư¹ü1nG°Y †-ô(°9;O&¼“#Ú®‡¡+hbNán9ùp̣«̃²øX°Hăƒ(jsÚe[]<^̀—Í:œYS‰¨oăávt¦Ç«–å½ÚE1'«¬êí”û]X~ïÄ¡çüí6‹OÁ†˜C²½]X ‰UúƠà¹gÍ\¥ïFơEu9Üo-c‹ë@á®(?Wó2˜ÿ`§(8ÙBVL‰>³– ç~)Uô"GÑ‹½dö ôQ4M]z5G”₫úÿG±¦µ¨|^0¯ ´oøèG°˜KîˆôaBÆ‘b¬dÅfµº Iơ7éẉC£’•ÇÜ·¦Ö½,æM ´5–†ßeáj(˲/RVÏ eÍÉ´³«Êªßtp€3”ùåÖg_åú¢¬0túíâlK x`W«¶kÔÀqk¤Ä±¹‡"ă #^­j󾺨–Uou8íí/OƠ‰Ó́ÍÓgá(dKj‚Plƒ„*ü9¤µB%Hæa  _ØÀoôñGz¬öˆiÀælk|ă h‚ZĂ·ßVÍ0£n̉¨*K£‡Ö7ơÜöT¹©ü endstream endobj 1270 0 obj << /Length 1723 /Filter /FlateDecode >> stream xÚíZYoÛF~÷¯à#„›½I(P$m‚EÇ@£ ©•­T]’rĐ₫úÎ’Ëc©•©Ë5’dAZÎ}|3+âaø#^H½0b(b¡—.Ïpơi~ăƠoÎßs.€ƒAïä닳—o…đF1‰w1듺˜z—₫›Ûä®Tù$`Œù́Ơ$à\øo'÷׫´œg+ư ÷ÏƠLåj•ªI@C,cŸÉƠŇ³/Zæ‚ $8ÛQ̉æô†¸ơCämÄ¥aÁkqbˆO!©ÿ}¢Q?-“ ü»Ÿ0â«F¦¿ZFD1L**Œ Íæ̣ {Sø̣ƒ‡‘v_ª£K#N"x·đ>ưæ†È K ›»ùơËY®’©æ=´6BÄbé”"*dưÈ%˜—ơÍËü·ó…ºª ÈĐ#ÅBPM `Ú<\‚XƠ³ÓÔ­É₫9FaÍ©ï&Ú¾~O,‰ûbñNÇÍéOX`o(8ÈÊ®?»(‘E´O‰¸Í€Á àl0&ä[0ƒÍ×6Ă B‘-b₫r‰YA°µ'§U0×ö|6gÏœ6!Ûœ;ºËU:/´ ‰x9‡„P¤0ß'Øm¡‡̃¹t‰- GưW©/Tߢ“fëU9Wu ŒÅƒ„ç;W?tÏx¨ø"„\\mQ·:)†RN¾am%6'T/‹'¥IâmúÙ¼·JÀÊqd̀sP¤0§c‹&WÆ~Ô`đ+å,Ï–uȼûơưë3ÍWE™¯—j5¡‘_º8"DÄ@<.icoüÏî°E¼6°1›ƠÜO€i²X+#W™ƠŸëAỴ*.~P³d½(_ƠŸŒ{n³ä¤ZùƒÚl‹É5œ›G-{¾´ B¥Æi±mi}×YüF”µ¹dk^ḱb$́2ËÊ@›ºDiC°¢V+rg Ÿt5 ¨dyÍv©"¹1n´±+D~ˆâˆTPTôá´8N WÀöpZ“̉Mº§‹4YÍ₫<«b¼(7¥¯'Ö$¥øñôÓ›áH8Ẹ̈eR:;„Ờ¶Z”Æ(Œé³E};́Èq¨FalaçX¨¶ÅwÚ„́±ÁôÖP€bIIüŒ¦ŸÀEă„F°t|³£¯L“>®Ü¼ e°»áÁÁôŒ9U‡Éø‰Q5qTQâ ̉–i•,ơÙWa€^:ÿ„  í`Yèx7ü^YmG ïÔâY3ưßeÑeyPæĐ 9? PÖ¤ˆ°€̣—|^ªå‡KrŸƠ`íU€œlÍĂÆqƯÍÁ€è¯ÙD{oN¾¥ú½¤'rß´½—Ùôdϱ½WlÛÔªØOå¹Ñª(.*el»îwí9í÷ÂđN×b\X¶IZïæö]W‰„ph]¹ÛZ¶:eí"ûÓâ"áR7&¿kŒ( –¨ – §LƠè„»\/₫^¥NÀBjp` kÀ’.̣©ºŸÄŸ§n>&×Oj-·Ó]², B ² ¦ÓjebºP‰A…i¶\&ÍçM‚¼é¾ï"ÖÎạ̈3~üùc ª®ùĂoT‡FŒîA$‚qI ¼ÿS–L“ë…2ïÅ–ơ—¡‚;xºÓ243Ü;½Û²Ø*ÎƠX‡}ÑæS¡á¬î’¿Oé…‹ˆƯ ÆÅ)çK•­K§b ÅL äŒ́@*ï)a„ÜüY)đ‹‘LrW>0Á]EµÊgIªv‰mË¢vlA’­1“Y·ªé8=Fơwí|VóiC›S‚ÀP¶4²Mi—l]ø‚4´́¡ØÜb½75>[ÎËR™‚1­¯µw_׋¬̉#Ơ*ư ŒˆcªM²XTºy‘Îê«·ªsŒưÊ»Ơ“Å-> stream xÚƯY[oܶ~÷¯Đ£Ȫâ,P HĐ)ÎC›¸íC²–¶Uh%I›Ôÿ¾Ă‹.”éƯuâ¶h KIäp8—Q’Ă?”œI2IDRî/rû¶»IÜàÍwÈÏÛÂÄíbæËË‹/¾e,Ay¦r…’Ë륨Ë]̣.}u[Ü ºÛl !)ùr³¥”¥ßn$MM9Tmc¾Đô¾ÖnJ½Ùb‘s•"¼yùưÅ7—Óæ ³ŒQr¦¦ắêJœ ’å ï¨.æYΨS—d$CùfË8NoQ‰ÿO’e™¤Ê.#”¹ï̃çÉ>~ŸäùíÔ}B3$ŒêäíűƯCV2T¡ÓÅÎl»¶,*#J$[L3&¼yßư¯-vÅU­Á°d4́{/„'e1l„l “W ´rëƯ$.–“x†ǵ¡ˆIû¢|ơ"&áŒ12N)ÛC3Ä$”°Ëù’t[Åä ™I¬ÆIï7&̉¯6[”³Ü:ó·Ù´<_VÛ1W₫ ócJĐ ÓI‡18¢faO8LS(đèƒb±Å„f9†ˆ€‚Pr³ß˜3Ú`¸îÚ½Ë.«¬}W5,SHÈë¢Ô™—ª–Rs'́Öç £‚[N‡Ø̉û¡°Ilvm¯c̣9ÎDăẬ]¦%„ü|0ÿé‡)‡sËiÂÊ(˜{•rTLGÀn$̀¸pwœ‹LQdEaŒÎ8ă˜e]ô}Ôd[DÁa,ôC“¨ ÷ÄÊhà‘öǽWÖ#Z‚ứï•ùt?è̃™uhƯëbô₫npî%uà¬́ê;'ÙMzíƒàFwö<ÉÖé8₫̣Ọ̈̀1$`x€,NÁOôH`ALaÈ)¼ălÆ@“†6ô­ưmQ×nØéáĐ5nlỌÀxđÁ_ÈÀxF̀¡,uß_êú~”f-£ª‰9 X´1k¼˜wÁ$b†‘Âo¹°¶{Q4~ĂáV;óàààÈ-_{ưVï{]»é§d(¬Dx½×¡-© T‡Êă°A©tÛ]gSó̃K4ø8`¡9t²2¿jvUY ă1ƘÄ0a*À‡Å\”í₫®ÖƒvbC₫Üb€[ʼnåD ˆ9s8:‡Ă9 &ÏBá<Ç™"Êi0T{Ư†Ó,.Ÿ‡Å-¹›†t"!0úgøíˆZ`°S4‡Îr)ƒä8m°P¥µÁ¢uH¨wP89„́üDˆ‚BË>Jú (VdH6oµåÀCưÑ TÚvîÅÍøEÿQơCƠÜø×¾"PiÉî²̃îûx`ûpWtÅRØbK™̣ÔkƒY6Œ§E}đߪ>x]íÜë±(‘©µ”-7É ă_Vœ0 a đ Å Ă(“9ư+““ø,,1 L‡̉ŸM~®E¾´ÀàAû¸×EÓ»a£™:7ÁïóÂ}4˜l̃.æ·Ùë²µ´ß?bµNQç˽#P¯uJ&{íâ»^¿tßy¯öÚóÄ5Ä.©®†}ëëSD»D¢éơ¡ƒLöÏ;=UƯyºÍ×Ñø‚!Q( Ü@đSƠ¹M-óÛî+¨w`^¬˜­&́ë8ça AÅiB !!ŸS²a ¬k%ƒ£̀5›QÄ×lfhk6‹4ö±á]{éùªh"u5SÊØ²¿:_¨_ÇùÖ Dú¾,èê}ïDÍOn!8À¥Àá̉ |'́>ù>  ø„̣Çú~LI¿!ñY4 u…( îm¦JÑH#fh(DƠsˆ®qo­̀ z`>ËßESm'wư,ÍÑ öî“h&zư·¼§DaªûÎNN¥đñú¦r2iÿÈÓíÙ½oQÇv¥×Ư‡ªÔÑ&0FÎHơ ́E›é́w7×m<¯X_ÊA¢F†½Ư˜ÛĐ“&??yƒ½>–)9 ˜Æ«‹¬KW8W A– ·3ÿ@>LÎ¥đ—NîÍK2ơܶ£hô­ẃkü* %üS*5MÏüớ×­e3SvÂχ A±²q•#s³ÍrơyM—p]m$a䣫Âå×eƯöñ> Z¢‘Q¡€8›Q—j…iÉ9ûcW ­`ư•QÎÇ‘ñ¼¿®oí́½ÿf<«4Ç«qùŸ5´̀Å endstream endobj 1277 0 obj << /Length 1443 /Filter /FlateDecode >> stream xÚíYKoÛF¾ûWđHáfßK(Đ$­ƒM‹ºzp} ¥•Í@Urà₫úỊ̂%.µ2%Yu‹ ÈA25œùö›÷†x₫OQOE ELyÓ́WO‹;¯₫rơá‚4r!†=Éw“‹×—Bx£ÇÄ›̀ûª&3ïÚŸ¬J]!c̀go‚sá_÷7Ëi™æKó ÷¯ô\z9ƠAH–±OXp3ùtñă¤3.¨@‚³‘¶̉;p#ê†0àmáR‰°à5\†8¢A($ơ¿Ïơ§eÀÇCÀˆ¯[Lv†ˆe˜TZÆ̀ơ öfđă'#æ¾V¢™Ç'|[x¿]üêCd„@…(¥Ó×ó|PÀü̉Ø2N#…X,½R¤ˆ¨_»YŸbæ_¦ }S+Ê#ÅBP£ d†".Zơn¡×ÙB  Å>@kQIÜGÅcÄ¢¸•₫ ́2 dsÚ å·_\H₫ë)"`Y‰J&áHỈÊÏ6Yöè̉ÊࣖZ·!¡1=!¸©åöđÀëØô}ưe„ĺ‰¿ÔƠ÷2 ªµæØ:Aaḯp*áqƒhdC"ŒiưÆä>ḿO7¤N@•_.À̃cQí¯Iưaˆ0"ơŸs+4ʼ₫L3ƒzJÜ?朕<[%ez›.̉̉ }0öEĽOÛeÚ&\Å醼p›å®6+à½Đå¦h¯Ûº.§ª.§vºÜmu=U¶MΰPê%¿—êuqJ—!¦̃y.cTa*·]æN—/̉bLMK g(fbØ`:\ƒ ˆ+rܧ|Ƶlêªóu…yª³ñêl4°ÙV\Í¥ọ́f+JÈøå· ˆ³ÁơÇ8i]eîu`ÆR“ˆeÚf]›Œæ8{*ŸøøÄ¼åkpu"]l… èIơŸL D‡zIa‘ë¸É«Öä?|4×á»ùC²óđ!b5L®º́g°Ú0;ûmă Ä(b’Ÿ¯ƒ9]$ë=+X@Ï„s@|Ómp4£ys™¿¯ä“…Ë$Ó¶‡wuẢ¡–¥¿7(²† endstream endobj 1280 0 obj << /Length 1606 /Filter /FlateDecode >> stream xÚíXYoÛF~÷¯à›)À\ï½d€=P ¤ôÁ1 ZÇJeQ%)ù÷™½xyå(1Ч€I‘³sí̀7ß’$₫H¢h¢r†r¦’ê₫Û§ÍÇÄƯ¼ÿí„x¹ ³‘äÏË“ó !‚Q ’,oǪ–«ä*ưå®ÜuºYdŒ±”½Zdœ‹ôb‘ót¿­ºu½5oxú^ßêFo+½È¨Â²H _\/ßœüº́ *à́HOƒôws†0økÜÍ%" tR‰°àÎåwûn·ïZcN2¢d^̣¯;½ơbÅXŒ”“¤­Ô®©wVê¦[ÀåsL37î’°äÑÈ•­ËMkV«TWë˜p½:sƯí›­Klw§ƯÍĂBˆ´ǗưÏú6¼/;·j×,H:÷'g)2NA¶bK)"ÂùRƒ̣æqƯz•ƒY>1+­Yïr°[n6îfœƒµ“b}€¥ûÙv;åù©YêERIçƠ¥ÖÁD[¿:Ñœ!£?ÖÖ|Ơ•&äóO‡ û·/¢PRR”ÓÂÍƠ5NVđ̣M‚WÉ£•¼O¢ ‡“Mrỵg¬ˆH«I¾^Ö´:ouçă›VbF03 2(\†™[ÀGr‘ ImŒÚạ̀°`$€̀2…˜`…8â¶FGL="2G\XUÔÄ4 –oCí̉€±øêÂרƠYz±̃èk¯@&„ Bj3ÀL«r¶̀Ø1}œ~À»R@›1pÙ‹×7ŸbZInw̉ ÅôÀ­bdÜ®P¥ŸcÊF”g•I( $l+:)##Åg™¿ÔƯny€55‚µü W< ߘN?é*̃úxÚô¯·£ñS<3~‚̃X¤´ê³‘y¶mWÚ!ëưŒØ¼"£ 8 5 (À8˜·ˆǽQsbb f5a÷˜Đd¢w´Ú”m‹bÁr¨ŒéPû™́s¸-ïơtŸŸêæ©W‘1Œdö7wwûΰSƠyWé0{ÛÚ]ïP¨ûÖ×đSs¥àHÑ¡áÂl"äĐ½®̀<×´iñ“vJPÀ.1åÿ»d¬@¨̃ËÙ%c9*¨¸ÙÇ£Ø%Ø¥ṛ́Æ2‘#Yˆ§û½.WåÍÆ§hLG®că; ZđÏ'óÛNæ¾ôX€ËÂÓ1ó6ăxØƠA%G”÷â*ÊwăĂA­nº¿wewÓ%$âyQ¶5QvSBà0 ¾Á£Đ;±Ø J1ógF2A•ú:ƠÉáŒ!Ød<¾óÀ¸ơèzkÎó·e¥ŸEF~,—ñ-́ ÂDÚĂD¦HIùvA  ;U¸ƒ³> stream xÚƯYßoÛ6~Ï_¡Gˆ8ñ75`/+֡Űam†=¤Á Øtb@–=YZÖÿ~w$%‹’8‰»CJ&OÇăÇ»ï;)4ÉáM4K´áÄp̀×g¹mnóáÇ3́20̀F–ß_œ}óVÊ„æ¤È \,Ç®.Éeúæ¶Ü¶¶™eœó”;Ë„éÛ™iWÏÛƠ¦Æ‘~°KÛØzngÓ¹*R*gWïÏ~¸—L)ø‘‘öÖ÷Â5,¡œäo.S$—‡ˉ f–IÅ̉›÷!ü9ø¥̀¥´{ˆ ‰^/¯̣d“Hđ~çL׉ ‚¸«’g¿N­M¹ ”ê8€r±hpÙC\Y¡ˆÔ&É' ‡Đø̣§M¹(¯+ëáXyëUp¢JI!%C'—~!!*÷å†2"%ïM0$»ÛME%8)¸EE'Á„N2›Ê£±C:Äjt0Ñî8%Ü |7Ë(@ơ(²2£/C6ö„Ẹ̀§ÀÈ(DkàđÆmëq¨í¯ÀM¨Ñ›~Æ₫½Úµ«úÆOcnxW•3f̉¿đ?ëçö¯Ơ<àÎøHâ„Ï]ö…á]½íÚpȲG vTÅÅaZEûr&B™_~UïÚ²‡À6Ë)÷jhÿàǤóv¼«ûe_h(Q@LDi~Xök}ƠsÂ4«>^åq7Oïpt^•®±K8X¨aK(v̀ ©CÇt8a¦ü ëư ĂưpÂ0Ưûu€°»¶hüy‹́Ư?󮯱Ö̃؆ íóôâvÊÅ*\·°=»đ«:¸½ δwI ?iî¯Ơ׸s‘ºZƒ²ơ{‹ ¸^µ;Ÿ.^È ïóµ¹éÖÖ‡zD̉₫̉µGfíƒD®ˆbŒ½Qé»ÉD¥°.'Yñ̃y{®̃–M¹¶^tÁ·Ă®›ơªmíâÎ"Ï8=%s(CĐ\¥ˆú™ùÇ$%@¸Đ•¤l¿$>ÇY.ŒƯmYU₫¶±m×Ô₫~̃5M8è³Ô¨{<C!K]0( ˈô㦠vLa'ăĂÆf 8¢¬€+?I3€¾¸f}Éovö_íF+ÆR£à¹½=&ZüÑÚ·ª–ΡNh\Ço\tnw¡€R…£™fYT/ü\c+[öO”₫̣)§¢„k7oVÛvÓüOơJHJ( øz½‡Ô ơê°Öz½âÚ…7A­̣€̃Ôö95Œjñpsè¾!j(:döº"”À¶ĐƠ°­Æ–‹É6aÀL'-áË©¢Tpă8,JÈœ OđºDsơŒ&}¾éêö醸j†¯bQ_¼G$&9+̣̀ÆQORটΟÇDơ·èpÙlÖÇvĐ'!!₫Ơ‘+ ₫Sp:RZ}Á¹r â^èÈj́»5îüÚaÑâđ &‡Qlˆ[» ưæ&ˆ´`ëmxẶƒÂSDôô¾R$j§§Èχùp³ú£ºÎ\0ơPŸĂ‰Îi Ïº|M7H™&¾Æ0n`lD‘ûnĂƯ æè»Av¢FˆŒPwnºù¾eWUŸ{oµđ¯iLI´Qc’óÍçT×MÇƯNÖ“_̉u#8ƒ-‹E‘‡”q˜0·v½³•¯­]_§S!:³ zƠ>kí¹µ »•ËăvFSă—-›ÆƠôgT‡ÄºbEï«,=BeY΀è)TI¡'ƒ»fƠÚª́ăŸ‚êI͉e¬w£à/‡ï2ôe=ơ+oŸ'qH® O‹01Ưù۫ƒƠ-ñ\ø áèC>t:!üúºqäQx¿;¢'Vˆ/¡„GđHqŸ˜M X `FsKâơØk¥µuœ7ĂÇçuNYöe’ø›ÿ@‘è¥Ê:]]vSˆơ¶²ÈçhΧÙû *eˆ–̣5úÉØKt$Ùˆúöê‰Aơİ{ơÄa#2ªøÚÉ(Zàé¡Á5Ny-ÂŸĂ¡ Mƒ7 ḰºªÎ,)\ưtê †\%=‚ÿgyLÆ endstream endobj 1286 0 obj << /Length 1762 /Filter /FlateDecode >> stream xÚíYIoÛF¾ûWđf '³“  mÓ.u ääÀˆc›D¹$e#ÿ¾o.#lÙV  X9|ụ̂½'aø#QJ£4c(ci4_as·¹Œ́ÅÙÛ#âÎ%p0™œüơüèù!"‚Qs_LI—ѧø·«âºSÍ,aŒǺÅ,á\Äof×ơ¼«Vµ~Âă3u¡UÏƠ,¡)–yLä́ËùG¿Ÿ̀Hp¶§¤ưé-q3—´—J„·â2$f‰4~7KH¼áH\~]·Zû.CtƠïâ(WS†W±/¿̉/̉x̃3ø¸™Ơ«ó÷ #‘@ “Hæ9’Œj ?}ÁQ ÿˆ0ÀíÖ]Fq’ÁƠ"úpôç¨Ç( ‘âÂbœX–£øÏ/UgUđ½E³±\‚" Q–Ù÷>{ØÔ=,~S-ÔK@¦!(ÂØ/aÚ¼\‚læƯ¶kÖó•œä åLôç^‚y±Àñ —ÄS¹à0»ºĂŸádˆ9G”Ó₫P©nB”H†2O(‘ R†RF ˜”̣t;\TjQ†̀ÀR$Evp3°-3øl}3< ‘! 1Đ¹nVת龇ÄQBî³iBEœqߨoAScÊîJÙÔלtÖÇÀ®R­½¹º°§t Ó̀¦ ¹±úªS,₫KÍ;´+)!ụ̂sR_¯;—½"Ÿ ø‚ñM»ùAL^8U+CU·]aj•5@^RD²ÁFV ]àăFÿ Ô1ÄFI Î’b³đt(¬)óËÏb$äµ&%ÙXzS4åj̀!óEѶ(¤¸5G9äçVçÄL;Q«÷=ÈB—d²àºX*ßçÛ´ ƒÎNÅ„I$3W¾N×ƯÄç⟼RuHEFPF²i&:6Qûơ¥ưĐùÑ€ơ§gÉ´ÏëC¿¼mïƒÄï@ă[óäôl$³̉½ÿîº$₫fÏ»íó÷§çöKQĂÁĐ(a¤œư@¤<_Ơ5 uUZ¤° ú̃îHHIÏđwÅ̀¾Y¾!ÃU‚̉^é( Ă\GÍgî ®@“ÜỖxÇè­_²HÎIàBv*ԀƆP ‰eùxRyåg3#ơbÁ—J‡Ô…r|<©t%30­9)ƒ£K¹·ZU—SA¹‰v¬ÓYÇ6̉;%¿VÅzÑM3‰Øb]·}$VáÖ+÷Fëđm̉ẁVhƯùóÆ™3ö`?uøê:S˜ĂnR˜FëÆô¬sIépSÁƠ\_©₫N-P{G¡đ ÛGb„)ƯF¿́1è—âÔ`“ _M 罘±í½ÂÛl= =uE3n·QÊC–C^̃̉ovcTXPP)Ÿ€Qÿ?~:įÖup»è›u·«x†¨‡&úéûé.³î=Dœ÷Ï₫±×"zb«7à¡‘D£‘́₫‘DBa+Ă³¡­­nlp[‹ßƯ8Qï™%¨€ïǧi0üå Ï;bElœ› MXĂfL¦ºm„4åÆôç6ˆ`TÏÓ}f+è¡xđI¸ù2©Ê₫“°~_;;Üq ÍÔÁ7ĐêÚƒ́O§ơÆNơx¾ªí±ÛÆW`'¿3ÓƠ1\Mt€~Ûc÷¾û-óØM̉öQÓÀqˆñÅÛ¨¡ ;₫ÀaF×mº°ƠqÀíµ™µ•–úâ«ûÑÆ_«…Z*K70t9¬~âàù€¾a¿löºUéöằ‰»á êă?"¤a¼ endstream endobj 1289 0 obj << /Length 1682 /Filter /FlateDecode >> stream xÚíXËrœFƯë+؉©í~̣đÊe;NÙ +±•ÊBöA„ĂÀ©ô÷¹ư€¡™–4’³KJ 1Đ}ûÜ÷¹M $Hh¤ ¥, Í Öo»ëÀ<|ùơ„Øu,Œf+ß^œ¼ú D@0ÊpF‚‹ơ\ÔE\†ïṇí »UÄ ÙëUĹ?¬Rîb¨ÚF}áá¹–l ¹h‚ă,$Éêûŧ“_.¦ĂHpv$̉qơ!Ül7I@&Ü@îew»¢i(»¥±T‘S„ăÑ«#£Z^–́{£ÍĐ—½lJód̃đđG”'đ@²ßËu¾«³°]›…Äü¬zó×Ë̉|¨ÖæMÓÚưlh‹ê&\–ÈbvôŒ,舤̃(äÛöôÊ>%â)+ gœo‡jE¶Ékób/~&áºí̀û›VđÎüĐºĂתQ/!`×`?ƯHó­“yi^•ùkĂĐđƯ®ƒ˜Đ›ê{óơ¯ÆH¶:*€’tD"Âjy»q˜×;i}“w̉Ôâ!ñ̃5¥rhXÊ?gÖâăº3w#£îû{¿ æv©̃%Ó;p[Ơ\×̉₫(ÛƯU-­ç@Pƒ'”#pQ†¸`FóƯ°Ư ½Ïǰ’$(f6Œ•!}¥¥<[„¯^¬±ZOÀ»u×nlôj7ÁÇG̃ª8(Ô“´g$N¸ÙC  [è_¥µ|^÷íë‚nmÓêÀ.¯v½×2QŒ¦ÔÚ‡M A ¬"Óđ»°ÍàßíY°ª¨ü=U ƒDL‚˜(ÈTƠ‰Ëï8(áă§#g̃饛€#NRxªƒ¯'¿›jâ""q H´(1ÆŸ̉NVZ¼ê!î}IIJX+BÆ*t E’Í‹$ ?TµünÄ!(Jm°SEO5I£* i³!NæAlŸƯíƠŸT’¢”Ñ8óÉÇ„‘qɶk·²î}ÂF”G…ň&ɸâV¥¬]…çÆr¡«4ơ”q„!œRđ¿IG“º‚\èg!Ÿá¡¡,2|D +>Z~̀üaQH”^ªƠC“ª±4·¶µÍß6Å+•ÑáY ÇÔÈÍ‘%r”ëS„dˆ'tQ&«¦rÍR,^Ï1EdZUƒàŸ¡”A\d(Gl·¨A<™J‡2·¹§SLQÆ´$¬Œ³(¤̃ªK ®MAYÔyßû9)°¥ØM*ëIE—¥̃ư…]p²0f“o¤ëøCY¯hêíJDD3 2ö́^˜Çy=ßHºlG,d]ÛmyƯFµ̣]oƒúʈ÷AÉ8Jè>G*̣@[ûrcyA5P}z'ƒ˜&ö¼†M6̀ Xṇ¡P ßÑ84/$5,I€d5¼OY;,]5n{JQÈíˆéÀÄÑÎ.È«®?&sÓ’T£6eÁŸÂC»´)|ú¢èÔgP‰>ó°ơCÛIKtú¡›lt”“Å«Đ"?ô‰ÔøØ?§ƠF¶»áø³ṣµ œ'Ï%£Uv ÙØđá³4>D 9́$ftÇàíư Ï»Rv/†q¥#j­’²@q$ˆ?Uưdä¯<¼̉‚̣> stream xÚíYKoÛF¾ûWè 7û& @Û´)\u›è!É–V¶Z‰TIÊF₫}g¹C‘K­N‚ M¼\gç½ßŒØ„›$|’¤‚¤"™̀Ö´Ư­n'nñê§ †t1ÆÊï¯/½TjÂ(ÉhÆ&׋!«ëùäMôâ.ß4¦ÆBˆH<ŸÆRªèå4•Ѷ˜5˲°odôÊ,Le™™Æ<¡:‹X:}wưóÅ×»ĂWDIq¦¤ơ¾¸ÙPÜT–O® Ủ‰\›ê~ÊÓÈT—s+ÄXEÉ Ơi©c§Z>ŸW¦®6Mé6kS̀ƯÊíÈè-U”Æ\&°`ÄZCF?˜E¾]5°\8Bæ—µû¿­ÍܽX.ÜNQâơl̉Ζo)“fNPfOÏ…YBçNôMƠÖ!-ai2Ô’²èjÓLY_ä+·Ñ³€G-ÊÊíߕւn·U6—…Ư„h€¯·ƠÜGóP-ăöæy“[Ó€n/¶DEûƠê½{ûWáX㉠¦“:f‚0Åœ́÷S¥£|µ5è¼2hTˆé̃9së ĐqƠX=E›wtOư÷ đ¹'Đ ,K»—́öÀqËâveđa^noV}—̣ (@ÁÖtC0óL8u®¶ÍfÛÔ!ŸÑÖ¿Z` ÿZÉ’1YFڵA{䫺|~ R™u±°.Û€›ßlë ¼±¦„BŒ9©QA3+Í£om8đhÖäSøw?,2]²ÿ½Ë`¦#eM’ mó÷Í;:™ĂËŸ'”(8ó¡%]O$‘,…Ơj̣úâw—å¾DL§Dª–•–ª×N¶ZSƯ6C2HÂåíÜ܇Îf)Ô¹æiˆ ăÄ®¤ë;,[~‰"‚%§îμw92 Ø]e­kMg„JöÑ,¿Y¹- ø·¯t6íƒa mjiá×–¯đŸŸ›An±Đ I•0ô`a\”pÆN£¶fJäû5¶>Glµ²ư6Â@Ë|}*Ú 7óâE­—/FmúÈ©í‡KʈÊÄ~̀ú  æ6ôlư1MEä°jĂUp9«]DZà ˆ÷̃ Kr¡p´‹$í=î6 r—3:”QÖ ¼ẫqœBK ;¢»r5œæXWævY~Å“ê&¯@u,Â÷yƒÿ=ßû2€óơÑüđ,M4 ›aaÈw]ÅÁ₫©Úe¾\B ă¨Å¦¡ăÀ-U=¹S×NR=Œö·ˆ×ÇT—Dhq¸´û¢¤pÛî|B&„ëÔG—ÅgGàñ!ÿ3ÂE2jïfeQ˜YÓ5a=çc[q8îbdé5_§<¯5Tù́¬.Ó:Â--St‰}n‘³“Fœ• ¸É̉¦¶'H×Ă ú]×ßYêÖ:a½gÑ¡9Iúv¦u,Ïu¸®\Oc0“;Â3Óy 4¶TÛ÷m×ö£׫WĂf_DfeÖØæ¤·†ÅĂ“<£}ù“ q̃äBöøÈj ‡\mÀƯM7¹€áäÜă&°ßO.¬;J÷v<¹°mdĂ»¶ô¶[ƯàḄ½Á,†ƒ ølpa…₫— .pă“O-–å2øuY‡{EƯ{‹Ê¦5̃X›§vÆ©~¿„Ờ®‚“‘ùùHú¸ùóícç#‰›¬Ư|¤E4¡bloF¸́Ü@e|óK™Ïsđ…“ô¥Ea8`}Æ­Èå8Ü Y Ơ€' ö²ùÈQçŔ7>W¯Ñx̉̀6ËÍ“ nơ¡­»B<€ñ!¸•ñŒ.6#ôçËø¡ |ªS?)®ưΩÔ€ºĂœ‹|†0f[÷ưvB#î©̣ß”Ơc‰ÂMlDn: æÎn±Åá*ç÷q)Ỉq×Ă6×R;slíJ×@5ÖTïÑnëuS±´vîÔÑ̀®½̀vF ƯUdZ#¬cæÖ#?Á¦.ư₫H:ç&½s³ç]Gh¾娋/W+·ºZÅvcúI§œg“AùP5¾R|~0µê;Í]#dÎÈÆ!?4w½hƠÊÑ ¡Sûb“/+L—E˵iúˆíúªÆUf8Ư|¢¼±à;ú†<bÖ̀Đc¹:2F½^Ă £źu§lµâpƯ½RÈÚ­‡diJ·#)äYbăy‰Tm€mk|ƯÇ€å½_3àƒ7K´¼ÆƠö–5¶©­>^Œk‡ư÷jmvá endstream endobj 1296 0 obj << /Length 1402 /Filter /FlateDecode >> stream xÚÍWÛnÛF}÷WđMn¸7r @í¤.Z¤Ij+}qư@Q+›o¥–6ü÷½É¤LÅn‘…kIgÎΜ9³ÄA 8HI Mƒ¢>‰ÍƯ₫&°‹‹ŸO°³‹À0Y­N^Ÿsàeq†ƒƠv́jµ ®Â··y§d¿Œ(¥!}³ŒăáùR°ph U¶~ ¹•½l ¹ŒH'Yˆ³åơêדŸVûàœpÄ}!Roư® ¦(¼®HNÁ'IP̀™ƒÜÖµÁ•̣𗦔]~ÈkùÊ.ÿXf,̀«AÚË./û†{˜Œ8ˆF™Öñª¬e«ƯaÎE¨ü•Î̀Ư’sï.‡ÜØƠ¶u¹»_’4̀KU67O6¹ÊutN$؆û0ÔRơ¥4Ø¢$ˆ`ï˜ÛçÍ’ˆp¨ơÿ5¤]„¶L,l·Öqï̃6ùv_ÆÜù hç‘ơ>ÿy'ûwZ„1KĂÓͦÔơΫj³R­s«T^è]̃Nï«[épLHÓY(›íi-ơö”0bă_ʾ4Á Bº`«Ïß²¦™r–›‹\Á["Ăæª7W£ 1¿î<&Xw&çm¯&µ³^ũÎJ©Ç¨r¤RÔU™d®—84¯è{r¼4â'í<ïK¥ÀCn¦úæ„vóMô?c/Nkno6‹WÖl!ï´'Ù,|çjÑ´\À[xÙ¥j;— ñs¹\`¿₫‰8F#jĂĐå0Đ:Ë•¯ríö½v:f_Ăm^UôÖĐ7övÙ́Tn´ÏíĂÆÊÆ±°à(ÉRˆibÙ´üÜé̉ëå_{¤1AHe k ¼ºƒ <„$#–÷Ʋ(" ‚qP—'¿;YŸ„§q‚²”Wí´}´Ï¹ô0ŒÎ<â¢Êw^JvmÑËƯP©¹mC8¨º÷ñL@"pëÑ\q#*RØŸÖøSß%(.)'—ÇjÍ×Ú•O‹TbEÊܸ}²Ưm[U­®Ùư^̀»a]•…µë Ư'Í›}O@•ˆk -\Ú†“°1Kư"$¸¼iüäx"Ÿ*4¦CûDRZoeÄÀv‹vÓØµjiúĐơ»ÚÛ¥¡ ¶xL ÄÓͺ¦×-ÑË|Ó6ƠĂ‘–7ºăƠ$…ĂAƯzM( Ơj†:B­k—6··ç„r÷UTn¢½“we!a_̀Tkâhî ÿ̉©“êófw€ẫȬ3\¨¢+»¯åjXâÇC¿×ùdlŸ 8̃ư°ÔáVaq˜Ê ÷æºKæb3DƯîơ—9OX A²‘'<—8e"đ=!ú[ ÎÑØg̉Rªh›FÚä̀) •âq@{₫ÍM̀bS®É [óˆü+a K¿ 0G‚'‡<̣ó¼ùÿq©í<ª)X†¨È^B%̣*Ñ “@¿øÈå&ḰÏX›¡®æ¼R øÈ³Å$CœPô£234Ơç_­‹j©9ç„~ +ĐÊÈqè o=©̃&·‡hœm¤s’x+bè{i£WôÁÍêƯhP“‘ñĐ„#^ÆËZăíÀIßjcw&·QÚºËU¹.«ưç•0îƠßN5óVïOÏ|Çü s°fj endstream endobj 1299 0 obj << /Length 1640 /Filter /FlateDecode >> stream xÚíYmoÛ6₫_¡o•€á«D°®]‡ ĂÚ¥ö! Ơ¦¶åIrí×ïø"E”éØNº†±!“wÇ{Ï=§’Ă?å4Ê%C’åÑtu†ÍÓú&²_.8#n] ÓÁÊï&gço„ˆF.H4™MMfÑUüê¶Ü´ªNRÆX̀^$)ç"~“Ho×ÓvQ­ơ/<¾TsU«ơT%)ÍqVÄ'דϾŸôÎHpvd¤Ưêp%CâíÂ¥‚ÛpÊKR‘ÑøÛ B£ñ´-ø¸K‰UÓï½#’1LŒÆ…vsu£üøc„‘wŸÍ̉UÄ'¾-£÷g¿„‚!™D` hSÖår©–çóZ•3íœq*sÄ,J)X"nÛ¤˜ S̀â7‹¥º¶²<"BPm e:E<ƒĐ̀̃Y G¶²á:Fƒ€ƯªoăxV†‡añVƯêXào(€äU?…,‰$Z"á4`‡„ñ_È‚ï×ÏÂóB‘½fñ§ …ƒ`q0œz¶é$ÿçsOߟÏ# mj5]4:ƒ q)¡Cr†æ§ ă=Fç*v†h~?sǘÁă{v¦ƠvƯ.„k[‡ê!ƒư÷P?TôÄz0~B!¯~¨{A*€ÎÉ „ô/ƒh¯¡¼[¡êzƠÜ-å(̣1`Ó¿ặ?́”Èr!ư+y 'iỤ̈Â3 ́ÊX¸ CôaÎëjek¦V;-Ö ‰›$%q _êíJ­ÇA_b¤"Gi±À³†/Ö›m Ăq)ƺlji W;âyŸ¦Ec#-mˆĂ€™5#âOjÚ¢×ÔỤ̀R9 _?G*®¯¤Ÿ·«„ÊÀßNvVsÅ]Á—Ë­rÁµ•}®ë ieÊMQ½Vór»l_Ø'D#Ó¹ö‘»+×4Ûí^”ºP;·=eĐ#2ÉÛm{<~J‘Mn• Ç\Âq@ăØ­^4yhÚ/†e==øxt8„¹}C*ơ¸Åw’!Iú»Ơ¼qUQ̃³/X©jë}¥¦¼QáÔ 0/»Ôf₫˜Y Vä—˜´)’çăYás½hƠáa=]Ö­·«´ª ±¬¯e€ƯA'áxÜcùư˜fÎK2ºKÀ­œÔʘ£LWÇ—̉Ê'%Ơ´̀½9e™ø*‚ù rÄGç æ”̉傸ưª!̉™ ÷h@ơ¬¤Ï̃¿m)»ºië-4ç•î̉jÈcÎ'…kÏôØö̀¿~{>®»˜U^ï5…{Dwù‡»+uWñ@îkƠnëµK«X+‘Ü(‘Ü)î¢`đ˜̃'¡Uëp\„Ă3¿$të¶ơôØ…:¡(+ÄèƠĐOU9+?.]Ÿ̉ÔrrV°ßeg|‡}sètE€ŸÄ~ÎBœû[¸)ÛÛTN]ç!#>7f¶€Jlïk6ߟ°ëàüÆ̣#øM‚€‰Ñ·Nñ¸;đNWƯxtĐT¤êy9 +üH.@ F•‹‚Ô‘£x:&C̃nÍåqG³?½oëÅúÆiø ·®Zé[åÄß̀ú‘̣v>K´TV¾ƒ/çP©ÖnU·øÙZ²'đÙo„±ÏKÀcy182 öÈ0*¶çúús” ưhV/î#`›áZ=éŘ„ä±[{á¶ß¨ú¹>P7J鉆äñ»w»̉”ƒ„Á”ƒ¬,€mv¤)`§L̀<̀W¦£ăb‰ ½kª_͘C¿ÖѼÔL3Ñ^¾¾¸´¡ÏµúÖ¯ªZu'ŸW&óÀ<0aIéë₫ G¡ty]û£&¨[ÀwÛ†¹p³S‰¿˜:–Óî̀55Λ[xØMTºEØïZ”ë®ÆÈ@¥…ƒ†V™ÂÔ#|ØBØÅ‘aŒr©M ,ɉ8ụ́JBRHáF›†Èßï6°tÏeÓeÙt*õ¹ö~¶l­Đ™¥4— áM˜ne¸u²î*ôÎ̀ơÎM`H¡ˆ‰ (=úÄÿÏ·<°$ºj™.«&<˜ÁËBx…tj«¿2µêÍo‡Á ;iØz¨Ă€L 9ئ‚&¥W&ă \Ϻ×KUv;œœü9[ª i½Ø´U:xÿ^˜í½ endstream endobj 1302 0 obj << /Length 1725 /Filter /FlateDecode >> stream xÚƯY[ÓF~ß_á7 sŸq«¾@KªZö PeâÉÆ’§¶ĂÏ™‹Oấ."Pˆwæä̀9ß¹|g’`øGE¥̉L%ËÍv«íMâ^ư~E‚\‚ÙḌéơƠ“çB$£ç$¹^MU]—É›ôÙºØơ¦]dŒ±”ư´È8éó…æé~»́«fkwxúʬLk¶K³È¨Â2O)Y¼»~yơÛơx¸  Îhé }b®¦ aƒ½Ö\-Q “J„÷&¿Øîö}gç̣©s8ÉH8 ¾í¶¨kSÑ–#Ê5|ĂIf̃ÿjÛơ…s̉úܬæÎ°1|±Z”~¥_”A¥*íÛ¦ö uµ5óeăBº»NÊó{k„‚SèKi„‚¤äC¾k…±bN ¥£8m`³<‚nyNkÔÆŒÛ7Ô÷–IÓ€pgú'« eu|ÜMe~́Í|óöfD©ñ€ÖÍBÍ)i±* [¥¢" ÂŒVư$i³©ú̃”m‚„´·Ûs­Ÿ È p ´Màó̉#ŒN×iJnØvàjØÑ­!_¼™­é÷íÖ//÷- ;6‰{¿éjT‡ Z W£At$#iÑ/]„à«ƠƯíë~>Ûd´>ê£Ë9°9̉|¤‹3,¸³>ÈmơưlËŒa—àZ«hđ£, ÜKµ́bT{8ïû¢Úsvư‡T[~ƠsàFµ¿Z7ÜæÏ±LZ—àX«Jˆ¯K±g[EÔötåÇYre\u¢È•OÉU{reî WoÀ¥Ù• zÚN\g9cלxvÍé„]¶çÙU!ÅI ̀5Ë¿ˆ^%L]J9UOB8¡W°b W°s¤WXé6}]Ú­Waª£̃aitï.B…Ü’˜ÇƯ²œĂ&Iî&T˜¬(ø ¡æ÷*U ø“]‚R­*³ÊeƠ~kZœ!€1+ư:̀ZµÆ¿¦£ èéûè„Hˆ§¦¦×1B‘1á́ˆ5äÓ¡«~3…Qœ3ơèÉÜùÚ¯aî 6«¿À†FƯV́MÆ´ \{ˆJ1¼7j7`éGÖ¡¼íĂ²Ù@5í#{ŒfÜ®¿5mï7o«:løÓ|OŸª t¡ĂƠÚöÊ.`û̃o¯ÜÄï/ô&³ưmUß́­¥-¶¼íF'&¹²j› ˜$tèOB¥[Új·6`zØm¤ÖM×û¥jǿüçv÷ ³²Ç |'…§æ-&̀+ëA›ñ«#mPWlKÿP›~²³–‚8ƠGnÎc,–iWƯl‹b›q&\n¾XùQ$2†aœ}¥ŒÅ ¡|´á<Ûí¡µ?̣¾Ûˆ»½W…Đƒ2o­=üY´áڬ’×.ÓÛµÙ–T‚WƯÁƯ­KBœSCưL,̃T7ëÀV'7÷²Ø7¦D‡Bú1ÇIÂ`‚ø_`œ´ª$‘_yŒ‰áè*-Ïy Ÿ|ăt²avä§³#‡˜ºä07¦µ…ÀUúz¿SÈ”^êĂB@ÂÖ{Ó¹Yd½âlè¤CBEơ >É­”½q“L’¢ªô–3W†~B}âx«io­Â¢ סÑQ›³?û5âÈ.L“₫í‚1l0Æ'›ïBĂÙ.ÇŸ¼2ƒfæØ;¯^äs~8;e }fP8É"Ä̀¤Í0K}÷`ѤƯ ̣:Ôܰ­rDà× ”_4kkcf5 Í€‡aÛÚ†mû8 Ûö9¶íBà좌‡?‹Î{4ôDxd'£8ÉÎÕđs ;Ơ™T1É£¡Ûâö sª- endstream endobj 1305 0 obj << /Length 1539 /Filter /FlateDecode >> stream xÚƯXÛnÛF}÷Wđ‘¢Í̃I(P'Mi‹Úú-QSTIʆÿ¾g¹K™”Öw! /³sÛ3ggÈ?D<ˆbAbóơ íÖ_{qöë srSN’¯g'/ß)0J°`¶ª-‚Oá›Uºi³z2B„âƠd*¥ ßMbnËy›W¥y#Ă³l™ƠY9Ï&SQ„œO¾̀>œ¼íŒ+®ˆ’âö̉îÆ<`‚PøÛ»Ë5¡JZwÑ„ÑÉTin6½ ÿîô2!‰HT·HHe´~úBƒ^~(QĐ~Ơ‰®I$‹qUç'úl3‘XʱM›¶Ǽ~^yBI¬ç$̉Ü úX¥‹ô¢Èlz‘Vѧơ‹U¢£€1’(Å’©P1ÑpŸÓC9Áˆ€¯Nê§É”QE‘¿oh:ôNÇ„³¤_đ̉>ó’p¹ÓºIë´(²Â§NQ¨cù—’i—À˜™ ›Nú,KÍG»Ê,ºÎáöÖ=,̣2kˆƠ7̃äâN[=ïËͶmœƯdhr,"ZH_ cá —qÈÔz—Hcuă[µôÙĐœ°›¨Pq8oÓ ~.Í¿́œaouh™µ{Đ”Ñ™‚đHŒ‘9¶Î È£JÊèqF½»ó"mü)Fâ‰bQc‡ÿضƒT«;R=[9¤{K“3"aN% ¯ÿÈ,3ä<U²›b1ÈîàØyѬ»‹uÖnë̉>okP™Ù¥Ö>¸Ÿ´đsËñØÅ“º·m`5Û¢ơ!ƒ#ƒ’KO C@EJÑK 6ü%µce° •¼gÀÈ̉ß9\aa§(#Ơö/Ù¦Îæđ|qS—‡u¤‘ï¥ÂUù3€,xdü\Nó™ièBÖ• Eúy fMU4V.e‚*^.çEƠd^®#¼̃ăÚ!»:¾Í‹́5‡Ô}ú±›>ÊƠÅ¡ƯÚcE€Q«‡́nß«‹o>MG̀“{ù5‘Dcv}cœsø={ö₫ô£î¼*Ë̀¦ÆƒY&81—;¯ Âo~† -³ ñ§`„@$åÇÀQÅaè3ejÛ¬rsVx‘çXûÈS{ “ưS{YŒM>û(¶Áø” ¯ï h2ÚGHyg¼Ü;‡7¦» ³r‘—_퓼» ’ööj•Ï qº…Wyϯp…!¤Ê¾Z§ÿØspláơu›5§—À+Í‹>ɰ\WÎxƯu×öñEw°:%ôή€=´-‡IƯoåMơ ̣́(箈ŸƠ0”’*Eåă¢¼«%¯ñDÓüđà÷ª́I<:‹¨ë^γ₫¨-ê•O¯DÛ w…ÓÔ…‡U¤é₫Y`Nñ̀C‰;UŒ̣¾À::ya=uwU— î"Ư)9àJñ®щ£p¥QE¥—+m8ß—,‡6Ç!¢D“-ï?V±Ư„sq?]·A{ÛÖ‘Ơ)Y}’?"Maˆ@s2ªäcÉøÿES ×G¡)£ vMu ÉăXJ>…¥˜6ư!;K1¾%¦M0”?̃`Pmz¯Æ´ƒ!]Äëøî˜ Ĉ¿¦Ê}>71KFz×Ơ/¶ëơµ—G_“n§E”¢ư¼áêkc´̣`ä0T4A?‡o‹Kpd:7½aæ>°YTß2|ø`eQí$꘭̣f<ÙìéG]Ù¿MíɃ¹¶·Ë2Z×¾ækă¯a÷º2—ƒfv^­7i›_äE>́Uû¥¿¼Í>¾¾e~" 5}Plê)Å–0¢ ́µM<æăZÛÔØC8Đ.¿K±•Ûơ…|PV ¨8̃¯8ă`ïÜ̃”…¥’?­æöhXs/|Zp ™+'̉fëMa>Ư!äĂ?G °$w)™́×yÛXVơ:mñ-¨ÿ¢U›ÉÎW„L»£ÆÄø€Ă×p½Û´măfEV³éiá>âsä:Cù7ặpGư®[©·kW²=̀ÿ̀î¼ endstream endobj 1308 0 obj << /Length 1343 /Filter /FlateDecode >> stream xÚíY[oÛ6~Ï¯Đ£ L,ï¤ vI±>lXf`Y›NTز'É)º_ßCêQ¦o©×®ĂÀvḍœĂïܾC“É”fH3ÍVWØ=-¢æĂÍ›+̉®K`a2XùưôêƠµÁ(Å)‰¦‹¡¨é<ºx̀6µ)' c,f¯' ç"¾ho‹Y¯ û ò”¦˜™IB–iLÙänúöê§i¯\Pg'ZÚ­̃1WÓˆ0„Á^k®–ˆ(I%‚7&ÿ\l¶ueƠĂá̉ááp”…$k®ï'‰ñ»v©‡I,p³2¯²æ´•)ólÙ<ꄘYB:“VRVш«Íj³̀jR̀á$RviPQ®²ºÑÖïtÿUu™—¤“P¤lƠ₫º­OD¦˜PoWöơ~BUü¡6UĐØIL:c“ƪÂîè6'đÚ…ÏzѼßÛ¯œH‡æû2¯kS´\·ïfë¹yÊg,Rû†GHZ÷Đø;+—Ƴ:›ÀÛÓ„‘ØtúWv¤`8d‰ÔƯíæđåÛ#:ß»¥«ˆ#N4|ZF¿_ư M"5â‰bX65‡yµ(M6áIµB,mÜÆd»éÖÁ ƯX|/Í]#@ªˆ” A ̀¦ ïăgÁEr¸Ät̃ßNl¾Å³$¹™é´[ư'8¤›# ‹»Üz’D4̉t(‰„aÀàÖæ ù/Ààëơaø&$†@^N•ÿmB&A•$XÅ“C8A,₫ç.¾ ÏmJ3Ë+‹`à€B"®ơ1ï@ƒ Á½qØ9¾Ícç܆¬–ˆª£îs§—OïÉ™­·E}<î88ö?{úP8Đ3ĂÁéE…´ú¦îơQ Åœœ“@_™ö RƯ S–«ê!( º¬Đ/ñ6ư'’ÿÓ½P(§Ú÷÷ œ$Hl‡g,à¸Q†èÍ\”ëUKâz‚Ăă¼J·]Ç¿ê Ï xäñœ?ăÔ[!Ö‡Î/ûY#ÎJ³åÖTC¦Èc`ÈÎ%ÜEÑf‘m—ơëæ ÁØ:9lg«Üṣ¨è®Iäné÷́´₫SÔv{ẨDËÉO‹«éc;¸¼4 Ù:t”-ƒàóU1Œ(ë ‚ïÎ!=í>h¯œøZ$ÀÓ§SwxÓÆEö\pAʺlÔ¯LUe{¦âơz;¨—LLB“K V&©?ØyÈ|–é Ø®î£WU}îƠx‡Æ½´Ÿ̉½Ùq Fw n€Ë£Üs$mh\Ÿªk‘{1ÂƠø/A?~ø̃¹A†x‡LÄ+TXYàÂ-œú\©–Î^}wơpnC†n§Å×ÓÉ9íÄ­̣Ú­ Ö“ÛÉ—m§ậ¥©·eQơWVÍ}—räCµäƒ¹² ÛE¸»“ܹ‰̉/é5DÁ ¨¾D³±¢dw¯Û6›S–Nc³hC8C)ă>ÓÛ5º1€È"çˆm¢„f;¶¿‹Ơ©º\Xäf9?>F] Bâæ“n=ÖSÖ‚5È!Gk:QÀ¾åèï©G׿VS›‘ũ¥_—•‡‹ ŸøÜ ͨù‘‘B†Ñå·m™û¤54 HyB×ƠÚroOö%P(†¦*̉àĐ9ª\ơÅ€ÁHĂübà+§àI¸ƒ$©Èygœ-³ªÚÓb€«ĐTŒ‡©³×®€îí;¿!d+ăûzWd êụ́»s endstream endobj 1312 0 obj << /Length 1795 /Filter /FlateDecode >> stream xÚƯXKoÛF¾ûWđ ×û^2§¢E\8@›46ÚC’E­c&©”ô×wöE‘+N€…kIÎÎÎ|;óÍ́’ÉTÊPÊTTlΰ}Û¼Üàơ¯gÄË% ˜ $¾>;¿""e8#ÑơÍPƠơ*zÿr›o;Ư,ÆX̀-ÎE|±Hy¼«®¬+ó…ǯơntUèEB–YLùâƯơ‹³ç×ưâ‚ $8;Ñ̉ }`nJ#Â{¹©DDN*Ü™ür×mw]kÖŸz‡£„($™—üëVW^,1‚R’‚´•Ú6ơÜJcƯt øù2§™sI˜roạ̈ÖaÓÙ*ÖEù®WOƯëFw»¦rÀv·Ú îBÄùzçë›đ=ïܬm³ ñÔ”ÅÈh)ÄÀ— "ÂÙRƒ̣æ¾l½Êư²|´¬´Ëz“ĂºùzíC J'Åzs÷ØvÍ®åy€Ôz€•0oƠ•Öa‰¶~vÑ”gÑŸj»|ÑåÆå;óO‡ûÔ‡ Q ˆ)9r1óæVđíE„WѽÜD QĂÑ:º:ûc.ˆH«¨·¹ƠM™¯Ï[ƯyDZ˜̀̀œ„?‡!…²E"$µ.0j]€Ÿ»#³.HĐˆae!ÉÔk'8â6JNŒ-"2E\XU‚N|0?ËFçç°§)ÄQ&­+,¸̣æÂÚ íY|Q®ơ;¯@F„ L˜… f̉–˰}ëIÓD(‚‘®Üè9«€d Ae(Mɬ+]­| ;p¾;¾ªG¼Æƒ/Kl&×@^3I„}úx†¾¬T}…ÊG`7:ƒ|ê}Lr† “fuI¡¦%f–Á Æ~$-Ć@«u” d³´g¤zùaN+IQJ #‚#Ă ‰/sÊF”¯*“P¼U¸³A=WF¦-Œ¤üGÖÿ¤“º32ư)Bè{ ¤¤â|ZTºIåđ§tû₫tXV,KKăè_¬,eƠv¹=yCgV‘Aœ̉ÙR ­U3í!ưÖÖv´:…̃€Kª(Rư6/‹ũ¶h¶N!Í&…̣‡§P6óïö¡®ưÁÇ«0ÅpïÓå,ønø‡»²µ=…¥³ơ]­ó»¶ÔS2Ư§]8„Íîä>‡]¬u¡»êÚcÉvÜdø7yW‡oËêứÏkÊ”¢̀l/Ê2¿«×a™›Ñ-€©Ó~™¢ĐÛ`ÔÆÉ¤ÙæeÓ~5i}­{e5™Ú́È`>{©É?ăÉ2ß­¼ÓOæPçSG= { á#Lu¯-‚đÛsHô­,2-$‹¯vÛ₫•mÀ@~t¶†ç¥ 3;ßE³ÛhÛ"v ´~æc×Ôk¸iDÅǾ´Êb-m[nÚí•€Ïtb9h$Œ‡wûÅaÄp“ư;²ÿL̉~Hy/Ê÷o³Á´Œö,µ̉C} åf0%ÀHSŒă€‡=;À€2 s |Đ̉º°‚·íGx7Ø x²»!i¤vŸ×ï3¬à&ïq—ĂœœZ¼2Ư33—Yv+æ©ÎÆMb4£!άúN·åß§ÆÚ°̀ §ûÿ ˜Fiừ Ỏß*)Ÿál–́€áÛG̃vu¬ƒ`îÙä¾{n:røzĐRæ-ƯæMéˆäT{UX\ÅûÉî¹OOƒ: =êjº .hüÜ•éêüåjunN3v²€vÅAů́ ` øÛSeÊBjËÂLÔ N]À¬™Ûá'‡0r×°—₫KßyëÅ€WtƠ–]éÛ ÇÎ!&¼ A7P/—pFḿÉôF¥Í5¯ÆgÑ~ăÍ!³ En­;ăç!EƠƠúË©û ¡´]–]ûˆ(´Éº³{§&‡ë ÛCw¸Ë|@Ô₫›øÜ¢'繨wƯ©µFz̀ÀÍ4ƒ˜tßÊÊËø:qÛºgW‘¤mD”!?su`¨T±øOÓíUÑ„¸6:¯ÚÑ́åÚ÷¡Ă.áu ‹Øß̣Ï寣>†o|Ă@…p/̀y¨DǛơ~h^́‡9'œŒs£?Á6u] a¾:öG‹‘–½‘¯ t×Wöàâ‚»¬Ü¶iÉÿ4ă endstream endobj 1315 0 obj << /Length 1694 /Filter /FlateDecode >> stream xÚÍYÛnÛF}÷Wđ-­÷~ P hÚ Ơ§$(h‰¶Đ’KRiƯ¯ï̀î’âJ”â8jjˆ–ËáÜḉ!Í2 ÿXfxf¬ V˜l~{Fưn}…Å»ŸÏX”›‚àt ùẮ́ü•R£ÄQDzÙƠPƠl‘½Ï_̃wmYO¦Bˆ\¼˜L¥Tù«‰•ùf5o—ë̃‘ù»̣ª¬ËƠ¼œL¹¡Úå\M>Î̃œư4ë+®ˆ’âv̉û»Vf@'ׄ*\~¶(Ú|¾]®ª.‹Åư3ôe7ReˆÎ¦L¦Xxđ¢lCœíMÂÚÓî ₫8{?,lTËUI‚Ë3ĐIÁ ™+\-l°̣vÓ̃mÚf̀% ₫€¼Ạ×ơªŒbf_̀9Ư¹]/ªY¿Ó+±̉Ás^₫û5Éæó¶˜ÀÏ'ü¯́ơg_fQZ­ ÿ†a₫ߤÙn¾É(‘&ûËK̃f‚p£Y•]œư6ÖS̀(¢™×¤Etº)ëeQ_—íx̃øL’9A aq¥¹Bpü|6%BËL J¸u»A(0ÚE!‰d6"u £° Âä̃&a4uµoœ I(µ'1Î…#º 1~Yl5ôçXÉ™c„Câ0B¸đÀû_ÖÅ¢¸¬b¿À‹nŒ?F%:cŒ8¥¸¯‚P–h§ºÎ0ÿHjL#%ưN§$J™¡VI¸½JŸÀ1ă&AÙNîù˜&ƉR½ªc)(zÆÆL&}`BfV;BÙt|>³©ç»™½¬Çüa–X̃Ïíw˜ E?[爦ª«Bª̀WÁ$.ÉÉ”Ib¨ÖZ¯Ê¿Âb]‡ßkǸ¼ü{Ù´ËƠuØnøơr…Àà{Uà©‚[}Đ₫ꮨ‹Û œGoWƠ}TÓ«EQ/‚‰O¥7eîuTĐlî&,Ÿb<RÑóàøÈuƯ–‹Qt¢—âX½^ Ưô¤Ù“ÂXSÚwĂ4tÑr…‘̀ăY´¾³ 9a¶¯ăƒSK$7p CÍ´ûBdO¬s˜@©…?ÛP_å¼*†Œ5eJÓ‘´Ó1¸“†Èm;C₫$eáÇŶqđªoˆp¹i°ÊS-m~á;bPưØj4§Ïá³¹êFÅcƯ G·êÅ8íVWØxÓèy©ör،ǥ̀™íw¹́—̉ö‹O9̃ +{ e™â<ŒKT,(H“n$ ^¬cU¯GÛ…k>À{¢ª¯}?¼`Wë|‰³©U¾¾]¶vtÑÈHĂàöøñ Ä{NÂo˜ü‚Â-Đ)`¾¨J—ƒ™x²üº¤¨ªà\]¶›zÖóM ,ØWظDɵ`zIÇæĂË¢ ]À)#ƹ…" `¡ÙTíXú¥Nˆ¤çP ÑŸjXª# ̀á©£°&Ú•Älçi³Y2UEVƯú-1󶾓đtñª¦ X>Fg7¾i๫äM¤Û]_6ë :Œà+‹̀o¢áëä÷MßÛ…†¼ ºØ0°₫ UúW}†ÊĂP…Ñ^œNÂPQ—dêá ơÆ;†¿Ä¨ïÛ²Y₫óYjbôI±ÔCn FÄv–1-€vB­=1ûl¾}ÉîÿÏ>w^æùD¿bô0 Ÿp»'Ÿ~đṢ‰ „;÷mL±̃ï#cđ‡ !Œö¡„Q>EÂÈ­"b8aDUÿ˜0‚n<ڤɃ›ü~‚EŒ k,0“~§ơ=øa¼ơ:vʵÁcxxƯ%$‰'’:×çæÜ’H‚K¡\qgFàd'FM×#|‹»À· ]C¾Eăg/¼=~XIpFe‹D¡ø¾¥áÜ×qTÅú¯qÀ0 -ç̣îÜx²…wd ·²…7CÛ2\…̣¡à€sáåºËNOÑt<ĂøÖ˜âH¨=â)¼/îU¸ĂA¦,rë¢Ùùx˜Á1G÷Px¾?̉7¤‹a÷I1"úh₫Øàr p=̃#²sW$æwœºq8ưøu¡n X¸äê$Ô u±ưS·Sï¨[b|^­›oËÙS á9ÉMØF(…ư,¥°@cLzœ¼ô₫¥ƒ½Gú)¡¯Ê¢{¢è₫rÀdƠưq¡læợ®]Ÿˆ3<ÉLđWMÍ)(hæÑŒaHN€™W¾YŸ@ö(Xbv₫¼*¬` endstream endobj 1318 0 obj << /Length 1633 /Filter /FlateDecode >> stream xÚƯY[oÛ6~Ï¯Đ£ D ï¤ 6´C‹aǺ) Ùf́Jrºüû^¤ˆ.siĂP ¦¨Ăs¿|bH†áÉÍ”fH3•­®°Ûí.2¿øôÛ t3Ê_Ñ ‘ŒJ\’́ä|Îêdæ¿^VÛÁt‹‚1–³7‹‚s‘¿[hïÚƠPoZû†çŸ̀¹éL»2‹‚*,ËœÊÅÙɇƒ·'“pAœ=RÓ‘úu5ÍCôµêj‰ˆT",¸WùănØî†̃Êß·gQH²@ùǦ5,æZîØ”!……'†%"|QIóŸ7`6ÍWCµ€Ÿë#¹íư2AFḶLj0–Ö„Ó3œ­áå‡ #B¿:̉«Œ#N4¬́øàÏ”¡D ¤ ^)TêMWWÍQß5ß §ŒƒPư,Â)+*₫±ë/Sn&%A”iç?²ưéï›j]-ăs rˆ9t˜ÈŒT A]˜ĐH–óÆvÍßçÍ$Qâ¹D ç8I?c•³äˆBJá¹óR’¤ˆĐ#Ưa ‰8„˜X¦„1ĸ)¾¤˜HDƠDq–2+âV‘”· B"%‡Cct̃9O9O—ÆéÖgnÚuƯ^øº]åhăj¥Çeđ¾WyOqE₫¦%dä×ÂkY·ưP¹bÛœ§$Hˆ¢ 5Hµ«Aø¹¶ÿ%jb8…ÔÅ :„Ø/đîX ¢Áâ*ˆ¥S:—P‚X"Đ⻌\5Uߣ”MQHs=çKIJḌ6‚Û¾́̀.ø¬7Y ›Đ«Áƒ>ú ˆùM½'|ßZg æÂtÈ6tï¶[çÍM7˜µ?x½"¯éßXe²Â‹‡¾‡08Ê)á¸̉xêîàγ襁¿ª‡ÀBêR̀±²™¢QI’ââơ¹MV›!wœ§©óKoÏđ;·¬Ú cRu–Ϫc_öûd¢úå~ñß̀mƠUWf³u\æ•8Œê˜åé~Ï9’gC¿—ô;=N]®¡ÍĂÄÆ]Eí̃¶V׈¼&—UÓx]í{h&ÁÿÜù_Yÿ­fßƯ£_C¼vÀ™®Gé‰ µ/ÂHQø&½xʤçCqˆg™ô†®̉üñ“₫9„“>ÙYỌ̈›WöŃMrÚkDIù˜iOŸ8íå=Ó₫n½«̣¡yMJí’%jø;,VißaÛ”i±̃?- ®zÀ·æ$×OöíSRª£e` 4Ỹ¯vAs;Ù́ÆÅøÆüS÷ƒƒ0~#(âÖurƯyeA…Ư£¶öÑóœ/ B)X₫Öăˆöèăz}ä†#»…₫¹êË~·-¦±0 çl₫AcĐª(}PeY ­^UùF6%c¨dlæANÈüˆ{3aaḉP´8Áû@ËÀ ›ZJ[ŒeÁöfÍZ˜Uˆ²t)¨\ ùm©-ÆUƠ‡'ˆ-¬Hnó¿·‹CíOzÈL×Ơªjç)ô›j¹́̀u]MhmǾ˜Î¼ëÿ¶1ĂV6ms3V¶Ëẹ̈I?€¤Q;½;(éÛN3ÇIÖ½ÿá$"‚ʰ–R"•Q <ó#( f¾b̉±Â¥̃7f”¬*(Á²3Ă®kưzµëàÖÄ5*¿1O7æ³Cº́đU0x2±3.ô6›!]đÍ.dœÛ”§áE’ÑÑë~ÀÂă…ĐÉ¥G§,?n€ÆƯͲß@z˜đeñWëÚúëMÈ&ˆè¥ï;ëÛ¶eªGuÎ̃×:“FĂS½×5OÆæYx›=¥ăa’‚–†$& h)Ÿ-‰½êœ̣Đ’À–êñĐ̣9„Đ2>l¶Ë: á_ XÆB÷àµ"/y‘t´t%ALÓ‡‘%|›Cï×úË~™D–™B–÷9·„^L^[rŸºpà’é.íÂ]›hÚ”Àå…‘¥]ï!K÷Œöçéno-EẸ́­ë!đ†xR/’Ùë‹96ñ8Ó½|-œÉ₫‹8SCràg¹»NR‘—E™³"₫†mYî›Ö;¿¯́b9ÂGíñ=^H6¥‡½®êmØï»Á“´´·!á&‰¢Ñ×ÿ…W« endstream endobj 1321 0 obj << /Length 1921 /Filter /FlateDecode >> stream xÚÍYÛÛ6}߯ĐÛÊ@̀đ.*@^Đ Z¤M¶O› myW­,m$9—¿ïđ&“^z/IPEÖ9Πϳ$ĂđÉ !Ål½;Ăft¸ẾĂë_Έ³[‚á2°üñấés!2‚Q‰K’]lCW›́2ÿ麺™êa±dŒǻÙbɹȟ/Ï÷ƯzjúNÏđüu½­‡º[׋%-°,sZ,̃]¼<ûùb^\PgŒÔ[ß WÑŒ0„!^®’ˆà“J„·!¿ÚO7ûiÔëg‡³%)dỊ̂ÅÖ•¡!ˆ%Ø›qêoV)_ #! ovS Ơ®¶•R2oFư)̣~×LS½yoe™O×µ‡Ö—çưœ3• %³+$a-Èø̣Î60ù2ĂSöÑXî2†($³6{söGjiA‘¤Ô¸â4H¤™Æ·X`øGl ăuƠ.H̃Ú·¡öCgc\/–$ßĂÜ» E>¹ØÁµÖ̃́؇…yƠî]zƠh t¾&ö‰ó"ÂÆ3Ôă¾R•e%Ÿ7 Y}xdr¶AvQ!¬"PIƯ_\›½ôn#ÄúÑ~5ö-l̉ĐæùŸcmç¯êÉTƯÆ>Œv„ç°Ï×=]ån¦éÆ©®6È#tI¸è’2+C .–B̉ü{pÅh¾ª||X0’×·ÁA ›°€xÈñơèàˆ£#‰)ÂÀ|JwĐÇzhªöi™Œ#ŒƠ7Yœ²qQÄ‹OÍ®î÷Sr£K‚(S¦~Ä×ị̈×¾ÚT«¶¶ơ>b̃9'RŸăRj6 8S¥˜15´EkJ‘ dq0ÖÆY¡S(œ-–/µ6Â3‘úẾÔTô:MkT¶嘽;÷+ ₫®g2«Îí«ïШơ­øg7aW“ójQKÑ¥º£pKVP<¯«Gyn¼åaGöá9€Â¦äîs&ØPPäéº8›ØŸ±wëÍmwé‘Ó9p̀éĐlÿ&?÷̀ü/–Ë endstream endobj 1324 0 obj << /Length 1762 /Filter /FlateDecode >> stream xÚåXÛnÜ6}÷W,úb-eÄ» @› .\i»èƒc̣.× •\]¸_ß’º­¹¾$iZđêB‡gfÎ.bø£ Í:á$áz±̃Åöi}½pï<¢~Ü ®&#_Ÿ½<‘rAc’Æ)]œo§¦Î7‹‹èÍMvÛz¹âœGüƠr%„ŒN–‰ˆºrƯæU‰oDỗlMmʵY®˜U±dyy₫ÓÑçĂâ’I"¢§ưèGÜM¡l2Eb)œË·Y·K–DwàŒR*úoÜCq+iÛ¼¼v7ÇeUă₫Æ|Äq¦T`'‰6›cܸ·¢hÆƯjWv¥Ö4ù_°yđ8z×íĐÂb9́DTmµ«¼mÜU[¹7™á ¹»±ŒµŸéÑOà ºu›:Ă™”'Iôz¸ÅÙưFó6Y Ăê]^fEm²Í$5Q0*©×´Yï–Û…˜Muoœ{¹rc«̣ØÏª{$?Ä”/!¦‘Ărå›8u›—¸^ Q‰´îjH,Ħơ‘k‡½ơ˜âœ6ô¤*‹»®—' [À~bH̀™6iVŒK·,'Đt¹’duẼ´nú<å8&¤Pv:‹•›~%Á§%Á£“¼0—΀̉ JI*%³ë÷b7w²ă”pđÜúđ€ÍƯsNųzĐ$I?ÑQ˜o¬ ¤‡ú½i»º3s(Ûµ&чEÑ':ăƒ`«¤ªûỗ˜Ö¬[³qw¹'öÆgRs×´fGBç¡9-o;0؃ËgÅ}ῃ*~‚½Ÿ»vb0}Àà¡  AÎçh5m=đÊÚœ¬®3OIÓÄ=ŒŸˆÊ%²D=2Ÿ(vlë1nN°Ôù}fLͦzÚ¦¦é°O¨Ëú7ñ)/·æÖ˜µă$¬h5äö7!»ª}€ÏC°ÄIyú¨%=ÉvJÂ/‰áÙ½g±¯øºèåêÏAƒ(ç$…2 º¸Œx TJ$üd‡î‚;*gG¿:»@yJx*ÁǾµ‰*´+–BåïñËÛ*ÛdW…Ù”m.Cܱâ2! ôØ\„ˆH¦‡H!£‡,Óxơ"d‡ª’÷CÖUW>Ï.—¨ñ#­ƠÅ#‘ZÈ ’`‡²jâä§LßÏ`ª ¹„ĐÍ/H±,NHÊØ>Åf¾‚·uµ»Ï£¹;So³µy6?>Dg3Pö2Äñ,«̃ZÛ̉yÊ ¬ ¡cL]£´n-Ơ}Äæ~Y!(ªZ¢ ÿöÊJ衪8€̀çU5_A¤ ¢¬)!èóv¹.²¦!¡M_H x\Üfi0·˜Bé=ØJ́ư°Ll˜D}÷4§>c®Mæ?ç¦KÁ ªú†́ơEp}€$Áh Æ9—PƯÏæ\U¡‰ε¦(VbÏ‘Căܸ±í^Ö¶[q׃}Øñ'¸Bص‡ƯéÖkÓ4Û®(î¼5\́¡#„gäe(; đI’ª)Ư¹î4Ô+å©!A2¿ô$^îAVnÜj¹í‹¹HAsøœ9öçǼS¸:ḳ¸œJ²ÑË=¹MF–ͼÁ.·ùÜ6‰?® ­ hĐ½å Ưô–>AoY询·hK¤>ç?ÁĐ|5ÁƯoêç‚[†´g.”S雸¶§}1Ñ>Eûøµ/y†–¹2÷j̃>b&̉yÿPÚíº¦—‡ÿÈ —_CÁÔ?¤‡ô <’îáÖGy”»«QÁ¸­̀Ö”ó<6L@FÂÆ„Àk‚_¦Dô&+æM¶ö¾ĂœMÎiư÷‰́’€Ô†™ÎoöóåCÖßü™¯Ä>‘$w¿®v·…AÊ/Q,åaÚ„|!± ªa!¿D°&©5¥é„4G¶~:ÆË^ñÚÆ /‚RŒ/{ü̃ÑÇ›¬Ù³V›¦+ÚyÉ ¿NïÓàë HtIA¸P̀÷êPy~ሜè^²§Wg.ß̣ 2QKø¨È)Ö‘ô2½î€â…ï;̀mfé~>¢P8%ÆøDCƠ<P ‚^h=¥H>·…—몄s⺫Íù2‘û°×BY„êc<}Ö÷¯ư³éüû¬¾ÍíÚ{ëÎ5‡B­é™èü«Rˆ_;?_ ©N!lsưïc†ÍûˆÛܘ„z£ôÆ,‚TPµÉặơ5Çá̀ô‡®K+Û^¾?{sj‰́´ÿ=jÇ.+óÛ®Èl}%ÿ ₫Ơ6½ endstream endobj 1327 0 obj << /Length 1543 /Filter /FlateDecode >> stream xÚíX[o£F~ϯ@û„¥e2w`¥JU«¦ê>´jÖR²yÀö8aeƒ 8Qúë÷̀ d|˦­RU‘ ‡3çúï˜₫HÓ NJX̀רܭî{qưóqrF=ɦ—WB£§$˜.ûª¦‹à&üñ>Û4ªDŒ±}˜Dœ‹đj’đp[̀›¼,ô^«¥ªT1W“ˆÆX¦!M'·Ó?M»ĂHpv¢¥­ô3s†0Ø«ÍM$"1è¤aÁ­É¿›mSëăÁ¹´ï"#Éœ`­ª<[9ÁAh0 oä"ë½߀‡IXV½YÎ&‘á5o|'FNS6aƠA8×̃CÁ‡”ŒƠÂyV0?Là¬lµUöᲬ́ư™{X6÷ök¥²…•È wñXạ̊[hµ{¸V°ÏL.QLăÖ̀ïN0³™€qOc£²ÎrÖ3u‘5™×@wàÀ@ăÎ> FḶs,́©ơ6ªZƠh5FŒ ¸-³é½)ö´§Y›g…½˜µ₫ê/*oîué뺩̣â®-PÙ·œH†$IZÓßy½ë‡^ùÔ¤ˆPzº’÷>ĐX»b<®cµô+é%«$Aq§ă3x¡–ÙvƠÀ%ñÅcørÔ®dg×¥?F.Yz²m¥K^›Ư¼˜ 4ê®Íj—n¢ë= ơ‡RN»R)í*²'á à‚#–¤¦+Ý*í·mÓC4qÑ~-‹¶Éă‘ø+RiÅ>)W÷Ùª.?x›\ „wÑ!Ÿßt‰†ª³–;¨èFT$ ¿× çĐRđïaÂH¨Úñg‡ûº0†aM/¨Ô¨s‹ƒ<ü€pæ£]qÓ)«àÓÅï¾Ù@d‚¸0ª(#Oàxđạ̈3&b[ß[‡$ÄŒ TjJ¥~ƯàcëO£d_p%´‡80¾Âåj§‚›÷ª̃w>GæŸZ¨Ÿ&’ „ö5¯'C"ô0íCè¿ïËđÜ¡/ïí¹ïr=̀ßùN$9î;Ô%cä-ú^¾÷:/)wȺs~ØÅq‡>ư¸2îØ™xïÆ±cBææˆà̀¶Đ#LUµ¯éñ°ƯOf^»0 NMF h^°+µè›jÉ„3’k}ù\ÙYí”DS‰™3l r˜ôf˜†Ùb‘ḳj|ÆÚgfU¶¶đmè.Håµ{Z•̣̀…1”̃iGRdÂN¦¸½ĂIôˆƒ€Wî¦\éq:Qô 2aëͧ‰Ñs„)Ơơå^«'L[s:ºÆys¯tß '!”n:¢}m1:N›¯V}₫ëÙa:äê@Å₫'F+{ÉheIį1ZÜJ¥ôÖåh®¶¥Yz{=‰ƒ¨ æë l–¬¿Y²đ*_©[/²3½̣ Ûớ©Qµ_‡³¢Åum`kÜ^áUNOAöN¨œ}Ù‡́lD´‡ZEú ·Ëáz³ÊºU퀡s(Áh2P"€à'ĂöúCG_oVu·­³ÆA/s‹‹̃ ³=NŒ×G,»¤mk­Ñn̉›‘ơ2pÜè¹cZ3ç½Kx^€iÛµ²œÜÛB&&cé¹óµÉµ[¾Ï!’"wùË]è²ÓÊhæ7äƯxÊAnN©é!“¹vóuo>Kâ(FNÍ DC€<#üíZÎ̀¿ëE1bMæ(ôíË:·-Æ—KGCô£'W™£=½­ /±Ô`®2Øđøs\å/ÁU«):ø ¸ªUéæôăªùÉäŸ@ÔóX̣άofÉ–¾ÚhÓ–·†Ă˾™̉é©ó¿”Ï$`™d÷+ç̃xr@N.₫§'CEĂx hS©y^ë±ß¦ÒĂĂ ïpr†6“să³Z÷£é3̃˃̃ồËmѯƒ[[ÇÊÁ06öZŒíÙ.¾‡l MƯ›£PœÓ@o,G{u ¡ªªu}çƠB$/É6ư;ÿÛ³í§Ö×à‰—E1ÍK™'q#î/˪\÷é°e=#–ùœḳ̃oÁ́ endstream endobj 1331 0 obj << /Length 1333 /Filter /FlateDecode >> stream xÚÅXMoÛ8½çWè(C_RÅ.6Åö°‹m ôæ ØL¢À–½ ûëw(R²(Ó’)$LÍ<Îđ½74‰0üH¦‘̀(ʨŒë3Ü>­o#ûÏ—OgÄ­K`a2XùÛǘü‚óˆ`”ăœDó›a¨ù2ºŒ¿+¶ZƠ³„RÓ÷³„1_̀2徭.7•ù„Å_ÔªUµP³$•Xä1ų«ùç³?æ}rrĈ´[}7K#B¼n&‘3sf!ÿYmwº1éasùps8JˆD‚º…›ëYÂE|ï–zu 9bP lW–-@awÛ¨º,V[³×xSkû°Æă{µĐ(”@§1Çñ›ÀCl^e½¶|‡Å! ¥ûE›ëûPf’6vk̃…¢™ÿđ˜L>"[‚Å Ö3$̀çÍ p¢¦œ#!ø”̉ 5Mó§‹J‹ệ‹:¡;#mЫDZ%i*‘„̃ …ä›é)\Po)4üOÛ>½5êøhƠed‡eƠèz·VCUKbÆ[R‘¿­yÛGV/fÚÇ|…Oó§v•çÏíIîO¿Ö ù‰FÔJïêÊƠ¸÷FÙz£t̃È OaAËù¾ ZUa\„µĂ=Ù̃’ÄK,‰J{y K¢ÁĂt«ô[Ø‘áÖB‡T‡Q”S>6£–/*°˜́‰INäèFáPđüIápºséqèg*qSªƠ2TˆNöê… ¡BœÊ<ÁA¶ơf«jư#¨û0̣¤îs¼ơEă“r¦íx̀ÚL—º́HØqs­9©‰>'°ÏÏÉúí•Ï?!9¶?Á‰…á¤hï—q ƒHÉö#S»£đçÁü ¨CÑ©~b©Ó±:0Ù‹…KơÅÁÏBOtÀ„âRäÁ•4$̃9̀·½ÿ.VEÓ1i†j9ö…~è×­´ơ2ªhU¬•ßÿĂXÀÊ–A^jßîTE4!²â™[{4ë w¬w̉åwL˜Z¾ë.ÆÆ¯<^Pseăí•mè™æóBwī۱̣À· ï|dÙˆ^?–M3ị́2/¯wÚ«ƠaOÊîßíĐÖ vu?NÈQí¡®˜8T_•êR4›÷GJ:˜\>Nâ‘‘ü "G”‰g̣È̃à˜ ̉F"hK£óFé#“¦æo’4“‚|ɤ·M„)}I@-%xç±QaÛỄ5OÎ Ư®~nh¤:14ó- NJ̣b³ L Oßkuưû›Ăp3Ç"ØÎ/4¯á5iđ5a÷ éÿ«„AĐ endstream endobj 1334 0 obj << /Length 1607 /Filter /FlateDecode >> stream xÚƯXKoÜ6¾ûWè(#I uê"94¨½·$YKÇJ´̉VâÚp}gDjW”¹~4A[¼5÷|3$ ø£A–YÎHβ Úœ$ănÿ90‹‹ßN¨¥‹0Q₫²:yu.D@R$ V×sV«uđ!<»)·ZơQ̀ Ùë(æ\„çQÎĂ][éºkñ /ÔµêU[©(N³D!£Ñ§Ơ»“_W{á"DpöLM'êêæi@I@_T7—„fÀ3•$ܨü~§·;= |°®˜[—1͈d–rĐ¥̃M„XJ8å@?̉Å`d’‡¥ùt¿«ô®Wæñ®Ö7¸ÊB}c·îs]™e[nÔ`–Ưµù=kTÙ¯Đ…Ư¥j×§°KYø¦Ôå¥̉ª\ßG9 íöYÙ÷µêß(­*m÷Êv:±Ơ2‡PaT½¨ÛÏoÛu]•ºë­eÙÂiB@C©”‰mÙ ƯkŸ+¸ 9/&W ª¯Ëf aƒzM̀nPb™$…TèäV1ˆ"É£XÈ4ü¹‘iXé2‚ŸÛˆÑPMỤ̀ç>¨ $/•9&À‡OI°†—ï‚„y7’nnÈaƠ—'ø̉¾'\+Đ!Ë–€x°äU7ÖHp%…éhM!ñÛ2Ëí·k–ơ•œÓ2JH¶¾ú)Â4gŒDZ5Ê&â‰H|â9IùăZƯúÄR0kÏèÔÇ…¦W–¤êv­ö©äê*Q¯G(§D@hæ‰÷ă¸ä1ưsÚ ÛöªªDFr)Ï:Ø-¹˜BÎ1YXS[Úè4S«t,Ă j'¦aUL(¨y²tmUºÛàÿ«±b' ¡8ÜFBBåïFˆ‚ưë¾Û˜7¥ÙX”»ÙÜ 2–Ñ{@Ù˜¶ ¬G jXă´àƯYás¡†đ/\(/–$E¤ñÁÛö)hgË´p<›R’²|ë PƠµ- «Z[·îmÎ&›9̣«+å[1¤›ªÓ Ư®½Í%ñ(äY¸glpqe"Ûá&\,TÚ(Ăw0otg̃ j¡œ•å(·ÈĐÜKRH9SK¾ÇÈN‘Æ x´±Åư±âN76a³9Bø;ª¹ß#Qœ3íú̃ZƠܺ¯m‡^¸³́…ƒØª8G7‘!}{ÛÖvµáœ›}„”µº.ÑÑÆú;5/&²S÷3*Ư÷öù@À̉‰81œ¶4’?ØxFª?Œ™A¯›́|̃¹m™` ÆưO¦²gv„Á|Ÿ ä KZùÆ‰Ø 1CEöo ̣0Tÿd¨àÀ™Ÿ¡YÑcC…y¾WơF(Ï+¤.¬QÎq₫›×,<¯ơÉ×b†ă1—®'g̣Üö“Q…xQ5½Ă¤ (êe©̀ÆñĩÉ₫¿.z¿cá3z¿®7ʧ„—&âé¶Ï ’çÔuœ¶ol7åÚ-ÊÖÚ2nºö#`#ÛW¹ÇYn  ¨,±@ïüĐ]aɆ_ çúªáäxáàÙ…TA¸|N+Es¦nꦩí=̀ưé¸ZÁS/ßÚ¡©í¬ƒ±K™ÙKÍ£4N9b́HîÄEó|²ÍÊNfÓh¥Ö~ø3†:As;„x$j¿w­ź0øM¸ư2¸F¼¯3POr˜Û8å7âuÊĂéyÑä(`k?Pƒ90[~G Öæ(t ¢ÜsGwơåØ)'} (É=Nº­êơ½™€Q‘̉G™I’B§³·cv¿à¹p)ăàR₫=;Ăä̉GO¡„oi3P›çË6£½ ³Ç]Oƒơ„O;ù›NƯÂÅ̃xi5öH)¡³\í@,‚ŸÛhÄăX”&0良œ&–Xij=1ˆ)s¡È•ÂØ›‘óÎÀ^đ…‹0¾Ï•ª)‡x("‡;S'À6œx  ÑÂû#ø.8]öS¸Ăt£ÿT-±§3ĂLœ"íYÎëè…úƠƒ3Ujꩃ‹Æ`7h·ÓzT)8É̉CN§É#§*q{²«ơ4éÁ)£Ù 0¸ÓGÙØ[“M©+4øf«2wTu,F5K™{–_Mb®ûxlàVLU©í¤ÔÇ‹1e[Ö½‘‡¹ÿ7wZéV endstream endobj 1239 0 obj << /Type /ObjStm /N 100 /First 940 /Length 1193 /Filter /FlateDecode >> stream xÚƠ™Ín[7…÷z >Äá3CÀÈ¢ ¼+¤Y´5²R¡(Ø…íéÛ÷ å²D;W—’/,œđæẵŸ-!†¢5d Å8X ”8û₫Đ˜2®Wœ½ÿ`k"‡,1£›´óBƒÆ+)e4bĐ̉"$XuQ(ÔZ]`­ CQ›¡ü´₫́£crQ̣BH!6#à'³Gú@ùE£_Dg%W‚–}•¨¹Á*©Zë˜B©) ‰2-ˆ!|•R\˜øµ'uU¢ø 4¤"I,`~WÊPŒ&c'€áM½£BU2Q ±NŸƒ‘‰_,PÚT œ*¦?ÎÑ—¯æÔ]aW¸ ¹”Ñ$ê«6 ¬ÔÆ0¦EÊ¢" eêëÇ^åHM¶;ế[€&…ª®j 9'l6ÚsI_]IS[]e‘ ¢,RPlx¶Ü:ºj©¿âÇ7µPt÷T…râŒN¥AÂÆF^h‚­25…¶Âyá[_kW˜£ˆS.˜3ùF fX;ØĂ+"Ø„|ư$y¾ ˆÇn<Äæë7Àó|l27…"̃³Qiñp€EW˜XhB€ÆÜâ±¼h®P |NxAÑiaâè۔ɛjShs Ø+pkSÂt*êcPÊđˆÖÍ”~vÿ[tË€›‘Ñấl±z.P™^³ïĂê·ßÿÀ°D[ ¼xùơË—‹7o ,—Ó}7¬. nzx~uyÎÎÂêđm­×;é§@¾Ó­€î4ùö%₫?̀K(ñ¦?F^½»¾úüëú6\„Ơ»·çaơaưí6ÜOúáßÖ¸đé¯ơbơ3°¾¼½ñ£¤ ¾X½_ß\}½₫¼¾ÙM­í—ơŸúéê[¸đXeé…».­~Ä|Ÿ®1¼*-|›6x›‚&`- lg{d~n¥“ç–æ&]Ûà'6r›ÁüÄ­“¸’8ù¸—¹~7ó©q/M¨tl_â0¡Bó2?FF̉É(gT¦íù̀8±²ô»êAæØ>%¤=§ÜŸœî“rOt̀ĂR¨Ă¸3–8\/¥:Ö|$y‰¤q$<ÍNâï¦ù°´«ŒĂ’‰°Æ1#Îlîmy—ÏCvG¯=vv;¥}vuØ@;6yÔNÇG̉©=MĂHtbííÄá¥oYñ¨=¿ø&Ùi>­Nñi§%/` Ù¬SE:^EZŸëö¨Gæ#á}$FĂH,½¦;“u-C˜øT8!î‡=…­vĐéaèjÜGg3_%¶̣Ûö̉s–Tí”T¥a$5É4ÿ̀G̉)°Ç‘L,°¸”x©ø8û„>5­NMƠñªöjû_,üËï ÿ|Ô;÷Iß69–‡'UÑn\1ZªØk1uØöQcƯg§G5Đi¦NQ†@ôj¿à0ujxI~®ç— é” — éó½<Ä5ü‚À‰:Hê0’_àös¤5í~á”Æ‘Lûü²GY—»ÿ#ùẴ‹’vĐö-†“í£““¹é©—…£Ü™¸S`©#áø·ç#¹„;ÆiÉÓö*9 endstream endobj 1338 0 obj << /Length 1418 /Filter /FlateDecode >> stream xÚíXKoÛF¾ûWđ0×ûä’>m“"Ú¤²ĐK”¸vØJ¤B®œº¿¾³/”hX1r"@´ÜÎ|óÍ́Đ$ÂđD’F2g(g2Zo/°Ưíî"·XütA¼\ ‚éḤûåÅƠ+!"‚Q -oǦ–Uô.₫ác¹ÓªKRÆX̀®“”s¿Jr®ÛÆœđx¡nU§µJR*qVÄŒ&–?_¼\/T ÁÙ™éws†0økÜÍ3D$ؤ‚;—ßví¼"±êt­zăDYŒ£ÄQJ ”g™Óx±*÷UWjơ O e a%o”ÓÇú#„Ê Đ ê¶Û[÷Û«®.7Nœ¡yÜv%©,¾Ùï†-U9ùûDdq¹Ùƒ»öy•ÀùƒÓ¯›^wû­j*c®s8Ô]»t"c|i”XÀü·Ñ1Dq>KçŒb$9˜$Œ‡=ưâ°b8ÈeĂ9“|XR>ˆ̣Ăn1R+è Ár+=ă¡NƒIN P1‘ Må”aĐ5øq/ôYÜ {£tÀ“MG&I#µï¼̃œ́'¸-àÁ–=SĂUưfoSæ8–Z̃¤₫'Ϭu­úúŸs¹eç¸U6VG¦ù)™@È$™®!€9È.é¼°ÈÏ )·Ïq¼×m¼2×Í[sNÂfê ÂI2‡+S9ñŸjư4Ô>C/veWk‹×¹₫Êđr”ƯóPuXzÔåuy„º ñË{cA5Woªêê×¶qÊø[÷Nå­(;Á·X  ÙÚ÷z®L§€Y7wă#‡0r½úµv›î<^—½ƒ¾¢¾ÖµóÓmœX—M ƯÈt¹Zu 1O&qmKÄ^I·NlH<” ïzO‡̉&ΙÈÚfópnbK»U­ûgĐĐVë̃B́£̣[3Øöئ™:µ¿ ‰/.zvéz«Ú½>÷²É|fá4ÍĂˆ”î¬n¼Œ¿(>öîÙ]I é~zHeZ©dñïIÎF&‚hJܶªlú‰öjÓZàÖĂ¿\ĂöºÜlĐ\b)ÿ®·ơ)|càyL…pï±À5 ƯÍ ÓÖíÉÙ- SŸ MZ·Àóêq´'Ÿ’fbåàäÂ@·¼1yvצÂϤ@Uj¨œn[7å¦Seơđ”{ywbèàáËŬwÓ Ê{G)bEị̂̃f¯w{ƯÏy„]̀Z¦«y1y*̀nût—›¾½³ËÊyˆÿ'™¶·±oO~œü4̀ˆD$8ÅH˜ùđƯUp,D\FŸ­Ü6bˆ‚6ÑÍÅos3/‘RcíĐ̀#í®Ÿáj½Jï”Ç`f´‚~j†‘@^dÔè ~î3˜ÎƒËxI€lÇáxiˆ‡#Ṇi¦̀|f~+}ï¨éøÁ:ÏÎ|–zß_‘úûg>º #Lé”t¶'Ñçô$J2$O₫¬dlñÇ[̉")àïæ‹Ú̉"Èÿ‡Û̉sº̉Âü•°*á«t&₫ w&BsD!U_¡3S8ơÿÎôtgB!-ÿñ¬å endstream endobj 1341 0 obj << /Length 1635 /Filter /FlateDecode >> stream xÚíXËÛ6ƯÏWh723|R€í¤¢$iÆ@“YÈ2'V K®,Ï ߡdQ¦§‹¬,2–¨Ës<ç^’Ă?IÉ”¡”ɨØ]aó´ưÙ?̃ÿzEܺ%,\Ṽ¬®^̃ Œ2œ‘hơ86µÚD÷ñëm¾ïT»X2Æböj±ä\Ä·‹”ÇǺèʦÖoxü^=ªVƠ…Z,©ÄI3¶xXư~ơËjØ\Pg"íWŸÁMiD€·‡K„·pa-"l± l‹._ÀO FbƠƒúg؉HŒXÂÆ…̃ç₫Gxù{„‘€ưÍ̉]Ä')üUEwW…Đ)PJ˜é Ú2¯ö€…ÄMÛ½|nËÎà˜†¦a.S†™Ù¯ï!Ölkß–•z°‚2!¨6°d:V<ˆæÛú¸[îÔÁm–Œ×ñ4íW₫°X,p<–à16!P’ˆ~ùXÀ…”¹EÍúShc’¢”fư¢!3„"!;›€Bp2‚D‚AƠ'Pö&"Èw*Tñ|Ly†X]SzALÙ×CJÏCêÛñCzAnö­*ʃb¨f¼h̀%hI)A\ ?CëéÀơqÎÆß0 „soüÔsÈÛ°רDÇ‘¦ú8Ú‡e}èÚăNƠ *ăÎóöRdà0‡3“©µù[½?vA„Ü‘’÷yÓ” Á$`X©)Qnyơ„Vöh¹µ&âOªèPhó¥3i#zA2/”f.n«7¼‹ûÔËÛ¤ ü½¸¦ôä¼v̀†Í£ƯPC@Á ¸Ï—L"B=¾=v£ˆ/¤ UƯ±­]t!Ïi|Üél¯Ml­Âq‡‚ÁSX`ù…NƠa\„#"™_F‡¸Ơ¡“P“ĂV&R”d¶ºgâ₫Ï&ßäëJ9‚QÖ Q9#x¬;¡cÎ(Sîw0„₫aN%Â<='+1OV÷!” Dv0³Ï»mÈŒá¡àCÈÏ΋Ỵ̈¾f7m>H³·P`D ™̣äÙ#;B)̣æÿi₫¾ĩ·Í¾Îw*¨ß^/̉¿fÿ”WÇpÑxú7[4̣ë ™ÄĤ‡yk%LƠcY³Ÿ‰›Q5Ơ>æ… R₫²6J¬˜´f\ ‰]:EÙ*K¦¥a_‡Ç!Ö†<è ;í«»®-ë3Zdwô"49Đ¾%Hb:‡pør‰ù¸Ă0œÙñùÔ›B"†§Û¤Ơ‘€ŒËMcxZ@31*;Ï(1céÄ5ó¥‰ek#kƠÀ^¬¹\”íÁ¸~` £ˆv(A»̣ø£n´‰çº T‹5çvÑrÚ•êđÊÁ¦¡̀~|¡}oB›f$~=W[NsGQç¾ÎÉkeUîT£w%B¤¾•®åé3躪¢©7®hÜp»$®̣\£ø¬̀Kwˆ›V=-l§t×5û› "äÔ_¤¦¿Hă~‚îkéë×fưxËăÁ÷ÖÍàï hA\樀{ôPÚtjè:8"öÇuƯÔêú…ûáÀ×ĂƒÆàÚl®Cîü M˜s‡ÙÏ»rîF>ôPR÷Pö—Öá÷–iÏxÓío+[a¯{äÚÆ\$€{ü3₫d|@Æ|d|èîBÚæíÆ¦¾uy|}hMđ‡áÁÀ3éåíéj«‚ó‰› “}¹Í«Êb²ư¬s«>1y]¨¡—  c$O²dË@ß‘^1l{vGÂô}M#ª/eÀ·É HXE•̀¿"™đƒK¸IЦg“+'[!ª„̣8ÍE•úA©/¾>€­:«.äz =ù©Uđ§éL”±a&Fpb¦/Ưï ÿé{&Ăßö³ùÎ>ØæO¡4Uóä{\W= é~†ˆßhM®Ô¨€µQ-?ÖjăŸAÇÀB¬<Ñl̀đx²†ƒ<Ơv«₫„ÿ¯O\Ѫ|ÓÔƠç90ü×Ä2~{çâè¶/ʘđ"ØüưâF²§ö¼;Bü)Ï$đ¶ư1&À`xÉöMÚµ[á꺨ƒÚ|ƒ»¾âDi‘#‘Ù 5H™ÔR6hĂđ¦¿˜n¼z£Çߟ¬ñ²ZØ )aÑ»™yÅűmƯe‹¶́º‘üÔÛ”U?dE‡h>`±₫Ÿ,µ endstream endobj 1344 0 obj << /Length 1598 /Filter /FlateDecode >> stream xÚíXÙnÛF}÷WyD“Y¹(Đ8­‹măÚ*úàø–FTIʆûơ½³Q™ƠMAq8s—sÏ]†$Àđ‡1 â„¡„ÅÁlu‚ơj}˜ß»o'½§Ó“WgB£§$˜.ú¢¦óà*|»̀Ö­¬ÇÆXÈ^'œ‹đlœđpSÎÚ¼*Ơ^È…¬e9“ă q”†Œ¯§ßŸ|;í” *à́‰–ºỪM"DbI#„7&ÿ´Y>´²ùuœ°°ÎÛV–Ê–@Ä( &„!"ˆÙYinVêß0< £<¬ÆáơJÉ2÷Ṽó \Ël^•Åü&ZÇÄ(¡ñÄ"xÙVëÓ¼ —́ÓÉ: ́¿Ñû•–¶2«›FjØ~®äd`–6ä À¾·«E-U¶m^̃‡QY•rổ>È;µO–ƯB¥íÏGC¿ÉÚ̀ºĂD¢À̃ïÊc7²×Xáj’Âü4ûx˜tˆ:ơ‰Qmæ™:™¤D?Ơ™“MHØá¯ruÀø³¢RÖ̃¿­tÚº*öPă~ñÎ/æûÅ;¾ Á¼̀êù½‰Œ]äᨩ:tƯ‹},:ÏËË6k7 7ZÏ65¤›öÁ±ÆÂ°%ï:/›-À¨ºÍ/¬UlBÂcÅ7ëô\~À„—rnƠ8ÿê,¡ †!U&NשDÔÊ„̀DÇQNgÅ„аªÛ"oZ#ÆOh¦̉+ç9J­˜«3•ɽzĂ³¼×æ|„ TªÍp°9ÛÓơ÷1‚8`w}^FÎHϾ÷í#„‚K̀TÈ:Dw]¡#FˆÏ«¸/Câ9¢¼Ûô"+CÂ|#öb‚9—kÿHî²¼Èn 9L”"̀á©HQÄ…O– Ùnj—ĶÄh˽* 1¯Œ{6ùuáO—Å­œµ.‰sÛĂÚ¥+M+Wh(±±Ié(56½+×:àl$P·˜mĂ#°kóáÄü×,+U÷ïÍ“6[/[³Ơï¾ÙêY ÉVR=EafW×µ.ăwù\·4µTVVj}»YÙÊØh´ơÉQ¦Œ1±ê›Ógª“m¶^öc³ p»̀l\ Œté4Ë‹ªözúÀßoÚâé'ßWSIẽ10÷éÔ´u7̀dQ8ềNư²Ÿ`æf+Ơ€å”±— Æâ IO-̃—R:º7Ơë!7¹€Êv~–àÚR5/•ŸÉÛCªÓF]9y1$W ˜vđum̀8?$’«HŸ.R±´—y1™bGb8jÉà(s=55 ợ\ưnƒ"”¤iwsèëJ7àôpøïǹ \nPÿ­›¾I²0 h®fï«k̀á%ä í^o]Ê@åI\ül&tßA,…ÅbëC³Î_-fEåø¿Ó#’±ÔÏĐ7kÙ qH2‚£^€;GØ7˯ăBâqgđu{¡ºù8Ød”Đô`KHR²½¢óVgÓẹ̈üɨYU–̉à2P#†₫‘­IáÇá2D¡xơG±‡ÅC"°gaĐ9…7[öTj’ơåa}aUkg”uÂH’>…?ô üa}à ö+PQâ-æ›Ơêáø8’"Ávxù̃DYúÜdOà&Ăl˜›»zí^Ơñ¸«lÓ¥kgîB‡mÈ6.¯Ù1í{ïN¼đØà®r¹nbkRëqåNơéÜY­³6¿É‹îÆƯ¿Ư₫øFqlúĂ›Óƒ7¤~v±c²‹đâơ,µY‰Âi¿6«Ëâ—H¬íẹÀø®3kkƠ±™ơ<•™&BÀïb÷÷ðS1<^‰{’Ø̃“ü÷Á©+¤8ˆ'§0óˆÿñÀs ăˆÏ´®å,oº̣»3ÑDú»Úè@É‚ÂË?ăÊîÛ¼œ«!«#˜†Ïï·/Ê™U›̣ _® Ñ!‚óœ׿?M­!t|W&)̣Ïú̉ô/‹Ñ^A±Û!ëzƠÜJ‚+H‰6ư+’ÿÏG{B  œ&»‹²ùàWƠ•±Àíá₫íyQW+ï;A7Ñé{u÷‰ÅÍ'ÍBgü endstream endobj 1347 0 obj << /Length 1324 /Filter /FlateDecode >> stream xÚƠXÛnÛF}÷WđM$PnöÊK€E/’‡&MôÁñM­dº¥’+é×w–»¤¸̉ÊfĂ@a@j8sfÎ̀™¥I€á) ̉Œ¡Œ¥A¹¹ÀƯƠf˜Ÿß]kƒa<²üy~ñæRˆ€`”ăœóåØƠ|\…¿Ü;%›(fŒ…́ms.ÂË(ăá¾.Uµ­ơ/<ü,—²‘u)£˜¦8ÉC&¢ëù‡‹ßæCpAœMDÚ[ŸÀÍh@€WĂÍDRđI„7ß×»½juxH.'‡ƒ˜¤(aÖp{Å" ﬩S’#µÀƲjM “í—OïÍ÷΃ïdÅ$TÈ4¶®b€M„ñ×VÿH_TJM³>êïûMD³bÀkÏÁvi0ÜG½X聾¦¶æz#‹̉4ñđ+øW¹,ökơÖ\!®?LÛÀ$Á®‘eƠj–=`¹f(éÁL˜‹B6Ë\lo0’'ÆÉǽz;f,µ_o9Êx̃ƒê¬:ë9²½Ëô³₫¤{†%̃î#¦s²cÿ÷0Ë$@¿g\ỌƠ5đă‡#1:ÓMÀ'º¦ëàËžy'I†¸W¥¹m…vW½Y>4•̣T–"ư¥¦ÜöÙ(+ /«µ¼6’4 åBPCƒV C£×ûÍÍ7%û&Mƶ"A<âGàF0ƒKđ\·̣Aeô¼úhàƒÑöæÎ™d ’½Í>/„"ư Ï‹d—àd„ˆx‹9JtcŒ[óƠ »á‘ ’DL©)›PS?]TvZTב[Ô ́éîQ‚N=ÎQS¢¸q8úSS¤+çƠX¬ÂªÅ$vˆoöëw"«ºUÍDm£åMôX]@H2ÑM¦àÿ‡åM·{úƠܵ́ôơójËWø–¯x¤öTû¦¶eV_Ú­¾Ô®>nQ0¸ ƯpUP²öă"¼;Ï™–-ñœ…Ăđ^`á0p™åä°pVR½Ê¶Ñ³T*Ÿ¨p¨ Ç»fÀåj“Ăá`̉¢,}\Q<» R†R:‡̃ï)Ă²’ë…¯ ºEöâU`'UøÎƠ°k¶;Ù¨o^A‡s!O :qAG$̃A¦Fdn¥™/ÉΡªú¡ëgQ§s¿D‹Ỵ̈N"vgp²,êå*2˜à¦Ø`Đ›¢è-D{8èéîuw”Ơăo÷úÅ7₫y0ƒ$èä°ÉÓaô<î0wôƯĐ„Síˆ$â?äW®‹ö̀saĐ ÍQNù¡9́!]ubyVñÉQ ëb#]†O}ÁĐ=²ˆûö©»]ëªé?ă¾Ý3 aæ,Àíđ(kq²pÙ?x؆ơdkéƠ°ÿ̉ûDYÊg½Ó„Z7•‚œ§̀û¨öƒÅ‚b' øè”đ4û@2+×ăL Ûu‹¯cäAJ_1áM«äb%ly8ke¹­Ư/“¹¶D4jzë-ä}Ơ«^;ÀµœèyTíÛç…6÷U§ú¸6ÀH+³₫¿zÿJ»êu endstream endobj 1351 0 obj << /Length 1489 /Filter /FlateDecode >> stream xÚåXKoă6¾çWèfˆ¸|S P è#Åîa»ƯØĂnLÇÚÚ’+É ̉_ß¡HÙ¢MçƠt ´ëAÍ|3œù†3$ÂđG"E#•2”2«Ü?mn"{ññ—âÖ%°0­üạ́ä͹Á(É.çcQ—³èsüă"_wº™&Œ±˜MÎE|>My¼©®¬+ó†Çơ\7º*ô4¡ Ë,frzuùîäçË­rAœ=é°únJ#¼n*Q “J„·ƯtëM×ưûÖá(! IæV~ZèÊ-ËÆËA)Iau¿jƯÔk0+uÓMáç>$™¸døäάË[ë›Ö|­b]”_0ázvj7ºÛ4•ul·Đöâv*Dœ/7î¶ïóÎ~µn¦$̃Ç“²Pà-…Ø’€‹ˆ°Xj̃Ü•­¹SË=µ²Wë zóå̉^Œ}PÚUlk`noÛ®Ù \#ç µçzw_=ª ­m}vÄ£)Ï~_÷ê‹.7&ßzˆ°?¶aCAâAJc&h>_áh/ßEqƯơ+WCÖáh]œüJ¢’¤—D³Ô‚h×å›VwÎ>?‚™ù ¡ :Í́ eHN!io£½đs;e$h€‰Ôr‚à Đ8àçˆ÷:Âïă!2E\ô‚0ÎvøÏBî¦)„N&?EÙ€ÿ󹉭Q¦³ø¼\ê++@” A{0“©\;6ËÁT«H×Ar1€êV}75©ïPÍÄ1aĂâ/XàjØ"¾•X_ I")ĐÈH ;AB\ ùC₫NđƠzN8 I!™+·¤-ÿÔ!D@ÎËǼ™ Á̉ÆtôŒlƒ¤KIÀq₫qpï–çM½²;rñá­%£²‚b"qg¨r³̉æº2„ÑóV(Dà‘—·o«Qɨ ơµÉîøk*É€p¶®,̉´0^f%ˆø«.z̀…ô&NÚØ•»ƯÙó ̃úèưfeŒ¿vô=.,|ø¡ĐÔCqÊgÈ{̃ÇÛOzo–Ư™}B°Ùñ0 :Ư “ˆëqĐ›́ ›y¡áWË6 †eSê1Œ¬^ÂÈœ+Ä) N6¢È`³«)¯DÉ~ºï³‘ÑÓ3Í1ñié¡ÙĂ,Bbd|€‚sĂ}H˜Àˆ̣ 0CÉjXqÛ”äC?JđŒ# Éû ‚ÿ?¹ô¡"u:Z Äăµ@b¤8÷́Bw̃ù—çL5:gîN£*#Δ†3Ăg1ü³yb”UÛå}×ăptHÚ×—!tŒÍ 21S›Æó±v;H’(£[Æ ÀÛªQ,ó¶=R‰ ‡˜̃N¾ Gr.¬̣•ö·ùPÖ®¿q"à-åoƒ^·—£…Û«×…Z¡¶¶¿PUU¼i]»̣‚’q¤è.Û†{¤Đ‰·œº s­PM{¬]lư~Ñơm<^å]a ^”ƠM°“s~5Ư¢Đn躨ó́å fîơú¦csjB¯P>NöÙu^6íṢơC/É”cKáÄ¥1â|b¢ḥ(dĐÖŸ‡t3˜X7{ï¶lÓºœ5FữglNŒ^W\.°›L®Ë®É»—@s_>nw~|•t¨åØ$»kơ2oJ»qÇÑze󳕫Œ\®²»¾/Ư³ˆ÷'̃°Q–àưÀ”³¥^”7‹‰{î¤ôÏA;(¸›¼Ô‹¼Ơ¯k»‘¸oïTO0Ö̀‹¶Ó³=qéâ`̉ꢮfưt¬­‘.­̉çÎÅ̃ו>2Ăe)%ßb†C€đ«̀pÏpn;ĂI_̉1d0E|väˆñç2I“NµY]ßw[öO™ĐS¥éh‚‡@ÏGàüc¢„O9ư7†»®̣eC ˜f©̣óÿ“qª15<ÊàKêy£Œ®>d˜*°ăÊ ôn‚a¢í/Au¹ö endstream endobj 1354 0 obj << /Length 1390 /Filter /FlateDecode >> stream xÚíW[oœF~÷¯à- …Ù¹0Ă©RÓ´®’TIj¯ÔǪđ2ëÅƯ…-°¶üï{æ<¾5‘úRåÁ„=œËw¾ï̀`øG‚”©dH²4Xí°yÛ\öáä×#ấb0ŒG–?-Çœ£ g$X®Ç®–Ep¾ÛäûN5Q̀ Ù›(NG2 Ơª+ëJÿ’„'j­U­TÓ‹,dit¾üpôËrÎ)Gt#(ø#P4ª;4•«²¨ »ˆ¦á…îghûŸ„ơÚ\hƒÛNµwYuª̣çEÓ!Ÿ€üL4†2”íiø£®Œ†+¨₫\GŒ„ªgÎ߈P• °4d8;ÇA?~0âóƘî‚%DÂÓ68=úƯG"$J¸qE¤° µûra°}['*/¼½‘)b™0•0î>)°±Xx\nƠ¹u ̉€”qN LS9“öÚ@blÇbr ̃‘ÖBx?;ÇÙe 1ô}ÅûRHMá₫W¾đD"I¾ö¹!q>ø¹iî*™&\\’">`c¢q!Â)Ä!û‡VƯK¯*́CxƠ-¡ơw'f ?ÑàdßÔû*ß)_4%äC_;»ÖúûƤO ”Ă¢Nóy;‰ U5†̀´¶ßzR«f¯ü3 ÿËImăB[=û NáˆÁ7[O Đ~;a椘l'Ó˜`dغÂnX4GX 0Ç^•o”}˜a_êº́Ÿ‡jƽy§÷;¥p†À̉w»·»Ÿưé´kÊêÁ₫`¿_;û^ü̃ù:?Àá³0m&µưûjqĐ ¿̣ŸL}xv2ÍØ:)> stream xÚƯX[oÛ6~Ï¯Đ£ D,ï¤́a֡ŰaY†=¤Á ÈLlL–X»¡L2Â$8:Ùåư}°7ø¿^Vfµ¾[y©&DǾ% wÜ!Y8E¡\‹¨m«¢3/±ÇÉ»€¿_™ƠΓ̃aÂÛI»EF̉̃,ï̀ԸΔM½tï1-8Ûö°™^®‚umM€"¸-Êpú²]¿·/‡Âï…ÇwXàÖ˦®>ÀØ#_½Ö41¤Îf.#Ü¥.£)©½ åˆE&$M»íz(¡öuA$œ°Dr‚¶*®®q²„ß& 8ẵ‰n8Ѱª’ßÏ~óµ3µ€€8Èé‚èíäS2¯4ªÁ4æí僽W?7Ų¸©B¤ /ØĐ×A‰LA¹Ô9Í„F2`–Û>₫5:Qâñ‰öq:ˆÚ˜)5VÉ…69è‹i"i4‘˜‡™ÂHṣ  »à]¿ ÙP,-ê¥ÿ­5•)†ÅP„WC嘮l×Û¾iQ¬*đ´̃ÔÛ]ßc󱱨¯d|æøÔ%+‚ơàx6Ôs×ơPÊÍmL½¤ˆè}́C'ö…ơÛ~¤4s…0K„ˆR=¯L®ö…ÉUlZ˜ÓĂ)†‚„, ÉQ³xXVEסx»1¦¶QNB|Ươ£‹'üKS›çÛXÚ˜ÑÆ\k”ËÓ´±Ơ%U0×¢Ïó]œŸ¦‹¯b})!ËrXP;M@rï¥Îcz¤Ḿ¼lvuÓÄ{½°~ d°á`æ‘)6h¨Z®Aúe¦&LQægê(êAÜÔ³PEr À¦Xua]t)¼m›ook«'Àjܽ‹̃¯Kó$©ÿ,qˆµÖ'Á!«JOÅ¡©Î3WÇTæĐcj3`•î6ÖơŒađ¹¿7nNëMç£Ú7‰ú̃l¶a<ñ/¹‰Én?åùi&äåM »;g¬̀›9)—ăaƠ YZ5“”!%TÂD“/̀å4?T!•s§`r@IÛñ®Í¼«¢ªü²5ư®­ưÚ‡ÆË]ØÈ+yN¥‹•ẼiÚ•¥éºÛ]U}đ‚v<5v<µQ·"ë:V!›Hq9F<—X4ơ(ÛCN>¤̀Öú—nB± ;Ƹ˜qHƯóúY™Mg*ßkƯ~˜­̣̃Oé‡Ă„¥ÇöZ…»µ‹oñÑ₫Ø¢m ÿ±TôŸĂp I„xÙÄË ²8T̀)ˆ×ê":ÀĂ=|*™2ï”?æ̀[GyhB2c7#AŒ”"Ÿ6j& Jej’ ÄóDÈr€ùÙĐ₫§£óƠ…Ơ1A¾đ!G•›₫ÏäH¹B,W§ G«@|9r|ḶYܬđù>hqR ˆ©Ï§4y3²Ử›zZ9ưp+đ²y* Æ~"M₫.jw½4âÿ\6›me,jœ[9Ç> ØÇ¥­¸QââsØ”rϵS%Éùlếôlj—›Úµ‹¡]Di5p–ưƯfĐ₫‘’}Ü'Æ>ƯLikÜU[ơñ*1*ÁàVMîañ‘Äb `¹ÆáGĐö„†¬.™“ñ]½¼8ê;PŸ†Úåcßy"ÂÄ£”41tvu£Ÿˆÿ*5Ư·‘ƒP ư,9Q;t/FN³«'è€V‡Á¾+6œà=ơå7ªÂƯ¨v§¹™b_éiÈ3§à<Đ$ù‚”7®¼Ùį¾N³ÿå¤È endstream endobj 1360 0 obj << /Length 1337 /Filter /FlateDecode >> stream xÚƯXÛnÛF}÷Wy¢€p³wî(Đ$­‹A/úäø"WSTIÊF₫¾³»$EJld;B‹c[Μ™=sfÖ$Àđ1 bÅbq̃^`÷iư1đ?\ưtA:» £‘åëåÅ‹K!‚‘ÆËơØƠ2 ®Ă7›dÛz1ÆBörq.ÂË…âá®LÛ¼*í^™µ©M™EDc,uÈôâfùöâÇå\PgDÚ[ÁU4 aÀká*‰H >©DXpù×]»Ưµ˜"#É:Ë?¶W…> 6»45M³̃₫÷t‘°ºƯÆ%JÂç>Ùf›÷Éư5 ¦L!¦¡zX! Qïơ 2xø6ÀˆÇÁ½³¼ ¢Eđ₫â÷¹3 œ"N•sÅ©‡z_ç­yUfW&É>`á‹t¨7IQx`µiw5à́¥Ưo²Z@–Ÿ[ÓôfI†|yl59b\Rƒ]äˆa©|h†^DB̉pi ̣æ7đóĐ¢øÁlk“&­ÉÁå₫€ âp6zï ïëû ÜĐ0m“|»[0ăªZ@Ḷ@ ‚c‡U¬/+Gœ¨iY§PH,"̀ù¢}]ÛtûbUcæøBFÂF”Cxé_¹ú³1ưYx™æÆ;q@̉Bø2K_.—{·6=/åØ ÈNđ`ôƯẨ?Ă’x K$¥èÍíÀÅæ%ëªƠ§9OD!EơÈ™+C¤4ß“ˆN,¶Æg¿§…mª,/÷¤'ñ€mÊS‡Ê’!ü4ÇœˆP…4¼f‹¯˜Qˆ>…B’À„…BB)S²§ĐLÄ®Ù̀R€`æ^̣$êt5Kơ A b0¡Øû×`­E„̀Ü=†s¹XYQá¿OewÊs÷Y^ÂPx6ÛMq¥N§.GŒt©“o)÷ÊMÄÙä%E14Ç) FŒÍỊ—.×ơƯ¨á¶º±T¹ÙÚÑó§ưÏ´̃bµƒ ư¬j˜ºù§©1júŸËÑ@×sVe*ă øl8áh"T&;>̣Ôé€đ/ÚXö`Ö`‡Y˜XíÇ4L²,·r—₫ó-¤—ÔÉ­±ùùƠ ¬̣¦{ZW¶wyæĂ“j½?ÈQ?jĐx5÷³¹´hPÜ[8~Ïy‚ÙÂ…ø¢#Fº×äzÛœ†ă)7ç‰QD(}¸'»tamÖ¼*‹Ï¾˜u¶º.y÷YƠ|Q{ơt€­v–ƒưf{Ÿ÷;ÔÊn°aÇæNÖá¨N“ôákç/UÙoñ¡…èFÄ{Ó­oIÑT/çür˜F|èöÆÔyRt+mƯ¢Ù¡ "†¡úÇ3•=e¦2)ơYfªơ%•:©cbO»Z@,gïª$KVEWºñªv3'˜°¯ë¡?œFB¨¥B”> stream xÚíY[oÛ6~Ï¯Đ£T,ï’ XÛ­ĂmƯ2{Ẹ̀ Èr¢Â²<™J‘ưú’,:td;i› Cdˇç|<× ñ0ü/¢^3³ÈËÊ3ܾ­¯=óáü‡3̉É… $ß̀Î^¾Â#%8!̃l1V5›{₫Û›t­̣:c>{„œ ÿ]s¿Yeª¨VúîŸç‹¼ÎWY„4Â2ñ9.gïϾŸ ÆHpv ̉^úܘz„! x{¸T",¸Ë́E¡Ôÿ¶lÔÏTÀă6`ÄÏ{P –H„“¼UøĐv..±7‡ß{  ́}jEK#Nbø´ô~?ûÍ…†DÅ„ÙT¶~¹¨Ö€́¯4€]ŸÓ#̀`¯”"):Ç_€“ÙØÉ̀W,óK£@F!(‚j!ÓNâ°µkë|ÓÙ‘c1p)ÁƒĐ7v²ĐzTQñ±8é¥ÿÄ»LsD9í…ª«.M$†°‰‘J&á(’¤—Ÿ7eyç̉ÊࣖZ‡oCB$ BˆÄH€pб1½ưƠ|ȪƠ*7.7Êk#D ¼…V]éDó?ºív²!<¥¤fǺ¦è,fM ơĐÈWË€øw¦Œú_SóĐ{×"wæëÂÊU™gQ!ñ× ¤®´đm wÖo§\§ª¸*–…̉¯;3ửŸ_ë›ưôúÙ‚Í!‚D&-ѶÀä)&„êç) Lë’4غ.V€ZLWXüø [5åƠr—™ˆÇñn™i€=8;‘%,åô´BÛ©(4:”́ —B‘C1ª¼\/S•Oo!´¯´i2Y„€$qW„FøíưºĐN4Ù]ƠeªT>7_7 ví®B‰h´o–a}XAk6Zc«½Zë §KómÖi™Ă˜ÛØơ1´…bp²+Xw±HKºjéø«u£6®M`X!Éøt+! âÑz«Eđ-ÄAƒ.Bh™B.»a§m‰Ă=ØVL§®ơ+ï…lÇ;«•|hÔÈ;âïü̉”º{]™¦Ư‘‘ja<éŸn ‚Y@悼RưX;´«E§t5è `ỎƠ´.Á訫Ơy:ÿ"ŒaÂvMÀ²}/ÛÂ:•2°(Ăt_iƯ€™=ÛÿƯnxdCßç.H-ơ“₫ä´åÀăæđ¿;÷1iq„¢ugÅf •öíI»/8Đ´Ăü˜d·AïFçÂ[ÖÉøÙ‰“z²ªY©éD¸4‰0•-_bŸƒ/µv÷0Ă@r Ûÿ‡c´WQÔKäu]n®¢–|Ÿmú9ªÿñÑṿÚs؈“̣1M™#n;=â? \ÔUiqQ>æ¢ñ.*"Dà•Eq;%÷:®í96ä΃„đ6ăé²é†Ís_g̉X¼M£ị̈EÚ,Ơ+ó†`¬£́Ú·€îtôÖ¬/¯äưæoáÔ€ÜlÙ,™„\lÙ@vLfµR-ăç¾Í kߺOŒ2Ï6Á0¢lèv ø†ºu–!«ØVdK—‡Ë®t̃êº|H·´Tµ1_æ›Mz»].@}¼ặöTŸr* 4B Rû)NZÉèT O7ù9uÍŒûcpÏæc[V,'Y1æHêÜxªSÆñ—G{*ô墸*ÜøÄ£UDŸ‡ºH"Aö]0¹¦1uÛª́™ƒù{¡Ăf1 ¹X{-ÄĂ,>vôƒ¶ÍÖĂ'ÊפƯ;Ơ¹jê₫mŒ›ö>^ó¨ă¼CÁà­¾aWư´ëî P?%₫Ư.—` endstream endobj 1366 0 obj << /Length 1500 /Filter /FlateDecode >> stream xÚíYKoÛF¾ûWđ 7û^2@ i$‡6M„öä@S«X©$ª$å ươ}âR+ËôĐ€%S«y|óøfÖ$ÁđCE•3”3•T› lŸ6Ÿ÷æíË âÏep0üq~ñä… Á¨ÀIæË±¨ù"yŸ>¿*wnfc,eOgç"}1ËyºßVƯª̃OxúV/u£·•eTaY¤œ̀>Î__ü<” *à́––ö§̀ÍiBÂ`oo.• î̀eÈø2Ë„¤é³l£iƠ•3x¹1’ễ¨¿MDaÄ$·bFÏû8YÀ‡¯Œèûbn8ÉáƯ:ywñ[̀¢Ê MêªƯ“Oº3§`Ó#̀ÀIJW¹;ÿĐectYúbµÖ©BP!52fĐጲßm»f_ơªäø$g¨`¢?÷Ă,#Xàt°Kâ±]p˜€₫đ8SÎå´?^Æ$‘å´I"QCª$,‰ ÷Ça¹̉ëE ¦ùƒĂÀ`Ơ†0<‰! 1ÈÙ5ơN7ƯטY#JÈ9L3" ©A} Z(»+í*×h2E›‚º•nƯĂzéO;öM}ij*ư¬«9maæc›ĂJù®ñj»Ûw­7«› Ä€ñ)^ñ¤ä¼2gĂjÛv¥m1̃ĈxIɇ¤„@sÛàåÚü5€"‡NC ¹‹|Ú¸êŸ!HÔ°₫CíCÉ$Ê%»ƒ‹Ơºl[óÂ2ÇCzXß hÆ­¯1 \X¿B·åF‡1>–e ræ%f`QA}»úußb-nˆơWzóhù8óïèÚs®ô©Ûúl®V0ázñØ=nt·o¶Aî3H !̉r½÷YUv}q̀Hz à&…øTX ̉›/«ÖË<èå^iơNÊ­\¯câ‹’ –îO×ë÷îÓFM°g)"Uï´îU´ơÓæ|ÈÇg·+E ßP»D’ùn¥–P§$VÍG̀ÙêxĂÆÍ̀‚¶cÙŸà»Ñ¿êÉ¡©WÿƯèHäYY«ƒ.q̃£HÊâáøQ‚·1Ú#ˆÚ"ĐŒWéÁª{³}ùùû³³äŸCÈUñpäÿ¯ƒp̀ứ<ơbÚƠß:f Ä˳ḥIJ₫GóÍPNˆæ-&2ƒC÷u§ï3‘d¡#±y E'%FtûH&ñ†` ä¹lê‹ïüùÇfjjö ^èá]´• e‡¦o›àúÉđÄŒĂƠUÏcÎ0oáa¶œ™‘t1§ƒ“6ƒFÑ Q!ĐRT~ÙoŒó—QÇdÏ'\ ä_÷C¹@fƯå6_̉Ër¿îº'cå¸^ye›=v|đ¼¥`Ø@e$\đ•ÀîÀ'N jN̉ ƒÚM!½1×ûúÇ@³ƒSÚáH| IÓ†)„¤,¦ÂIă8:́4G;ºYÁL³<ƠĂÎzC<·Q¤‰o”¡°°E…Vư‰k;3GahúIb®=ø]8ê¿éM<û!tr8çHÂNÀyĐCß}ç+•îw­¶v¯À*Ư·ŒË M¦Ü^VơëùăDÇ|4e¸{ ¿\BÖ¶§̉6ÜHưbÈÓMÙUÆá«ƠöStUô›©Y§”½4vC³úç½epwkVB¯¦ªô®7êăl².ïÊUÓ̃&ôo¬$ÓÚ]>ňÂ]¨đëê#sMñ(†(̀*Ç™Ûßn€‹u3ùlHÜÖï¶Æ©?íf{bà°ºLn…¯•G̃Ô¾ªÛî´uA[;¶Ñ‰p é½̀Ộ¡äøXî"Z7gÍ¿ơƒ°ïyŸ Ưj£ë}÷ Ùà¿9¹séÇbo™®êí¢Eî¿›lơå—ß"t¹ /a.×cφ¢¬ `Q?Çüf!D endstream endobj 1370 0 obj << /Length 1667 /Filter /FlateDecode >> stream xÚíX[oœF~÷¯@}1+…ÉÜ"Uª5Ủ*IK}püÀîmR¶,ëÈÿ¾g.°€ï¦Ú*­,ÅÄÎå;÷C" ?$Ji”*†K£Ơæ Û¿67‘{x÷ăñt &Êï/ξ""e8#ÑÅơƠÅ:ºŒŸßæÛV7‹„1³g‹„s¿X(ï«U[Ô•yĂăwúZ7ºZéEBS,³˜ÓÅƠÅ«³.zá‚ $8;QÓúºF„! úu•D$T",¸Sù;ƯîÛ‘?µG I‘ḍu]iO–>$KUæÈ̃kí́ÏË]ư,Ä— ¤xßYúïj@AÅ«6_À¯;óîĐø½7‘¤ Đ]f))—W8ZĂËWF<>YÊMÄ:•Ñû³_BN#©@’XN’§D»Ú>½Ñ-rêQKf惄k*Ư GB‰ÔÀ¨5~Ư- ›(QI  fL µ³#NÔØ†±Nü ü,/ÅÁˆOMÑêè4¥HÊ ¬ (문„ØdĂØdñ‹¢ÔW7” A- ̀Ä—ߪưfyßê.räVHÄ•ê(¿]„ÇƯ$ê&À!Rtä€6¤G”³¨^~ & )Ú‡Ö“B‘=ŸuN ¨ E°¨D‚ g e\Cù›A…¬ŸÇ”gˆ©́Lé ˜²ẳ‡ùŒ!=Ñ7íư62QBù'¡„fj́ _ ǹÙđÆ¡,¤cÆçà¶̃míü|ñü­«đEµk›ưFW¦œµÁª"2p§đUÅgđËjP‹³Gjq½4•'₫Ră´÷F±óƠØ)æ5d¦V% ÉM<·€‚’ ³²<ÜkXŒÿÔ‰¸ßàw¿µ"XÖ¸DLD?q¶^;ùk0(ëË/¯ƯÛªnƯĂÎà`>Lc½*>`Âơú‰÷§'Yëë|_¶»̃®>Î(Đ )̉ÇÆ7!µ…íb_¸0QAn:»8ʬØp cYD¥đx¥̣s[£Û}Sy«­²ûÍ`Z:°Rí]Z˜ôê½̃êj¦·r;’z+s½ZHA&4Q1ig?×ù:_–̃íĂ:ë6·±¸P̣ï@±§n4/5Ï\á6i·nØí2\₫©ª ‹OU—ÍÛm/Ålbm¡wöèjS™ûµX$4ă©4<@aTXøƒeÿÇü1#ñk8h4Ūw·‰ĐÎå,™öaÉ ÀØwûôuƯhẉmN¨GGV¸TÀRm)/nu_üú̀ÊßƯB¹wn«íĐܵyµ̉ư&ˆ "¤o¤'Ư­©Â(5ªÂ©ô3ïÖ#ñTqên¿‚M[₫ôD'ˆU™w¥5÷KyÛUr0d®R †>œ-Æ‚Ähæø@aÖá“ú[³æRncö„#ÄЧ̃Mæ†%âzåá6ß • °²timĂgË~Y^±% &{$yÓâ¦êYßíDËĂ¥Íhʱi““lz>œk†ç ăÜ= ot¾®«̣¾›¦% ô›—‡v%S©Á_‹ïGŸiÏzT*ënG›ºƠ£‰tºï8ª9ééTºÏ³?Ø,»ä endstream endobj 1373 0 obj << /Length 1658 /Filter /FlateDecode >> stream xÚƯXKoÜ6¾ûWèf-1âK¤ ổ )R-êíÁ5 Y˵Ơj¥uưï;©efí8Û^J g†ß̀|Äđ‡A!)’Tù₫,î6·Y\üp†­\‚ÑḄ»Ë³×o9pŒ̉8ÅÁån©êr\…oî²C§MD) é7›ˆ1¾ƯHöŨu¥Ÿ°đBíT£ª\m""â$ Ư\_₫xöưå´9'qFŸié(ư„¹2AX€N’ ˜3cr£öu§îê¶Ó&\ $ˆ0E˜ă¥€qi‹¬\hlµ]Öơ-x”p9]è—êùíî”q¿¾ÙDœ‡©¼37ÎëƒD¨ªs+aCx—u«¶çæê˜ÇʶuU>À–Ä®]±Wuz±Lñ|¥_ÿg›feo})*ó VâPåuµµöö°£YíF;î7`]VtEu»z²Íº̀gÇ͆Èđ¡Sm¦fë¢̀nJµ³‘¯´X¿×ÿ!:đß ˆMÑ›˼oAÚ¬®ÜàđÁ›%ÓfĂí®6/éà}<”¯ßJ€I1ÀE£% €KD¥E8X#̀àvùaÄí‡ Œ˜q$Y$X¢˜q Å«ë8ØÂCˆâ°Éư ºbXª ̃Ÿưjë D$• K 1"vÀ„1Ø…7p©ƒ)£ÁW?ƠÙv ƠÉHÇd¼¶J’c”rN¯)—(I9˜e•₫\́˜ÄËx‘QTƠJ‰¥J†äæ¬Ï§ ‚%IºĐ„}F"†Øb7Aß Ö¹)V x‚R´Ërû,«¶æY£J•od#0ѲUm̃‡®n±DbvWú®µÆ¦KcuF̀)[9îºIƒñäx4æ&*WS xÔ'a9ž’&ïlẹ̀@3•P&¡¸R Åkh21!“""¨‹LwwÄ…TÅị .æeÖ¶̃È©B'Ô đ/}·ˆ0?áŸëJùơ²¡î;jM"óg$2²Ÿ$‘µ.€¹m,P¾T_ù3SNF‰±’¯5AkÅñ$ơʧø”áyƯWOňΈ½̃è¶~ íêÆPg戸ÅA ¨¤̣9e†<*3® n™y†3•O‹›xZÉlŒmĂ×E)åOÖ=œ[÷.¦n¶kê½ítàöØƯçøµÖ12$q:¦U%”¼°¹:ç:æÆRT¬b6ÇLˆú™ĐLn²®Sûƒåzæ&[0‰…oŒf#ôÎbåṿ¹c¬t°ç Úơ‰éÍVN-ˆ(›˜ç̃r¹bgom˜ª×=.¶jª]Ö—K ¹CîhfÛx;‚5̣H£9–ºÂ=₫Ó*½‡ Du¯7†íc¸,lû̉7x‘̣SµDú%›‰¡Ô®IüÓármz.¯kN+_2#N¤QÂ^ÙÇß4ôÉÖ ±:¼WºÎ¥iX©{³ĐÜ,ĂÛñ‰ú·hí9\™Æ‹±ñ›Ú‡Có¤ßœk0ˆ²&Û+3«KûÍ«Ư¸‘7Í\8 ¥ˆOk¼n›€üNb1h"’Ï”XG|Ö`N£>ôªí ÑF #áå™H$bP—-öè´ĂÖ£Ö¶\÷¦¶«T”eÑaÈ×J°„ÀóSp&­‰MÁ?)gz)Íđ¶Ư/†—aẲôs@‹¹Î{<¨" ó‚vÍv̀8j5vc+¨Á ”…¿é¢7K¼ Âö •U­3µ¸)íÉë#ÿÛçX˜geéï­ Œ¤ù̉ïëw^(ÂRbáíNLp< . |ù ¿ơ¾»}¥¯;ÏÛ̃ƒ% ,|˜c’Bư¬ƒ%’ ¼Đª8s[₫âlÁ’ö¢k–êúF'aËy¤¹1c$—Å.r¤eÆj†Ó ÆÖƒçVÓ]OÈÎÁ÷ʺơ¹Á^ÎÜü``=́ăYâ<+…é4 TÑØ²¦û¦èN9Û> stream xÚåY[oÓH~ﯰxr$2xn iw+X´À̉ÀK郛LZï:vÖvZơßwR@Ú‡‚ørü͹Ÿo%đG‚D"£(£"ZnÎư´½‰̀ŧßϰ•›ƒàÜ‘ümqöâ çNPä8Z¬]¨Å*ºŒÏo‹m/ÛÙœRÓ—³9c<~3ËX¼«—}ÙÔê ‹?ɵle½”³9InjͮïÎ^/ÆÅ9áˆ3z¤¦ƒô#u3aĐW©›¥ À$)J83*¿­·»¾S˃q¹k\ͱ@)µ‚ưrk¥<àaœƒ°Ó˺ë mŸ2·Y‡àS‚0¨g?lÀY¼́‹üÜ©äà’F;q™Á$C)¨V^^%Ñ ^¾‹ÄDt¯%7E M¢*º8ûÓFÎ[$q!4#'X¸¬®C!ƒæ˜BUs#¾*À¤(a(cS·iaí²¾1O®µ[¤¹¹o˾—µ¹1 ykß*í­ó•ûzxŒăv†ău±Ô×H¥#‹Ï‹:€-KjÇxég}[Ö7溱I½Sè"î3»¨Zêak¬Wüœ›[Kç„B́Rcï‡]ïd"ë>lU9„‹¸Û-—²ëÖ»JƯCÂ4›m%Ue=WµD‡úyC¨€ª`QÊ¢äÔ¼™Ä £L` ¥ T:ª¸È¯ Oà/6zu·EU•[ÙïZ«¾–z¯C´Û¨mZóBù^I^kÇö²3ÇĐ«w…}8¢µ²ÛU}8'9GiÙœÄFá:äxè )̣@(DÀ^(6BÍyJ”÷Ë` QƠ—àơ)a¶[^Bg¤ng¤ñ›²’W Æ(çœèµ„dZ«©+}'£Đ+H{‹«V¸j)ç¤|W! ­Í@e:Ư6]påê¹ñp0´>]†–¢ˆ²lØ6mÂñ—º iăáüˆ2bøØ6[Ùöï‹ ­(8¢XL–œÄçGøÉ8)ª]9Ăˆç£¦¡ 9TøÄ%~¬=kt¥̣4ËL·…ÿQôUqṃSơ›¢/¯+;ÚîÛb«:”ˆ‡æ9tîi_fc_nUCÖFèfÇÁ†̀¬ô₫ĂâơËñ«̉~w«êƯiØĂXÉm+—E/W¶³î¬VzI5N«RE÷cY«Pm'~UÍ œrđû$E9å“ùf}ẦWúQ­̉É™0à¦mxºZD72v6´ư KqH4ơ©¾ öcẁ.›º†Yªé²·ke³QƯye$Wr]@7îÜïiœ%¬2Z>ª«„™¯NÍù-;W—Ó2Ï']}/ñø‹jÀPwÚ²À‚9r£¨¦Í‡­ê×…À[ƒ) ¦ˆ́€•íH¾›ñ4ÖÅm>(Êv`–²·Ó¯L6“Éê „…óø/©œM˜ePà@¾h O¸S¬”+å“|ƒZ¿k[[3ƠĂ$gzxôwƯ(‘{[‰[ǯj-]´N7sÙd ÄsQÏB:q$Ș¹}¹‘Í®a©¹x)G4eƒDQ¯B(#‚Éñ Ỡpp8bœ#MR$ !~'_û&ĐåRQ0 MÁ Çíök Àî.…Ø¥@Q¢œ´K!P–8Ê?ÿĐ&E€N ¦[ºK1vƯd£`Ø¢ă} Å,5Å£ªËØi1R ’!á¶£ÄnŒTg ªÅ„Û¥ÑëEØGÀar­[cƒ7DwØ§ß QĂÍyçưl؆«·‰M•Æü8S åÀ³²ï>}ßÔrđ1ËY>tr›÷EƠ5/ƒuÎƯ“gèă.:¬w ,Rnz蛆ïas9̀6‘ÿ2Pi–är@äø®» D%TCxÔÍéR₫Y†¸§çÀÿ¶Äëjía–ë(ŸÂ5Ṿ.H[<®±è![ơ›èoËÓ¼I¯û¬TưÙA2“MmW)ơ/)¯±0 endstream endobj 1379 0 obj << /Length 1592 /Filter /FlateDecode >> stream xÚåX[oœF~÷¯@yb%3an\"UJ“ÖQ󶉥>¤yÀ0“bØr±åüú¹À2́൷R[Y²1{öÜÏw¾́…đƒ½˜xqBQBc/¿: ƠÛö³§̃¿9ÁF.Á`&ùêüäùçQ¦Ø;ßÎŨGÿơe¶ëE» (¥>}± ă₫Ù&a₫Pç}ÙỘæ¿[Ñ:›€Äa”úŒo>¿=ùñ|2Î GœÑ{z:J¸ÅÆ(圌î’…œiw‹¬Ï¤a+ËQŒhB@µ’ún#ơûÛjè.µtΓÀRNGéßC)Ë6C4B…¸vÙÅ JȤéTÛ}Ö ưn蟹LGÅ›™ÆF­U¥s‚eđ@æXKŸ©xT¥úK¡ Óç;Y?¯JQoà¡×]¯?ßÀ¯?ä/Ñë/\  v1ƯØm§ÍCîÀRö¥ùĐ C8¤ÚîO5Dcy:÷qŒ"J—I²¢!Œ1ÚÁ¼©k‘÷¢XÄ!ƯªÀÅRȧZºnBí%4 ÷´ÊGˆRbÜÜ‚\HưLölHü¬(JÙÁY¥ßï@kÖfWJ±îy*;óiÛH[×e¡\‚Oí¾âû`pÊQ”L}ñ̀0G1‰G‰RfÏ¥ &€Á÷îR”¢L‰kZ§?t.³êÎ^‹êM—&J&ø₫Ê4¥²M›ººƠÉÔí)³«‚Wï“đ½PÆÚ<í6¿d{˜tSV•é\Ơ ¦ïA„Ă4@­÷ïÏÊbç hl`/ïZ±x)– J¸û „v.«ºæ…K/ă(a.t¢-³j§&²i{ạ̈9ˆB($±=‡¬°ªDÄ M‰ŸÂŸë …ñ1øÏ Xq" ĂyŒ,Qơă§Đ+à³·^ˆ8ؼQ’Wo Ë®¨¼'¿j́µ=Â1©RÅqª=Rs ¦5̃ÀCÿü³èSŸ@@€ €M‚?Âj¡óƠBư³²Ÿ\øP¹X4e±o‡¼w¡0£(¥|†₫ ƯŸüZ€¿L*½øOû‚Vñ:ơñ±$9†è„‹Óéߌm)ªÂ¹ ¡ỵä¹ +¹°«\̀¡ Äù¤ Pw'Ú₫Ö™ØL¯Êú,¥6†¼ưbQJK@Ú¾~ÙlT®‡ÓlÑiå4röü/°¨Đ“,J6›"ÛDÂ$ŹͲîúL1€Ă ¼gC† nÈư¦¸À!nˆƒ‡‰Ç"RÈú8X<áE$¦6nØÖ I€Ú1¥*ăÇGœWY×!W€€Æ1,ÏØ'SáDVXZ¸]±À^ä´V¤`̃‡º`RƯ¸m40xd¤©÷ß8¿Éíéˆm‚“ù˜<0´)—™>ïLëç%́M&SưºưĐÖÖ PèÎa± æßiD.³~œ$ RkéB# ±XăØ€öö¦́ŒÎ½]fÙ”ƯÅlfzÿÛ51L§3C{ƠZVÖ8ä•Å\ă/ï5I8ÆˆĂ„P“Â’N’e^nà+MÀˆÖéy'V(“ü₫!¥`¡”¤ˆ„OĂ)(`DW)E+²âá:Oî½úfFÑ\|qi’ÇIz”J$4ÎbÂ₫ƠI8> stream xÚíXKoÛF¾ûW½„¢5÷E.(̣*’N«íÁñ¦Ö6S‰TIʆÿ}g_—ZÙr9,Ú׿ofp”À2e‚"A³¨\Ÿ$ú¿íMd¾üz‚­Üç#É׋“Ó÷œG8Ay’ăhq=VµXFñ›ÛbÓËv6§”ÆôƠlÎßÏ‹·uÙWM­¾añy-[Y—r6'Y’æ1Kg—‹'ïƒqN8âŒé©“̃sWS”€¿Ê]‘"œN’¢„3ặ‡z³í;e~\Íq†R꯭P>2 «e6m³˜D,Û~!½LùƯ‘ª3Ù*LjJ¹Z™tù\ÏHo»̃üueÔ‡\ÉÊHæỗÍx«­ ¹@¸:Ñ—FuƠ:Ù[Ÿú[i@×Ế͵uÚ8ËâuÑ—*àÛª¾1_SQÉ)7TB98 …9JSc~á¬\{ER¬\²”çÓ^çƒsV ¨Zcnzưp¡„ œSc÷³ÖD±ơ0”Ru"A˜ÙxqV¬å‹PB9Kç¹́½ô±¸†c6Ħ|×—*œ,.W•¬ƠU÷»ë‡đtVÿQ¿dB.εé9PÚØºùg'Û·E_vuiÁÕvæƯeñNÿ­Ă‹j-›mÿ©íÍÉ¡LÓ¡X\ƠÖ1Y6ơjBĂÑ_ vB®”çØ¾n²¨;[ö•[ ¼„â–™o\jŸ¶ư‘(sÖÔîÍbNá¹”î ́WPF°˜~±!À­ÂÇỪaˆ‚Ü… B’3‚0¼€¢—I´„/?F bYt¯%×Eä’hŸübơ¢§ă £œÚ:3…#\ሸ?½jd’CœPũË"”,FélÎS¢¢Dw3ơ‡JMYÄqHOâ`ÔEÄĂÂÈwIE$0$ 7ÏÄ($°mB‚‡₫ô¾­ú0è%”ê˜RG?Àt̀4~_­ä¥QB @9':)T±Û·ëíúê¡+Ẹ̈1!œäÏ3H(Oâ‘oiâ½d ¹ÿ ²!"Œ:¡æê[È0dG|G-5˜ Î=j.¥ă$¹„ƒIUÏ)ñí‡%úĂ9e9¢"?&§äˆœ̉§SJöSêëñSzäƯô›pÉ$ˆ`üÔừ 0=Î…½ #ü·º•¶ éRp˜b™¶0‚ wÑÛVañæ³Ă₫®o·k‹3a˜Îá6¹1^7˜?‚Ó͕¡ø[È5–‘ x¸Ă?ÛMY]²<@˜V¡Wăæ%÷²g³1öu¹†ÍØ£ă›̉ Û¬×xúT“Èz&ư#£–:‹AÂ’ñ˾uă@ªØô²¬¾&˜ÉåK{¥Vd)¯‹íjèQ›]¥²@rë¡<~ 6ЉÛÊ܈jSí2RÙP³aJ£đna‘ÁŒ! {ngĐÊ~ÛÖ6jí́VW&Y­ßÎ\éèe·»ơ^Ö¸–é±hŸk3õ†äȈäBîR.Pó ½ữËâje‹`ŒËĐØjI~ƠVûœ¥e@î›ñA (8Ëđ³x®ÚËe+»ĂŒ=Q7MÛ?Ûaœjÿǯèÿ)>˜â#Ø?¢è"d‹"ʲñ¼Óăƒđ&¡e¤øqß"A%>º;Åw£ ̃;& SÏO/C¡<Ọ3&ªƾùOºmó´ß¸Ûÿd{­@½TĐ-™¼ŸfY. ŸvÚÅ7Ÿ̀…ƠƲ®=ïqP€Îû&»0/C₫ưè³»B›R0I²CrSGÍnÀ!¹p»Ö'l˜]ë™n »‡kq¯„Fué§.C4™v”“. f́íµôàøÈR BJ§²¿6"§̃¸>^ܨñ/A©nyv{¢ßêFi¸¯]ñm¶6‡ÖHf79zÖ¥4Zœé É8Ö1̀gzbáV ˜sŸA3ÙV¥½›ƯÖÅ“0ËÄn¡àZÓ{å|á–l°V‘f oC¶ßƠ ѺO†}¬KßÊU1¬ÇKsàµđ›¬/|»ºpT9`±[é,«nG£mƠÍjØ.Ü4Đ9Ü®½]iâ´̃•̉«@àÁ*±̃ÚkÜßM¹ƠÆ,ÓZ_†NuØç%Ç÷OĂqÍIi€4ûÏÛÂí`MÏåê­ë ½³¶}Vh,rX  sỔ…&)´ª©Á¡+|̃ÎÅeáY=€&ƠعX%bp»\1 Û?›`Sè½C± ¸åƯz¤] 3$ñÚf•œÿú¢ endstream endobj 1385 0 obj << /Length 1587 /Filter /FlateDecode >> stream xÚƯXYoÛF~÷¯ ̣b 7Ü‹G€Íå"}HR[E’{·ŒsÂgô‘H­ô=¸ ñ0E!à•p“át’…œiÈŸúPa_4]!Z‰céeè8F5;Ö{¡́rØI?/ Q­`Ñi÷êÍ*àÜÿ&róĂ>kÍ»uW—e-·ÜƠµºé7e±Â~n.и^J` I‚’8ÑH>dBNüJ-寬m‹ëJlÅzf™б4ƒ}ePÈƠˆŸjü‘ÿ;7Æ×rÇÁCúEƠvM˜E£äbß`8¿¹smúKÈĂFdÛº*ï`]†?É u£ƠÇ~#ugªµwT;ƠV`y£í7€4sỳŒạ́«í¶-$Ç)›YÙ×­ñ-³2ûåدº¬ëA°4ö[ó b¾[äiA"êŸ[>TçFœ³ó¼¬[±}B×ÅAÔ=èÅœĆí“Ü₫}F³²7®•₫nE^WÛVî[Ë®Åp+#ƯÀæáÍ6ë2'wûĂë»N´¯´Å¢¶e›R(YÇ Ä)Âkñ!•‰Je2¤̉n£h ơc̃7¤V́wRóÉ—ƒ‘4¨¬iC"ăv"åđâ·UÛ‹®› ₫Ơø%øÍÀ¸Ă.ß‚*)Gn{20ª4x«ÚĐJR浌ŸhE•uơ10 !Ë×hà«“P‘V>˜ZÀ́AÀ¿¶¢y«´a EH>æû»JæK¹ĐdU đ­(U>ïÜŒy]ëbV.Ú^@‘0©èŒ.c{Ш^Êân¬PÖ·Hvä±üVaÖ[Ư4¢,"²û1F1tMƒ"F48€Id“ èo>ª˜ùW¢ù¾R½tÔ4¶_ˆt^©kаỌ̈£d0N“­àKë°#ÁCŸÇqˆhÄ<a†ªË₫z[x ñF̀Ư*уÇĂ ¬Jïế×,€cLAWˆbiHĐ—ÚÁ…P̣¾„˜]÷ ä zÀŒŸË!$! © Œ†±Ÿ/d¾'³ơ/R|5 "c”r®ăLǻÂ"­ö‚ơ]¡l/́FáÔ.& Á ewÉÔ±xª!óQ8¸éB éJR+ôÜ¥2Æù¨¹0Á4†C>„]ĂiIq₫/Y‘ǘ͕ñŒŸ ́Ú8–!–Äe#G Îì̀^ S´»Y­•…Bÿ ă¯:,z₫Ă~3™§ÓïP¹^]½y¯jÚûee¦₫!«›¾̀TâÔ"sNßW7}ggơôĬ>fnA=„ñ¹`á§¾H;—ÁÀè…p’äy‘€‹G—vu˜K­YCÊ>3lƯíơăØê³Ê,!œÙéI[Pq†’A‘&‰EùĂ#Pv2hwĐEÆëÀ4ñ#XÛïA46gQ\0|’ëVđC(oÍ 6ï×ÑHhÄ'w=§Ị́)Ï*½ØØk|…ǹr­¹Ư'}B¾ˆŒ‡ø>szÑõ¸ÔJB¯ä¹K܇G:Ơ1@-wn%4¢'•$Đô§w+vY_v²,9a±xZ¢ƒë…;F–4}4¶Ú$Ïf·ĐĂ¡¸¶ỶơµV]{„0â¡¡J­¿ çÈUÊ€`0]%鬢}́»II;ơ÷Ǻ²§<^%j,2UÜĐ>+Ûú¥ó˜ĂÄ̉InÏnØ0(…À¸)j5‘¿2ÂaÀÊ`ü;F8© 'Ä5ÂÁüÆûvïꦩÚ>›Ø&jÖ)†”‘I¹¿œü]9êµ_–ª?eÆØïÎqe6cŒÜå‹ülRâÿyWNKÊî³B¶̣gGg˜äa×—”âyëøoø^«Cït>"(ÛÛÑs‚T†™óÊŸ{û Ă½ë f.û}˜ầ́·éáèPÑ´öÿ l_… endstream endobj 1389 0 obj << /Length 1608 /Filter /FlateDecode >> stream xÚíYËnÜ6Ưû+„®4@ĈO‰ ¤I› Y¤­3@I²Ä‰hFS=l¸_ßK‘’ÅÊăØF» ¼°Gºs‡—ç\̉8ˆá ’”¢”&A¾=‹‡§Í×Àüq₫ö [» £™å«ơÙó7œ8F2–8Xoæ®ÖEđ)|}™í;Ơ¬"JiH_¬"Æxøf•²°ßå]Yïô«jÔ.W«ˆ$±!KW_ÖïÏ~[OÁ9áˆ3zÏLGë£tS`bÈW§› „đI93)¿Ûíû®Ơá¡89/."œ A­a¡®¬•ÁˆĐŒ£È”×»Ê;U˜z»|ߪæjẺp¼•P?8 "ë"ÂPD,lZ°‹i˜iÈbfEQj³Ê<߯p˜5Ù Ä¡¬ÊÖ¾mj́ª,†àM½±É‹ỵXr$R:fÿ“¯@’Œ¥FËç €Á÷îr$QL& êÆ›Û,¦së¥ị̈¡a‚ï_Ø3 “ »Ke¯wƠYt‡â‡gµü6XFI“ ¬#E˜că÷¢ÿc:®úuYU¦%.të‡Ê|̃·—°VCnÓB‚t÷àđ÷!bë+è a?Ô;eÍ’c3&¥1û¨”I.«Úú…Ï/ă(erD :¹̀ª=äŸ ̣剒¸™*ÑUÄ _Ö“„y—­à×ƠâPđ÷´¯q#*XÀ¥„²¸̃ƠŸ¾ÄA/ß1âôz0Ư 1¬Û¢ >ưéÛû8*0|Qf!7¦ß<ÿª:ïO¡J‡b(ăæ›Ÿ€ƠèœƠhø¦¬Ôă@àIÎÉ€Ơ¬ÄÄ„`×ôù¬ko-E’N»ègØÛ1Ă)/;Ë€âiï~K_p†#£‘­W5>\ –¦3Ø‹̣©ÛåAcSªªđA¡—yúä`Đ0Üà3vđ8ƒnæ|̣”»WMwăE6F“SÈFXB£IêBûVuPCCÀ:’a¦+UkÖku(5𠸆óđºÁÜ[ƯP>̃HOđ4–»¶Ëé·i{ ït«¨FS…–´!Ü1UĐt Øqp#øU°db HB]¦p£¼äà ¶ÎCjÍ«¬m‘¯4XdP r vIµóNǸY aÎáÜ #À¼}ÁÖô³´ơQBɾW_₫̉Zé)àKq:ßßYÚµ¶Ëlc·¶×óT’©â™yܨ®ovÎΠĐĐçYƠÛÓ¸̀ºqëÀØ´L ¢P‹³45xo®ËÖú¼Ëœ¸bˆ{°3£öîØ-K§ 3óѨBß(´ Ú:›=P´_̃káCÓ€Å@X‰øÎMä„×r+đà)fس‰·javÀ1Ơ_5¤Äf³{È́@aQÈÚS̀Ú•‰ovhTVœØăå²È nŸZbDo9ÔÎDámVê‹o>O8E)=93ÀÁ‹$̣éf†ÿ7¬Ậ¬0¹iË”/#8DáXœD“¥HÀÙæ‡hº~\4ï1Âiº›½ZáđéN#‹…»6ç™w ‚C*€gÖk̉ÓMSoÍú®_ÿaDTM¿5fí¼œÊ“a¢zØ 7 "üæKK…i)ÊQÚLb6C ruj$=’·Œ³u>ºI&|>ô[éÂÊí|`B “A=NYôm:÷WµÉúª{a€ÇW7j1ăEYe•̉àOƯ¦cRŸ5Ö0lØ)À+ØôJ:½è|Å)¤Đ×?]¶0ÖOf¬ă¾±îÎ{®»ÚĐÉoœˆ4v¾<¨4—óñrr₫!ÇúNA>‰c.!#éÓñöÉî\2:ºĐÇ:ͧKLé’ïTIäƯ‡QB±ÿ”zpäu(ÎëLËøt(¾&mWº©/_$0€”9墽:­ÄÏB‹ă?­Q°‘Æ\rưøŸ]3øîƯï:f¾ó^˜?qÈ<ª\gµ¶6¿AF’°o-,q;©H6¿H$fC9ó;g}#b§ĐÀí̉¶uO´Ùx¼Íº\|Yî¾zöd«™/!ÔưĂz ³q₫;£”6L«ư˜ÔÆÑÁq{Ÿ•‰§ ü_øÙZ endstream endobj 1392 0 obj << /Length 1662 /Filter /FlateDecode >> stream xÚƠXIoÛF¾ûW½„¢ñ¬ä0@¢iS¤-œ4VÛƒă%b¦©’” ÿû¾YHqè‘-ûP đA4ùf̃₫½…D₫H”̉(• I–F«í6o›/‘}øôËqts œ(\œ¿""e8#Ñb3¾j±®â·7ù®SÍl΋ٜٛs¿›Iï«UWÔ•₫ÂăOj£U­ÔlNSœd1Ïf׋_Ï~^ ̀Hpv¢¤=ơq%CäƠâÊ‘î¤ Â‚[‘?6ơ¤"±jºBµZĐ2k‰£9ÅHèô‰WùV½r„9D 6T—ª³fèn”Ơº‚cöƠ¦n&ߺƠ®UÍíŒÊ¸7_[ƒud¼̉ï₫™Ñ4V I77\ç$C8Iœ„Âe?å]~\Ê9˜…2‘ußZî<^Ăé— +OV8aÅVƠûîí́Iûöv&’8/÷î[Q9ÉÔª®Ö-²±ø—ÅQ½±Dsb·*¯ZûÉi¿,ÇƠûz•—¥SĐ1§ …0ä̉Êưaßíö]R"‹=s±xQWÊ‘¥S2‰g¹(Ê˶~º• `ơfûÁ)₫„ëµ>Û₫Rˆ¤ È ‘qH ¦èêGkøøk„O£;C¹¢@‡£2º<û# $(!æ&‘eV/dο Ñ11ÁLờqJQ2›‹„]5ºÀÏíL§mHŒXÂ!xœNuÀ´W†#N¤¯Œ/’VF° Ü™öù̉kcPăü®):̣•a°¥VGpg‰+€C6†C¿+Jum/HÀïeBPc¦áŒPí·Ëûn©dL+Ä¥́)¿Ÿ-G²%ØK,đd #ÿ ´!8¢œơDợkˆ1D¦¤C´½]b¸Ç@K@$Àp‚“‘H$hTưœPÀ₫7£B¡9nS!&³SlJO°){Ú¤ô¡Iư{|“è›î~Œ(!OùgN 0ͤs%₫[»G›-X_LºøçUW[7/̃~́ñ¾íưVUcº04gàMá£Ëûj„ÍÙ#Ø\/5Å_C¢A9ăéàŒ¢uøl /'Ơ²¿K­TIw¡ăÚ%ó¬g«dmù›p ³qGÇ2 e½ß™²6¾z,ư#VÉë$f$ W€ß»[Ơ®lƒ±H¬Bƒ³*>cÂƠúµs©#Y«M¾/»vĐkˆô‘h8=„ÇwÁf¥t Ø6Rdđ6(]\Ø&B:*³©-³^} IÊ„DI&&•í÷:_çË̉ù ÉG€ØƯ‚½ª:pô,á ¤OÊÛäˆWP}Ó”<«Ä»|½nT{¼¤ÏÓ]Ưt//t„$F~¿Đ}û6~Ô*âI«HƯÑoÓ*₫ÅUB¯­ÿˆè)†̉r̉†!Ƈ°ÜÁ8 “́½6L¡eäñ †aW"LˆWú{oÍđTÂü ê\‡̀¢•OöDÏÚr÷\iqÍƯƒ Ồ{ÎU³ÉW*{ø…• ~)”è Ó|2Ÿ;× ¸ó^] ”̀Ë® 3\«-#Ï%æèMºÓc‚Ùz«ÚÍD_\¤).‡F¥ï!–PĂ‹j}´‹Đ¬<ép… o²1<ín'!̀Md̉vtíüP9†‘MaNZ}¬µ‹˜so]¤yÑ´F?=…b”˜ö öEØ…ËoU­¯¸sXèèqÆ´\R·A2#¹‰¡ÑFæẤ~h*è°â¾BĂ çƯE¿Û BÈø:Û¦X9¯Ö<èQ»tè7}Ÿ|§…Ï wv:ªÏ€´ưú˜]'6t—ÀV¶§¤Úé=ÏâFM2\›U#¨Á Û1̃Ạ̀Å>Ú©÷HÛåf§èÚ¢@\‘ P ¸̉f„¦Zh ßÏÛŒøa­[¬ ,#RF’ÀjäH¾ˆC5Y•y$¹ëơº̃h2Đ'‡—̉ÈOe©S™>̃Ưr,Ï&]dx›ú|æ$¡ç$=$¸ià&o'h¶tªKXÔÁÑ»aE·Û/Ë>cÆ@p,EßÖU™ZÏæ ¬¤-Ö(KØ Z^0 ˆüËd3zw£ÜçƠá’qö¹QpUư|j^ë¸₫¤̣u]•÷}=ÔÁ÷*È endstream endobj 1395 0 obj << /Length 1471 /Filter /FlateDecode >> stream xÚƠXYoÛF~÷¯ ̣â%nöä’ 4G]´(’4QЇÄ´HÇL)Råá ÿ¾³)’YEv´( Ø¢v8óÍ̀7Ç~h X ®‚íoÛưđúç3êä"Œf’O7g.¤ (Á)Ii°¹«ÚäÁ;ố&Û÷EFœsć‘]„‰@C½í˦Ö'½.®‹¶¨·E1EâI^n~=ûi3—Lb)ø‘̉'à&1¦ t²)äª,ê%¨¥7mF$hÛÔu±í‹ÜB̃NbÖ¹=@w̉úÑ ;ưûÊœØ ôḤºẸ̀¦®B>Ă#Ơ®́ˆ&˜2¾Fñ$ÏÛ¢ëŒT89©´b P|¥FP™{×<̀,̀FNå̀ô‹lg̣ ªÍG ;ëº̣C=Úé÷÷Æ÷Û}W´·áä(G ø-côàùÜhÙÏ6jZ á•u×·ĂnWĐ<É)äŒ/¬¼k×̃­l¾™^Rëể¬u—[q,·wđÇ‘äR?û¥“9c}Öđ©B{0 º^%ÑdLÚŒ™“óÆå§>wÎÑómƠtE~ĐoÊ]Ñ  —J ¹Ÿôë·!ͪ¡°emÿv;ï¬á¡©w=bø¤#“•}Y°2ÓIơ™Ă‹a÷ôs_tO¬ÅR`vUG¢´„ÇÀ]j‚BW|CÛºê3¥ír¦…À`¬ k–Ö®‚tܾEO>G/₫x½́{°y/Æ̀‹Û—₫e›oñécÓyr;™£*·n­4e¾c£ăW´»²Îú¦=•ĐÈ×xâ«—ĐÅ&V̀GÀâ$à·Đm” e—|t‘°€ ̀Èôt‹à³oĐ¼p’ÄV 8ÇucfèíóWđ¾’ØóbßÛ¬?@°Ú8&0,µ6(&“<éÁÔjúQs¡-À€?·!§¨ç÷_ÓP¦`‹€Ç K.ơH~wI‚¡T±sŸŒè.XĐ>UÁ›³ßíà^‚¡Jâ„r£‹ 7¹‡|ÿèÚt&‹9ëYB0á: ÇÄyñîB'x¶‹ptQVÅ¥U«€RœJiĂÉơ.!bÀẽ…V́́Äs1Ø<(™„~ơ.‚æ°b2‡%%c9ëTøl đ’BÍƠGŸ&àJẨ™&ê C”¤t/X₫LƒsMÀ²B/8vµĐq±j̉…1 –́°÷'¢,ÅJ¤&̣)3₫°oâ4(ñ}øºdÂüyO¨ºo₫©6LW :ß’œb6W4¨º¹)H§÷bA^Ü̃‡>_ô‚<çÁïË̉î̉—‡Ö̃ưo-ÅX$Éißc §ÿGßai:æœÀ:5%pVˆ)˜L¦4?đ¹%±bj”0¼öi‚‰"¤üª¢6…Çn3_àás™Óp,Ơ|83Ûè5=ÔaJ5µ\Àơ†hƒi馣kœ7ß5.àÆX›ªkG₫¹ë@YUăV;»+º~©:M̉—Æ`çógÅ̉M=îÊ#uëîyn“ͪ®ýÓ+` ‰©ÊÁØ;A¡aˆø­ ü[hJa<ªï2?AeñăsNåeK«([-a¿5Y>̃,8¯d—¾Öq™à8*Âtă™ÉU_L0£wjÉl–‡°`)…)]mX¾ë₫§QçÓ]®¾íă§›̉tƯ›5Ă3}=ëtwr—°]f;óÊÂtÛ]ƯƯ …9ă­ư÷Ê¡p&%ú'"øg endstream endobj 1398 0 obj << /Length 1445 /Filter /FlateDecode >> stream xÚíY[oÛ6~Ï¯Đ£ T,ï’ X»®Ă¶ÛZ{Hó Øt£Â’<]Rt¿~‡%‹];Nº!Ă ¬ĂĂsû>~RH€á‡1 â„¡„ÅÁ¢8ĂæÛúcĐÿñî§3bí"0Œ&–ÏçgO_ ŒRœ’`¾º/ƒ‹đ‡ëlÓªz1ÆBv>‹8áËYÂĂ®\´yUê;<|§VªVåBÍ"c™†‚̀.ç¯Î~œ› *à́ÈHë[á&4 aˆW‡›HDbđI%‚÷!ÿ\nº¶ÑÛCré49D$F’YĂn¹±VN (E„§`lŒ¢>ơ¼lÚ̀ä§Ó­V>÷Bxva¥HÂE›ÍàăFÿRCI₫ó¤˜ Cq‚$„Y^\â` 7_ñ8øl,‹€! ‰â`¼?ûÍvÎÙb$+Nïáb5 êíÜêF„Cx t2Ä¥èíéÚIÅW ü¶*•5‹o›™M´Ù{¥ú"gë¦:÷ùå%Û€?`"ºæº2qø—aJmܲ_ÆXđY$$ ¿‡î0jº73F|Ư!1FLrh¬D´ŸÁiwl:´‡#N·=nH$†_¥\ưyêdăí–à(IúdÈ̀Åë*[fWk[9@$yiÈ€” AME˜€ KÅPĂƠzgO‰€|¶Æ°ÀÖ*:åˆ̣q̃ÇYs=‘à;qD|)Fr–r HQ̃ø¥±O¯½€ÏHA›Ë«ªÇTí́íc¤ÁË¡íJ°Ç@ ä^¬—Ç‘‚˜‚8…€WăC ÚRXUˆö/½J Æ,#Ø“úbÊ–̣µºô7búT²µ«Uă#  *‚G£ïfúT!´!*é·åÊúPÇ~R†k†³ÓƯ4²®¦m8¾|.¦IVÎ +'ựÙÖOÄ$’Dú„Æ×jSj:ë -^éúOp'vN.‰ÉnFÑé¸1ç€}½g>·ÎÍåg˜ÍVYbè'‚̃X¸T7ùBù Cq̀=O-ñ)´IơñÍȃĐ&¥đ Â'¬Y«ly˜/åưùr™A¶’qOó+·aªMØÚä0o™2`æ» ÷<0ü/å ÉhLq°8’ ‡₫/ç>É.îàhS«ẼŒÖMĐ=É÷5¤b˜ßeØw_N¸Ư¹đ…­îƒưsŸXô³¨º²=<—ư £ÇØ·Đcfß=Jê¸çQ@öÿáíuª®‹æ£×ˆ‘œ̉mú-ĐÿnïèfÛïw‰W71­@™§q;$<}ß²ª«Â»Ü]xX-”–’F7ù5¯ˆÍ;±Ó^Đư{’wºnèÙ8?o÷kEª BÏÖƯ }¨§ é¯p3J/Ô*ëÖíyÿ ÁXwÚ§ƯÜéô«ßzo&¶@̃:qê!@ƒ¸üÊACe endstream endobj 1401 0 obj << /Length 1416 /Filter /FlateDecode >> stream xÚƯXÛnÛF}÷Wđ‘¢ỡ—4P MSÍCÓ:.̣àø–V¶ ƯJR6ܯḯ…—•V¶¹)Z°li93{f朑ĂIMTÆPÆT2Ÿ`ûny›¸?.>œn‡½“ï.ONÏ…HF9ÎIr9雺'WéOwŪÖå`ÈKÙÙ`ȹHÏO׋Q=].̀'<½Đ]êÅH†Ta™§‚®/?ü|Ù:T ÁÙ‘6§·ÂÍhB¯ 7“ˆ(°I%‚»?­ëƠº®Œ¸]̃¿N†D!ÉüÉqQ₫Xå(ă9œîNÙû? „H‹ÙZW(f}èŸB€D¸‡GËơb@³´ùaQ–5~́¹ơÜü¾³´}9q ƒ{éÜ»ÿËIp’cø+’wáB"Α.Ëyu H¢Œ°& RƒaÁÊT4)gÆÊ²t̀uU·ÚGfh(À|&!…xÆœe²: IÓ·K0BÓ€ /f.åkç϶ ˆÂˆIHÎQNm9\]ăd ~L0àôÑ'qb@%ŸO~ QÂ^ÓØ’LºÖăƠé䱜Ö:ZF˜1›bój¹‚>`ư>`éùt¦¯©BP.u‰0ùe›́ơüæ©ÖM•Ê₫Y!©¶,~€ cÓ~p÷ƒ“đ(§Íù¯p8G´;´¼¹y&Êh[øobfEB° 7"!A÷,{!‘(ª`j£×0ß T`˜g0I)öÁ”ưs˜††BLwj“¼*ơhZc đØ•¡!¥ ) €@¾˜ä¢$ËLW©Èm¶9¶ơ_/]ªÿxÿ›£”颪Ëơ\÷És“Xr¸°-Éuv~ÝIưËĂ>é},4†U‹â´r¡.0!sDz¯G†‚ë8ưzSư?Tt4<µ¥º‡îḥC_܈«Ü®“@nLqJ÷”ª®ˆAÏY©×å£ڲ¢§¼èqƒwá€mê…Z/âqn§ "¬Ôäß"5œƒª́U¤ÆØ™ê¤æV×ßEgLêp€…‰M•iă Ù“n0ØKbà–1K!îTÅ™Jú&S=Ç`€–"{uØ GªÂª\®tY?E¹†*Ê–Óàk‚đ‘p…‡,7[¼¹¿&ÓÀ endstream endobj 1404 0 obj << /Length 1562 /Filter /FlateDecode >> stream xÚíYKsÛ6¾ûWđjÆDâEf¦3é+äЦ‰Û’( •J¤J‚ÉøßwA€AAä:í!ÏX4µX|ûí»0‰0üH¦‘̀(ʨŒÊíîß6ï#ûđê§ âäL&’ß]]<~ÆyD0ÊqN¢«ë©ª«Uô&₫₫¦ØiƠ,JiLŸ,Æxül‘±¸«J½®+ó ‹_©kƠ¨ªT‹$•Xä1§‹wW/.~¼7ç)GœÑ‘̉p³4"aÀkàf :S0g̣/̃uº5ûƒuùÔ:%D"AäªĐ…óHHÊX̉{©̃₫F+dø0#œ¹T"‚v@‚EÂE?­AE—  >>.(‰ƠÀĐ_£ÙDJ$Ó,’ {£ß¼ĂÑ ¾|aÄa×O½è6bˆ‘ 6Ñë‹_CÔ ôơº(S·Ú=n•-S$D%)Ebạ̀ ¸N]Măgëz爈”sZŒ«˜x3û?Æo1ÇvÓ€f'^/?„´’ eéè‹Ëx”” "»¦̃©F߆”qŒRBîT&P ¤9‰Å¦SN OẸ́¡ƒ$H)eC°%&8ùŸRŸR_‘ư!"ÊÁüsÄ'D`$ÙŒù׆=Ă·¾Q¶lĂLÅÁºµjíËúÚJA®Ø‡zir8₫ J̀~ÜçLΩƯæyubùô†, 9brd#±@ÖU«‹¾È:œ=DÈ$Àº¬¯:đñÑü U"gÏ0Â8›W&Ç¢CÁ“Ô/:₫î)NQN#.s$%kN09è¾È–›¢mQÈ paß—Îs™ñœ1ë6´3g™‘X[å;úP$h%Jœ$͈:‰·Ó”9ߺµp ‹®T›}ÑÖös»€HíZÄK«>%gṕ3nA6ɺùQÇ÷ơå̉Å™¶ Ü´^ÆP£Œ÷Ê܇…Ëâm¡KcđͺzH/$™#–H ©IUXḈƠ°Íµ×]›‚¢,ƠnuÀq2¢sźiOIÙ—½&s&Û:ÎƯ#Á\î>2aô(Ä(‡ ø<¬8Cô‰u3ûn,8­K[cÔŸ}̉êpjô{%P+Ô ‹«QÛZ«›ºƠÇÑÙL:Ñj°/yÚ̀•’Yà̉—÷nZ7ŸEON?jû"”;ôz«êNß#ÜÊ1µÄ¼ ½C¦ÊºZA÷­÷ï¦ỡ é—W"TQ¹c̀ơ¬ËÍÔ²1)KHØp+k œf‡ßPó;N´Ÿëj¨2r.–cc̀©¡j´ơ“#•q̉?=íƒF—Ă¡ầc̀?}¡8 ̀iFö­ó{î‚©Y`ióúÿô>ư?Å9JEö ư?Åp|J¹7âS³Öê&¿Ñ›·«U·]̃ê±ú}£@,ËÉo@!Çñ›ß÷qpˆ˜ö}Áö—¡”Ñè~SÄ9ơæ¿c­¨ǿ `EzÎ đu‘ê+̣I=®h́pWªƠëª0D~»Z5ª C`Q.ïÖ›¤,C<Ï}WMô¿4I€Fh·óáø@˜£,“̃ü¯Å‚™†ƒ₫6ËO …S¦Kzÿa$x!¥owáH÷¦Ôcî!ª*RÿM®~]₫9ûa¦́Œ´çw§=ÅáL<@Ú‡¯"`t”™ßtÿaBʸ:8jÀ­‘ 2Àÿá%å?Ú H¿ưđrh[Ưt[U™nI‡;=¸cȸߴ|Ë‹Ù\ëºkn®Uàœ´ÛN•ï›3¯m-7̀&Wx·tê£>\û±rçMÚ~Ÿ*̃–₫’ÉŒ̀âƠ‚Ä á:ùç®u¯j×ÿ·†wU®ßbÂÔÊ-T×E·Ñ°Üơöƒ·»µuo¶Ê¡;Ø~âđYlçp=xpW8QÏVU«áMosF±‰Q‰Á wĂеê±Íí6ÊA;­ 7ñ¬2Ươ¾„̀†ĂÓÁ*6·jt³V7—­Á/½qæăăK7[Îl4ÿ?Ø™Ăñ4> stream xÚíXKoÛF¾ûWđf (7Ü÷2@/ "A‘¦±n®QĐâ*fA‘*E&È¿ï,w—âR”lµ=ôPø%Ă™ï›'q”Â$‰¤¢HQmv7éđßösd?|úé;¹“‰äë›Wo9p²4ĂÑz;Uµ.¢ûøÍS¾ït»J(¥1}½JăñÛ•bq_oº²©Í̉[Ưêz£W ‘©ÈbÎVë÷7?®GăœpÄ}!R/}W‘S”^—”rfáR„Í÷*á‚Ä}±7 æ)WHdX%BF£Œsb”$^KjŸ?ÚS1`Sá…¾_%8åéQX¤S`  cê…IøÁKH–"&E”¶ÿ—),Yfˆ0â…Z½k:]îó¢hơá°!c³ÂwK*1AœÓPç¾i»%‚ )Øä¢1HJü¿_èăP]èc§_Pw¿d”I/±o›½n»ou¾ÓK&%GË‹ Ơ„å5Ôû%¯úEÅJ"5êE-’QH‘̀ =,›!£‹º3˜ Âî—=ÔUëÚ† ŒáCY¯àßPŸ·ùF;\aL‡2'|™{WïûΟ65 ‚X"A饈  *Œ %Q÷¤mG(D¯`¸h¶öfg`3¤d́äﺶ¬?#Ó`Xünëäwe×éÂJz›÷UçTuư{‹‰D)|á[´Ä+q0ºØœz à€(ü; Ư<:\ÇĐï̀ïG{Rí%‹7M]¯°áăM÷„Ú3¨utæÆÎk€đƠQ›ÍËv)w¡¤`´ Rø—¾›ä0_Êa7 ­ŸôX/Æib@qxÊ«Ễku×·µ/'‡.†8—¬ ~ÂàK~l.ĐºÜpüb~i?øư9Ns¦êJ%`TˆÁP³ÜưCpó}d&™èë ¹ƒI¤ñdƯƯüêæÓÀ<1ŘAñ.93è-m ïM•û2”û€ó‚ a¸DW)ˆ6rÚ¾ĂQ„;ÄâYR %bw–nº₫8 Å&HJ}í™Z dçñzÓÙ;O'ô¶MÉ góJ¬Of÷U¹q—6Z¥̣Ú L›¶æ²mH®„dLºÖ•‡̣síóÙ§~7CI-JaQNu «ûØ”mÂFcÛï´íqóÆáä €[ûÑy«ó¢©«o¾ÁÎY,•F¨)JM<̃7—gëƯuVŸƒ1È0=1hoĐ4á|Ú¡]ø ½hFœík‡è ª¦:ÇQÎ9‰Srbj€ü¬•QjATœ®Dp5^g…I?:‹o}̀Ö·NÂÈí¦jº¸"*ºr§›̃ŒÊđñÊ<ÅOuéjåÁœ†¾^8¼ưÁgÁÖăøjÜ™—˺É"‡¹€ăqˆïN\=5¦ËjX8f^v₫LT²Ñ}£F{¹éÛVÇÜ™!Ău%oMŒÖ‚†l¼w̃—'¥NbXœhص́bÎ‚ÅøKón!»vzAg¦DÀ§è…E_Xô>4µ>£áå,æÏg1†åü¯¤16IáĐĐUßé¥p°‘‡I»«Cózq_äà¢lR“€¿Z endstream endobj 1411 0 obj << /Length 1980 /Filter /FlateDecode >> stream xÚåYmoăÆ₫î_AäK( Ǘû. (zm R$½sÚ—CAK+›¨D:$åëưûÎ́’"W^[糯hQ°(j8;3û̀<³C–Qøc™á™±‚Xa²ơ₫‚ú»Ưu.̃üù‚r É?\^|û½R£¤¤%Ë.·KU—›́]₫ꦺ\·*„¹øƯªRå߯¬̀Íz¨Û‘ù·ukÖnUpCu™+µzùĂÅŸ.‹+®ˆ’â-¤ï™kyÆ¡`ïd.ׄ*̀~dzU(ÍóĂæv2â·£f&KRJÿ” Ơ¾{O³ üöCF‰ơ¼ä>“D2 W»́íÅ_S‹3¥ˆ°elAçª ®zXn@˜ê¬àAøƯmµ©®v.Äâ*¦¸¾•èŒ1R*ÅQI!”%ºT`Ux>i³̉„=Ilª¡Ji‚đ2z”ú&¥‡q¢”˜DÖí¡Rø$ö~…[—·*U·àsD4]FÄB¥üÄSVHÂåQû¸£§&0K,/ŸàL“̉‚q3ç•ê½kCÊ5)H)ÔÂ5–‚DÁ¥ÄebVÙ7,†m×îCr¡×₫VƯ¬¸Í!·ƠÚ‘ 2†$ơø̉pÓk{Ư܆~\»\® ‚̀-äi`cĐrù2ùQLVôCåSk·)ơœAÑBU°ùwøÏƯOLNQ†eZQ"åibJs̀Kû$⼌çTM××Ođp½«ú¤*˜ó o—›Ơ¤4– æ$d°o&?́Ñó+‹©¢Bôüç₫ôqp}êІÛƠ0¸ưí¾„›2T˜èéÁ?}4¡×#T®a¥”;ÁÊà Kà9öIRbaOb§&y¿^Ư„›û~É6ÜßÔ¿R&¼=1´E¾qÛê°PJ»#î@aÉ»ô‹ÑÈ(~: ‹ PdÀå .UÊXƒ[€’ȲODg´.Jפ¬I  ¯̃₫¦ÚíÂeç†C·by¾úH –ŒÇ’ X*ÇđÁçK¨é°^»¾ßv»“B ̉ïZàÑÚ.+ؼD}†{5®¹DŸ¿Q5ăĂO}d2 ÁçQ>fÁÛ÷n F, ‹K…œ~Ỵ̈âT—€™ µOÎlĂ²U×ùBơÙ8YeÁfIJÍb¬…̃Ăœï=”´À|æEz% 1Àcç2ø‹´Èî° /JơR/₫“Ồ©$Z²ç£›t­d÷÷%˶éJA—ŸØXSØûÆ$1ĐSFtñÖaÙ¨7îC¸h1ٵȯ§_Ü¿ê~¨›ëđ-´1pµ1áÖ̀%đüm…å®Úc©wáđ÷n®¶m7k¼—d)ƯL–% ̃<§TKh́9UQĂ“µ̀èÜo×Đ8J0Ï$¡Ä#Pe=†îVJåƠî0BªkR?rßÉSz·—[ïvuïÖm³émÙÿn§L(Ö́%º@T¥©₫]àg6NinPà& í.ŸƠ`("̀k’J%Q{Ú¾ơˆă±>†œưe₫7,{³äÔ³l|ÂU͈â*ܹ‚\̃›»₫ÏPà—5´8i~5 ®m ăOoå^'ÑÈa“qoË;nÔ¢j?!:f(|¶ûZóÍ7đQhTÀG } }ä” ›‰Ø×¨ḉ.·2DzULF̃,öLœ:H¸ôd®×‡nÑŒƒÁ3¨ˆp_}“D]+-‘ô¤¤u®Ç>sèÅܘ¥Ă ,ud 4 ]²É^Ë﵄‚#6@é%z-Ô…Œâ-øĐƠƒ;ßiñ—é§ơ ăNf.ˆœ}Jç ^zæ2·å±I~u~VÂDI¬=Ãß1̃×pÄ%¢³r5WÜÿŸ V]— OT%•ưr#”Gk§q›öw\-‡ˆúÁ51†÷8üDûUƠ$ºîâáÄÛ¡ L„†w:C‚ÊñÍ/̉%mtï3g¿Ư8|—ª\œđĂ÷u»¿Ư9¬-ÀO²¤p’4₫Î9´ üY}2Ẁ 8ôËeÉr¦$oh $¼œ( ¯ưỂc2”Àà£À „̃Æ%€y?j‚HƠÏJeiå¡KÔ}*c%|0́×,ÁX^(èP½q¶Á±kq¤,øê—?₫ @1*ÿyÇ…¶ªCpú°j~°đüïÚÜWø¸C%‰jÀ ¸¢eÆ4…J̣̀7Ài– `B(Âå\ñ0£¼ßB‹ˆg•ëCç₫¡­×U?$‰QáUEƒˆ‡̃RÄï¾ ï`©m-4¢,ÉeLÀ°Å÷kăî>—Í1⨧ÚlDưS& 'à(w2ưÿ¯‹¤’οJêuô8øk·Û³s›¯RÁ^V=ü¢ª? G̣5CîXáÇÂØ Óxù®hv¢ŒÎ­]=Rh8²øê„Ù™h^°9˜£×M^Ù’kGâhÎ8å‹Û¨¡`𶔫3Çt"ß“‰né›ƯQpI|Ưâ¯có¯G3ê~jh¯¨¢`äú²è8Gü;,§ †¾·í„ßaÁgy¿dv!2•½Ës‰ endstream endobj 1414 0 obj << /Length 1481 /Filter /FlateDecode >> stream xÚåX[oœF}÷¯@y)Læ L¤JmÓºrÚ4ÙªIØƯY›t¶,8Ê¿ï7` c{Yª¢Ểz€á›ï6çœD₫H”Ó(/*XmØÜm¯#;xóËqóR˜˜z3\]¼¸""I,I´Úù¦VÛè]üê¦Ơ¢â“§Û :äŸ[p–ÂE‹Î=Ëáá˜Gm·SơÜ# Pk1¥±Ü!úêÆ0´ô,ë«MYÛÁzˆW_¨ª»ÑԯǶ©OÓVơ $Œ7́b–xŒÎOÿ¦ ™‘ˆ%mäyȨ©¶±ß…x…)Pîƒ ̃ª]Ùï;+A·xîć~“_/Â9¢0ḍlßW¼¡ºU têz¨êXn¢û½ˆ?é¥Üt́Z¥±ÿ©a5C%G¬s(û–UûÆ5jJö$*ŒS 9̀* $˜èO7!>L fæí™ẹ̀jF°Œ@ͨ‡7 ¸ăƯ~²=#P.M…£¶ê6(8f*a¢âP,ZÿûúßÇr¿â1ë>«4‰?»S†ÇÉØœÜ¾Đ³éƒ±gå¬̃)Áˆ ˆ2̀ê~iⱌxăÈX+ /„ÍI#™«x£ùûoƒgîẇÍĂT{zJ!6¥g®¢¬X¨¢Æz;0ơ—º ŒUeÙÛY€f@”º&¸ÚÁ<̀ 3Lăr»­´²4î댔my°€nNí0«:¹§m£Óq[mƠÖ>i‚üG¤@YÁΧQÓđAº9-Ľ†$@páñUÈæÏyØÛ„!KŒ>Vc@¤î9—đ¦̃¶É´}¨³k‚7÷—đÉÍĐÏr!‡Nt"·Úï}ÁÜ!=Ôêv;M²Í=²å_C¶s [ú$dKj$&²ƯAôjOºƯ}äX ưầ^÷‡ơçN‚âw @¯œ[à-¼Êé9P?NjÖŸèCÈáG^ơp¡Çh„åqÀ—Ỳx̣/}}Î:‡¤C §£í́lÀu¢6¿+†åagcÑúÓxÚo#ĂƠÑ@q§ Çlh­£ơư?zmU îôØơ]p× MÆäW’ÓpÎoB<K_¹t•ÖUpñurÇ<ï:s~)ÎO¡Ù2¦PĂ±×½éƠ,Œ*ÎNÊr€’"†÷åLJúƒ₫]›ă₫´÷ÄB6e˜,s5J‘™ĂđÙ›S£ññ«Æx^·]Ák¾ĐĐ÷/SIĂ² endstream endobj 1417 0 obj << /Length 1431 /Filter /FlateDecode >> stream xÚíYYoÛF~÷¯à#Dë½—4P hSÍCÇE?Đ̉Ê–¡«$#ươ=Hq¥Ơ5-Œ"@́HË™o¿9¾†$₫DÑDe eL%ƒé¶Ÿ–‰ûåæưñçúp°ß9ùưíÅåµ Á(Ç9InG]S·Ăä.ưá©XÔº́ơc)»êơ9éu/ăér6¨Çó™ù†§7z¤K=è^Ÿ*,óT¨̃ư퇋o[ç‚ $8;isznF¼ \*ÜÁeˆp$z}!iúvØh:¨‹üøÜc$Ơ ¨?[ODaÄ$·fÆÏƯ=N†đå‡#₫^́ÑiÂ'ü6I>^üCC”@a!¤åp± $—ơå¨ÔÅĐ€Xçfa÷¥I»Gï€hÖ%¥×ă‰¾w¤JA¹Ôè3C—€Ï>;,à̃Άc1@íO}×3L§XwañNçÍéOXà˜o(„Ê?<Ç,‘ e´k‰l¥ À*ä5Đú ix3C(¢µSÿ̉1HP‹½|rj³Úñù?:CC!Z”z0® ƒ‘ ‰x–í Q 1̀Iöôztîb°%¢joǘơåÎëvóå¬̃Ÿ÷.ö僄çW¡̃•ôÈ|°~B1¯!Ô­AÊ3hû¯8F[ ©æ„.Ëiơµ¤Ù)ѦÿDơ}´A~å< æ \¤̣§óÀ&4WÆ"q[ëÁÿ娜O]Êü₫îW72CBÎ3gđ§ÙbYGáa¸ˆñ†D3¥Ïñ,G\µ́Œ+‡°pø7y‡̀ Êmr½Ó£b9©¯Ü'cû8Pï¼ûµ6‚åfF•›À4i¢Ñô÷™€ÏüÈ÷˲>0œ‡¥›=eñ]Âѵạ̊î¹ J¦…t²1tÄ0¢¬möÜf¸¸ç­…« S ‰7Ü CĐ‚B̉Ü…í9₫…GQ¬4X™{TS]UÅ£F€ùl-0v³§l\d(§ê,›…±%™Œm/å¸Ößdµ˜-§_j]ÅZr8ù€ÀT…Ó.¸SÅ€{\Pd²–{'k é`’ä\›ÊQ¬ZƯJªHJñ¯̀×_1¼XCôŒóuŸR…” A'ùĂDÈWtꪧíl±­{§;z>Ơ»„$1¯AÈ•¡F¥ṃ Dÿ;‚QêzYÎ<Ï­*+‚jC̀[å- µÅq̃À†æˆU!u Ák9v2¶¥zÔơ7‘ S`ƒèrĂÊ™X ×Ú‹à“·xë‰[ë¸̃₫J$œ’³½’ơd¸9;,ÊÄ® Ôíç ]Ö_¢ÍÆA²s#JA‡Íé½ö®~̉®âŒ#_™ơ¸)æ:]*otF‘>ëé‹u´Pñ‰m<đkk´û–¬ïm)́{v<âGR»%6Ên}˜.?>›¿"]‚ 2Ư"£ øoÁ¹j›ƒ‰…M"ôNAê3xÀ˜ù)WLjË’bŒbiI¯Ị̂Ụøa¿¶ưu«H56gÅT‡)°i s‡n£uƒù9äIÏ¢ˆ DÖ­‹#¯öbÎ>³+Ÿ́ƒñ'L¸¾iv/#ZAitÄ®p©¶ÑÿS£k 䬗/ăÊÛ\ùåß`1l“ÉfLÆÍ¶ßÜĐN–e;R¨5îa©dØKÖG­Ơüj ¥éåíA5DAjV4ÆÈ‘%´öbxb á\nVĐe¥]'2₫ÿ%_« endstream endobj 1420 0 obj << /Length 1555 /Filter /FlateDecode >> stream xÚíXß“Ó6~¿¿Âo83Xè·¬›é PJ§

_,Í;÷¾T !H Aíû³4q èÚwçœÚí#‡ëA 0ûU?L,Ïé-(‰‡ 8° §ñ‹ÿÄǶæˆ̣̃byù1f‰äàĂ!ç@"ªt’£D|„Û<ŒY!Ù'¿¤^ümbˆ 1–w’És$)ñd’ÿÙ́Ù í„lî7Ć<47›¨kF”»\“Ë,‘¡o^eµ_®‡ËE °7Œü ÎÊ»UWU¹r₫}û́•Sèźnªí„¤đázBó´q–BË„B¾²R¤™vYo¶M†c($A»¼»¬ø¦c‰F\ơYÔaáđy ̀YéG3³@Û4ó¦.©! +=5/·+{tØ₫ï [yå@\O{±Ü­)Ư÷6‘­}¼ ÚgæªØ.›s÷ÍÓ›ÆÔOàU‘‹eq¹4ÖóqÜK€»(‹éfă@ÅÁ¡:IađJpŒ9¸V ¨{½%Èo„sï̃_·Í]₫å÷ˆ¿Ÿƒä˜‹á`aJCmùÖ_R¾¹ÖHHy’̣mmQ%#å»6Íiªw(Bc­µÛ´:ºO!CÑ= ‘T–6‚ëkS•S571c¡´EÙê­º×6‹bBß[¾Fù1åë{¢ôP ~ˆÚÛ7ˆ»‹“ÄHñóo,{­ ~0Nb́Ál¯Ú,œ\r¯?̀ç èä̀XÔ›¨`_ṇû–~l¹É[‹öâGö´-€](´'±2דN G2¤!24ÈHk5–!®zbàRªP¸;ňh-)I‡"ä Uẹ̀>.gË¢®÷ÔM¡AbG­‡÷¥-‡®¨D·°÷12bs]¬Lèú][²-¨<ÎDÆ@²I×XD=à‡It$¾Qs13Ë¥û¢.Ư'4*ƯÖ>è%]À5PäK]ËpÛmt,OWE3³₫°X¿ß¥̉Îk —¢¬M "ưÍ}ÚmsÜÔ‹eGA1›™Mj‡ă¬G狪>˜»̃£¯ZK¶Z;eˆ'14B¤›1v5̣n`ÓÅÊ”Ûæ ÈkÜ›}$Ễ×ö®à“Å̀Êơ¼Fnêó»úÜ.ê¢5#>£L±öuÀŸđréµÓ²ư©áÄ7Úwóa0…©8P ^–ë.)Ơxh́x0]Ơåù4²ï§₫ ªNrèẒcƠ?,ZÊ,ÚîEDÔÿÑ{¯ Á̀¾Đ×öÓ×P+Đ’<±•‚b₫u 5œ́­iÂ" ơçjÑĵTQ$í5åD±ơvuiïiÑFL"çƒôI8@ỰÁCRÜgˆÁNĐNî ¾b&dŸ%=Ù€í[ăôË&C}£87u³X–È'óyeê(1^̉ê°ỪNï„Ö£9Á­ưW}̉Í áÁ¿`i”ƒTl>xT0Ø‹Ø̃XàzØ̀₫›C¯ … ‰uUâ¿ÉƠïË=GßÊGÆH{q8íÜùp.Oöñ«=ƠHÍÿacÊú:>|†êËÔqĂ禌Wƒ™³m9₫̣àÜ– endstream endobj 1423 0 obj << /Length 1597 /Filter /FlateDecode >> stream xÚÍXMÛ6½ï¯ĐQ"F¤HJ P ùl7 4ë"‡$­EÇjeÉ•d/ößwø%‰2l€‚YËμß 1üĂAJ‚4KP–¤Áf«o»¯₫đá·+ĺ"0Œf–ÏÖW_1àåqƒơvîj]ŸÂç»â0ˆn%I&OV¥,|µÊhxl6CƠ6̣~[щf#VIc‡,_}Y¿¾z¹ƒ3£ɑZë3¸ p‚bÀ+áfá|bF5äëæpz’ËçÉÅA„SÄcØ̃®"ÆĂ¿©Sœ# µˆµeƠë:Û¿^¼¿"YØvƒ₫̃z›ùGÆ]Đ1Ó>Ëb(|‘ EÍmde¥b ­~×UƒđG1Ku<9$Øû́M _LÊQ˜îäV(W8 ¤{áz«mZS (åÂ4›êsŒ©(ÍB±-ơĐÏóIÂcƠÈXCæÏÉ@ssưP5…l¿§eÙ‰¾÷%•CO`e’ư₫) ËüH0 ©$´O_â „_1bơN™î„3øT7Wúh)‚?đEPئcy€ Cp¨đcÅuƠØăÎŒQÎÑ)Áƒ\/sÂđ›Z¿XÂăyµ9¬¦#~Yl¬̉¹c®'_pœ¡ŒŒ\óÈçĦƈ̉… ¡O&HØŸ+!ˆ/¸÷çOƠuä¦úGÀ’P|ÎXŒÈÄ‹tv9Æ-–ël¶ ̀U¦„¢˜¤.}\e@•¥‡s©3º±uƯNªM},«æ«Y"º½¤ÄÖŒ*§caQ…ïHÇîa~đÀ0m³«Ø‘$³5ˆ4€MÛ40LÚwª6¯Úzy„9âỴ#Ă ơôæùµªÏµ[H:’¼ê÷o 28ơ6;)0 1²đb̉#³q*/]{8‹8é“/l‚8ÿnX-SÆD̉‹œHw0§::5¡Ơ#–Ăd©—•‘iÎ9Ÿơ›Fg_¼9xƯßæw¹ }«‰é*åí¨ é̉,ª4“ÿ0‰uß>¹Đ ³f„*°c¿k¿’̣H€¸¸µ’­¤FÂÈ¥6H̀™«[Ÿ̃¶EYÜÖî+É*æṛÅGn‘ơºy‘s¹5ú&P…đ̣ ¨0›ëÆ%:$œ¡$Å.₫¼i|W₫]{Ưpß{1Bº8ư¾â¥ĂÓÄà®Ç,EÙè!äKÄUßË̉sYÎƯùà9ÛÍ™Y6ĐwÑm‹@ÿ§ÆÈÔuđNßÁfEu€s(Yήkà=Îç5uƒḌ™D.¼ç(åÉ‚pÏ\J„'oÚ´¨:͘”ÁiwhøMÓJw-'TÇĐ !Gö¡½"U£¦2Ë`²$`ĂˆmX¼ï«¯åX«|#ÉËă1ƯƠ™º«Ï|s;E¿mU†›¢®øyJºU¨à{/]7LƯ8d‰ïdéư÷¶‡¥™ÇóNư2 ̀uµ­¬f Ñ>¹£mUsу‘¤́—b´µÓÄ^Tƒ©èô‹F–^6’®l™nvE'×JC í¨g:ï¶…ỰíbƒzSéîùŸ0ù́̃[̣̃TFBa19ỈêDQ¶M}?û…iŒó3úp ][‘Ÿ3ĂÈøºÜ»¢6ª®¦0¹6vr…ñJ½*3oU<'Ă‹­,ÉË”¶₫œVö5{ÁLby%ÍÆà₫|v¿¤éx½„ûg¸×K7zg°sLz’ï^̣âJưqnêbœk̀¦Í̃ôđ̣Ç—l&£‘sc 6ÇÙh„lúÿyº4À endstream endobj 1427 0 obj << /Length 1558 /Filter /FlateDecode >> stream xÚíYYoÛF~÷¯à›) ǗM2@Æiœ6H̉4VŸ\?Pe1å¡̣ˆ¡₫úΤI†¶d7) 0`^³3ßÎ|s"†?âøÔñ†æ;q~‚ơƯêÚ1'^+ç 7<[<=Â!…8$Îr3Tµ\;—î‹m´k’já1Æ\öláq.ÜóEÀƯ¶ˆ›´,Ôî~H6I•q²đ¨eèJ¼¸Z¾>y¹́ *à́H¤ôgpê†0àUp‰ˆ:©DXpù}Uîq“ªI“Zá˜î;ñ‘dvÅr›˜ ¶ëÙO¹ZxB¸“¸1O¶Qm4́¦̀²rA÷&-®Í³Ư‚¸í*Kc{©Pßy¦XÓDHcú]”kŸ êúT-Œê:½.’µ1Ô”ö¸µ-J6B9£{©Đí„ÀUK1ĂnZÔMƠæI¡5vK½œïZ§`ĂÜ(«æÔÜû \%Ѻ,²=œ“9“oJm-²÷J),^x¡OƯ¬ÔÊà~ç)«Û\j4m®₫¯ \˸‡Ùü¹¬Aa0co«Ÿ(Ñz]%u}„z›MÔ´ Oy軵½Đ̃ßLậiNKëüº°´Û:³²NÖ§Çor™æIÙ‚^"®»RË?-Àh”µ–—iau—ÅÚ²¶­;6m: 7ÊÛQÚốퟬ£&åj›Ÿí›¤~n,¦Đ=Ze‰–O Î@œñ;‚Ê{Ç­4ï@¡¹ŒÛªR¼ôƯFĩÛ\PB`P*ƒÚá¬M å·{¼èYXƒ]¼m³&£ºyU•íî́u'h,^kqăZË8%ô§ú—ØP¤ÖƯu»ªă*µÛäñ±@_j» ®1jdÎ ’2K"ötÊÊ;Áö%-̉‘Ú›»÷ï<½{£¾Ư(?~£₫p£]Á¸ØF•âä×Ûï¤øÔÖ J4–Rj¹`e•§EÔ@ÍSj"Ô¥®́Sw6K¡Z÷ ªó²Ö¥ Tƒ̀Æ®(›[E`Ó29b\RƠû<Ÿ z¦=3¤›‚ µKR÷÷‹³åÛ·ën[-èÉ!a·K1‹~T§n đàđi¡zo×₫ÿê{:ñ1b’;ıîè—WØYĂC(5H€¹-;qÀYæ\œü6×÷‰/PP”.BlÚzƠäñÓ.®smŸa¦¶N ù‡fƠå¹ ̀`aîy%WFôBP(„ñSÓ—M¯­úñBÅÀO÷B?,Ô4ăaI<„%’Rtâ*¶s¶9¢0Y¡rơqN P@Ă&2ç/è±ó…g ±å€fô"1®1‘=êö¨Üsôñ:YåüfÅ/Å®mê9Ơ“m¬z¼"s«‘Ú]D]*(R æ%©4ÅÈ’\ÀQ „¢Ódž*ẓ‹]éR$½›s‹óå®C5f(á1\§Gp¨•Y TaBô%éä×mïç´2øèÁ "4D‚Mrè×nÚÓÓ¢́óHÊ#‰|ị̂HÜAö ̉;p¹M­±I;P·ºG‘9¨=ÛF¯.7= Ô•êÙzMo-fä2o |¾‹t•fĐÿ¡uîM#„QQ9is]óû\1mùæùÙ|5àúÅmT t¦±Ge¥û_¦¥P€ä“–¢Ç̀ÿ"ɺÙ{Jß1/»,»…ơØ,û2E»³1¾o7LªÇÈ OæÔ„èơÔéß³½^WKqĐŸœÂ¼&₫÷çŒ?gºx€¢]•ÄiƯ×áÉ$&‚CÑ…棓ûƒ3Æ< Îåj‰¨0|ẵûä ¸l‹æ0® ÑAÂzÎ×Ë遼¶‹z|‡&aÿ! ôÅèNEư‘TU^_Ïj‚ÁZ‰6ưÉÿï£ í¼ăx€̀¾[0¨®ŒÍnR„=̀MUæö#qÿFÁ§ŸSç&ø@àÖ7ơÚ3¶éYMĂz6¨·c§ XOwsßlÍç=~ûq£~ÿâú“R?$˜OÊ?%›¾7=3wÆ*Èó8­ñQ'ơ|Œ–«ä祄SÅu³å?¨2 endstream endobj 1430 0 obj << /Length 1399 /Filter /FlateDecode >> stream xÚÍXÛnÛF}÷Wđ-$P®÷ÎeEƒºHP4hb Đ̉ÊV ‘*I9ÈßwöB+­Év‹Â”¥Ù¹Ï™³$ †?’4)CÉl}í·í}â>¼ÿí‚x¹ó‰ä/×—WB$£—$¹^LU]Ï“›ôơCµéu›åŒ±”ư˜åœ‹ô*S<ƯÖ³~ÙÔæ¾× Ưêz¦³œX–©$ÙíơÛ‹_¯Gă‚ $8;ÑÓAúÀ]E»J"R€N*ܹünÛo¶}ǵCtå4:œä¤@’yÉyƠW^,HåHñ¤­Ôơƒvá·º»pÍA3û£9øH„;?k¶uFUÚÇL1Œ(Sƒ©ÇLÈ´Zmuḉ‹q;₫œ³CÜiƯ¶ëî>jE"EØ`eˆƒ¥Íê¥à`5”’-Më̀¯u×U÷Ú{f> ^Iđ¤@ªTN³qñ,’¦?7 „¦3H1<3FR=ôÄßc¡I“<‘œ#A¨)óÍ-NæđăÛ#F¿XÑuÂ'&S«äĂÅŸ±f …°a]”ú¤l»»~=»\|i—½[a„³¥ăÜr-Φ-Î̉«åJß:²HA¥ÔƠ´(—Czëíúîk¯‡”SY!Wc¹Êr‚N§ÎIí±]i” -¡Â%{&Ûň.]Ó!7Mg¹*ơvĐW }! Å¡ïÓÄhˆBÀ¬‹‚œE´£#¬!)¾OjVhx{mü.tTơ|¸v­t5œđ ú#&|åÏÎu7k—›¾i¿‰ê ê@‹ó ?}Ê%̀—¢gM9R˨„'ܦ${ΘSƒ’ZU’ª“¢Á˜apÑĂ%*¤₫ÑÔú–ö¯,M ½™•0qÅ^̉,µ6w$eïH*̃º¹#×j ­ëMƠÉ+>ú€ñơ+đ^»=f²ưoj[Ö endstream endobj 1433 0 obj << /Length 1637 /Filter /FlateDecode >> stream xÚíYmoÜD₫_á>)̃îûÚ•h E­ å(H!BăK\ƯÙÁ/)á×3ûbŸ×ñå.ׂ¡H¹³o=û́̀3ḮI€á*f(f*È6'ØÜ­¯ûåƯ7'Ä‹``4ù|ỵä¥Á(Á –«±©åep¾¸NoÚ¼^DŒ±=]Dœ‹đå"æaWfmQ•ú¾ËWy—Y¾ˆ¨Â2 %]œ/_Ÿ|½&T ÁÙHûÑ÷àÆ4 aÀ«áÆ6©DXp ùm×̃tm£ç‡Ơ%ăƠá " IæFfUW.h¶n¬ç †e1ËÁ³ïUy *x~ó%!†¯|’LEÙ´©Q>̉fIpîÁÊFÖr‹¹—”ĈQ8AÉ4¸̣€!ª˜Ÿ₫́”RÄ$5¦h,ZåÀàl6ͼ %ÀÙüx̉ƒO¿Ùè]¹±’:7Ô„ơºk/tÚ´yéSÈéœ#N<"ˆ8‘ëÑǯ*â₫ühÑÛ̉(GÊo¯³js³Îµ‚œÚ»¤ Èø$™ ¡Ë€‰¶1¤˜0¦`Ê‘j%1yk±^§k³ÎÛ®vKp~”»ªtá“~‘ă¨HWS¬5X¬“१ ũtëvoPơX§Êê­v’ô#F±åˆqiZ`$)ÔNFÁib(L̉–¥÷ ÆáϯÙ-(1„dx ûÜ—qÔä4|Ü.™Ëi]˜ä 1L?±¸A™"̀ØÂÄ9ïö÷‚'«l]5ó5.Æ36©qăªæê\±ÎwÔ7½ăƒäC´æ Œ_ ÂÁv.ẶˈHJñ¨âV]|˜³¢ÓdoA!³”Ï»œÛơ¼7 02‘Ue™[Ï̀P’€²d­‚¤"ü0+*ªîÜ–4ù±j Päspˆ%ܦ<U bAùÏăQuÓ£̣ƒÏAÜâäÑhÄ<EB‰‘ÉɆö¬[Ư¹́6›»9«Œ>º·¤ơ)¯¬¾u±Ô Ut`(|ƯÇPĐ¾-6ĂPÙ3ÔŸ˜$ mC.¯ 7WÖƠp´3%Øœ]à–ưÉàR¯Ø̀åj˸2ÅX?³¹©+¯ ƒ] Ó¶¸(Ö…­ü®2pˆøØËĐ¾îûLólùæÙóù<ăæHx?ÍØQi¦Ù?OÁ=0/Í̀ ́ïÈ°ÑÆ̀? x¤́Sl ëØû̀÷›ÜăºiΈź[ŒĂx¶́{aÛ÷#@Óơ»Øhưûß• úàÇ£ĂΓƒ¸§.₫,̉l£‡#cÿî¢r‡£:Ưê/X©j;ưºoé•mơéM₫Ÿà‡t` endstream endobj 1335 0 obj << /Type /ObjStm /N 100 /First 953 /Length 1173 /Filter /FlateDecode >> stream xÚƠ™Ín7 Çïûz‚]‰â‡9´o‚4‡¶FFº( va;@úöưS¶‹Ä+»ëƠ:élp$"9³3¥VJ9•Z ÿrªÆ‰ªÄ€&²8'΂IRºª'‘¸&m±F“5I^$5’&(5ƠĐĐä®Đ€ơ’KŒÀdá‰a²áJ)&=Î!IME°µj̉¾9Á¸Á¼ÀtËX çÅKׇY—.y¢¬ “%Q±¦‰J¹IøÖƠÆĐ‚ÀÍcúBû*‰­­ƒUżK°ï„¨qÍ„Â[Ö ;Æ>0‰ k}+¸KgÑUmغÀ]ÉaG;p‡“8À‹{Dä_ơ‚ầ†É–¸ô€‹w‰W¢»'f‚~F̀ÚWÖÄ’ăP–*W°?¶~Ø[ ÉáÀKÁdÿ }„-YºÄH¦+ÁUD`˜¬µ¯¬,öKWÉ̉̃‘¢Ø7 I†±Öº>ʉb•…à@’±ÛtĐâ]²¤•b¥&E 1Rødd¦j÷ - Ÿ…̉­Ï6ÔàÀ3ĂAK–sạ̈ÇrÏlˆ‡„ÍăȰ2ŒµÊ+ A­Y¬$M-G´p̃Jø,H¢VºO$P+‘XŒå i”EÓ^0Ô IHˆ¶ ÎQOS£ƠÉÉjszyq“NN̉æéßPÆo!‚¨Ư‰Q å^düƯUdÉưΖè~æ®*ăêƠ«ƠæÍƠ凟·7é,m̃¼>M›wÛÏ7éư S±ƒwÿµÅÄùÛƠæǴf{qs¢[^m̃n¯/?]}Ø^ßö“>öÓö÷?ϸüœÎ2ÄeMÖ^7çW0}ºµqçèu:ë=ªọ—_Ăù$SÇtñéăÇ7t8’Ç | ë`$\H| çi$ûåÂăèG»H˜æ‘ÔÿD2̉C[3ZàBØÙ€<ØéQ+́…ÛŒ j}‚äl3/dPSBóHêwÈ‹#• JEæKEP*{Ưr¾Dw0Ím‚ï×kè©Ó:ªw½Vë.;-Ó́”¾Ă­ûp:€Àσ ¶ A–ûübƒ̉6ÄçË·œ£d‰ JÅÊ4£%ơZ”Í—É~½ö®×¿e—q³6°³yví°Ú7ö=ưF̉hIËÓHZYîSn“’ú<$Mw‘đ~ö@sYÛKw£c%Ó ¾Í“kÇM¦/đ<•XGI&Ô—çi$¾àụ́A}ù|}ùơåëKÖxe¼§B¼ûtg·ÜwŸè$>‹$¾$,ơ¥¾á́ ‰/ÏAåvÔëĂw̃c!i$:ľƯ/̀¯‹jú—D|ÚEâÓHJ̃«?Ô£\×Ä̉y*…@kPSe¾¦J=̣ïño÷S”‹ È<]́[¦<@̉æ‘ø‚‘́¾µaz̃[&̃ABôr7£§Êæ(H…C2D÷ë¼ô¶©₫o_sÔµyZ¾ ¯‘\UT竨>]Eÿg4©• endstream endobj 1437 0 obj << /Length 1840 /Filter /FlateDecode >> stream xÚƠY[oÛ6~ϯĐ[e bÅ;9`À°bZ ÖfØC-7.l9“åtư÷;¼H&e*q´ØË2yxx.ßwÎ ÎJøĂ™$™T)*³ù欴oÛ™{xûëöë XX+>?{ñó —H—gçËPÔù"»È_^W7]ƯÎ JiN˜ŒñüƠL±|ß̀»Ơ¶1¿°üm½¬Ûº™×³‚ÈRè\ĐÙåù›³_·Ă9áˆ3z¢¦ưê#uÉ0E%èÛ«K*9sêR„b³‚ ’ÿ´ƯH>ïª|ÜÎ(Îë^©¿‡“°,̀¡Œ›s..Ël?¾ÉJÄá¼Ïvé&cˆaOë́ƯÙ)m°äHa«tûÏ ăËÏíª³Ç-NT‰J 7% ŒƯ¦ 01 MLóW«u}é™aŒ4çÄ(¨1 ™ƯÛ́7W_ºzçáZÖQª_ùă¬À%/óP9Q†Ê ØÊH¿₫=,NiÀ9,Ú^}JŒRD÷‹§Ä`‚8§ư’EK¨K¨„“V-Jd¸óïmUˆ̃;ŒÊ9‚ŸbTúíŒ :-hđ̣M[ÏW;cÆÔ#{L¹¨ D" ¾‰|ô—q‘±\oiî¡àUƒăÛÄÎgà¹áünë\mÑÁƠªÙuí~†ó d@^73¢̣ÎI3ºà®Âmrj¯áëæfß%µ+á*d½Ó åŸR*b+k®vNÅÊ©7hJ ªçFÓ¥-¼°ÈwÚFG´9+±ÜFmú¿Ơ“ ƒø(f \GŒ»Ø̉g4@IÓû함₫V¿ï»Àøüă·u·ooWëàưfFd~e*wŒÆ¼̃›̃ƒººIë…Â’F!ai‡;Ú¹5²L(I¹BBsöÄẲoÛjQ]­kIHM@“—R “Êj°œàGh,Oà’x.­n’°AEM"rÈc›)(FT‘{S°fÉăøư<­LrÇÙOá8›ïµqT °¬æöMå´@˜êÑ…ăl¦ˆüQÀ12êÚ8T2³Ç¾¨‹¶̃íÜKyf•<¯«{ơ®kWÍGd‰ç¯ưºíÆ„äÂm^̀L-*/á¡Ú¯;/Ô&1,~†Z¡¬@øỴR””ˆ\ØI1}/‹¢›>!4ÔLdÄ»Mµ©ă¬ß·fŒ¹[›ün +ơ²¿ëXpW£Féî9öÖùuxßD´!+zw]­×îW‡}ṕºÊ²^ß„ù ư¡Î@tk¯aêLø¸Ù+Ơ™Dc¨ UÆ€Ô¨Îdr(3)¤Ë̀øx¢9 ·¢˜ÖÇ ûP#=xz¾®v=×x¬ëzAl‚uS÷UÊú²¼ï$¢% T́Ñ3„O‘€ÏQ©Î ¢æ̃°WIư¸RK 3feq¨U¼u¶»t. Rjô{a;FÅ$lÎŒ±O²SN*½'‘ưD…¸̉l”»/­~.ă\¤°@[‡œ6…û­­×uƠïđµÅû³µß»¨wóvuÓmÛSàö´¨.S—M¤® ,qZæ–¬‡MA !Ê\C˜F”P̣Á™;QHp¯T‰œ’'çe¦Ê’O’S”ÁÉRôuXµøn)u1Ujˆ§j€†Êg¾Ư7]²èrí̉5ƒQíơá`“8MµF+¿¦+¿H‰®“́ă"ËM·ql§U oÍ­—ívsÔÖ́ÖaÊy`¸]Íëÿ( Ư~ L Ú°ÿZL·„‹d\'»4ˆ9-GFkL§dú%eû%•÷À‰~©¯Å*(Ö67]ÜQ¶C(ô»ª?(ø<¥|¬/Y½åóŒÀ ÆèT Ô£‚^!­©•Ä?@YPC‚} C ÏióÁÖđψÙÏm{ÍÁr¿^é%Z»ÁÓªIù˜§cHÁcÔw––!ü̉ÊŸ{0ºk…́KÇäđ`è̃ƠôÀXæ4㸮7»zí̉e7ôY µm‘ñ° NåîWÖ²4=Ê[µ­MÓ/†)&ØÑÅPqä¨N&G3¨R˜? 9Yœø!ÅôP8bÇ'4“½:MÎ>LN0ª(a_[›>’ª7@xP2c CGßhMŪ£!ÂÁdßÁ̃Ï`́¿G`ú ÅåS0˜%ù– vÚT³ˆƯxà§«pàà‡|±£‡nø ÅN(^V₫__~ è¾Ô+0âJ7ØđïüÜqï[(• DÏĂ´5 À?Ư3Ce%³¼á8Ă|ç@››umđà9¼ d' à†R›«!J^*¡2¢(%¬˜̉¨f˜`Û+Ú“¥¹„µ¸y9 iCÖ4+Œ!Í‚€r̀×ÁfMå_¤e₫¯§è¨*q‚<ĐR²Pv N7ŒUÿ‘®̣ endstream endobj 1441 0 obj << /Length 3156 /Filter /FlateDecode >> stream xÚkÛ¸ñ{~…¿X+zP_?åÚKp‡  .{=½~ĐJ´MÄ–\JÚÍưñ)Ú«´‡«!9$‡óq̉Mÿ̉M•mª:ë¼Ú´ç7 ÍÚÆ_>¼Io ˆÛó‡‡7oßÅ&Mâ]²K7ûM‘ª¸̀•?ï¡Ûü3*ƠƯ¿~~óăƒ?©È¸Pù¼Öa¿º»Î6igi¡đn|FVÆ đÚw—ËƯ6O#Ưwæ+@U½»Ûe}øë¯<₫ {m›>Í'Ó2üÑ´º5̉}ûÄ´ÜÅ»Zm¶@EWưư®Î#mG3ô°?Ï£ü¿Ù¿*úyîµ̀$I…Çn¶©JăJË8O2>éÏĂå.«£kG&Â-TœÁó’8ÏvŒ×2i¥ IÛæql Đ~Ỏbơ 8Z{ ‹h"ễăC¬Z?û ‰x¾Ëª¨±:Àæ¾k&|oƯóêÛøVĐ¹Êâ*ÙmÊZQ :.`-†É$N3’øơL(z·ÀjW†Ï¹½†^uœ¦Ë÷oßîÇ}<ØĂÛ[̉TVÇeZ]‘ömtد ¹æk’Äơ¦,êØ ôÇ'ä ¶/øX TdFæ%h(­Í4é禿-ªB½đ¨ée¹3ădÍă<‰8IÛGÆÙo4Z.ö|át„+Q•Đ·¤Đ³Ñ@zVîØ¢ pgÑ;‹¦’‹ß†?{Đø{|{ÆLû;iP}Z<…÷ƒe`\L£fÓ óPH ÓQ æÓwr ¿´i°_ÆØ‹$pü¨ªr7ăæª–«aú<ŒC+D"Ë/¶i'Óc`è Vńôh½–ư¨ˆôm¾ ̣r#qq^PÎĂ,×!C»á¼¢p¤Ü»:́OvBo¾Û-ê% ÓQ€€_ÛR%Ñ/<߬§¶QWUªÜÑDZ|< ¼ØkHa›á!f9"ĂƠ3R~Çanl#¸xD²‹ØÂ‘8r, ½¾îƠ‰¨JÔøêÊ¿N'^ĂÆ 2̣s‚Œ§áÅÛœÿăN?{9Ñ]³»Œ¾VŸÓkÏÙ³Ï/ÔNá,)Lf˜G S$UôÛ]­"4¥¼Ø‰(#*0ú¼zÁuP‘æQVưQ,U¼Ta€R…8dÚ…óRVeÂÏPe*6„SÈSúβtË€?ÁÓ2ELD¼ær9‘w¥Áix×4ÈL/FAg²âºSa^°ú¤›5Œö‘ø1@lü!à ƒ‘é+̉kæé8”RÑ?˜•â²›=4̉ư:í%Đ,¶K!‰µj¼_ôUWơÛ"ØxÍđˆQ­ÂQ5øâ´d6§•(aƯđ 8¯¯"íÀƯVïµµup˜z7C;+=8}± st»"ú‰đ ƒâVXùqñ¹E&€À1ˆx_28z(ØàhưØL ‰OàÁ‘Äúä|i‘³^ă’÷áña¤Ç±‹ëS(‘rư­]½¶…ß“"¿S:okÙï”bâQ䶪È́yÆ¿Ïf<ÂA)êGÊ[«̣XV·ÚP|!¥p„W·„£rIñoc½Éó…–%ÊÅ@’üjTá\)­ ª₫Úœ/'¢¿º«< »º©ˆª ₫©¤₫ï8³¿ăQñ@9ûù¨9^ằOÆ!s{Đv0e¯írÂUg̀ă´â‡/ÍHÉH5£àô!/œ̃₫ÓÀ+z¯ÚË"(ks4a­G ÏQ¤V©÷Å\ˆm¤¹Këg\BJyäƒ]ÅYdp8Ññ‚‰̃ư· ¹€A9Ë®ă€J1¿ä¥ g¯’‚Ÿ‡3.T Ï‹*z‡^<¯qàyMGç)qĂ™@”â]NtyÇ—z¤†¼Ă]·3#¦zˆe₫‹æ×ŸWë·ü”47¾¤¹|úÈrX<̣’UXQ•ĐÂøÙLG9ÏWà¢^ă¤/#Ú48LR ä¼* ®áöUÊ)ëJAÇ%¸ZËç–jÖñ¾ŒïĂá­©œkä@˜8 VA1´daRƒa'̣믶ôë~tUFnÉѱƯăĐî¥́ -@ß‚®È}ÅE₫–Öœßk†; ‚¬Tß}Ç+ÿàl^¦EđRe©( ¬°nĐB1a)¹‡₫z9Q•£Ê)¡­l$¿ß~à¯H̀Ơ³Ütz-ié}ä^@¹Ë>Ë<”>åíèg€Ø÷è'ܾGö ¨8¤Âñ;†EḲàñtªT´"'ѵœŸ€ƠÿƠ£#Œ̣î2e eJËÙ̉‰ă‚zE¸Lå˜Û[¾›2 läù%Ý(Ú‘çÈưíˆă¼CI!æ¤"gs–3 UÑq¿̀óFîn&QÇÇPû@çp˜Gr)•"2·xr=#¸@Úe`«oÖâø€ª´1ê0¤Ñª*ÎÔù)¢Î9Í'.¶Ñ.©ƒ¤\)ÀYIbzđuyH₫¼«i!Cä2çq¢nNrï ‘SB†_˯dLhT)U’ƠăÄ(”ànƒƠ‰Ề65Ư3øD·ÀÀ¹¡gÍ{è±Í”è2ƒi‘ă˜£IŒPJo+¨VÈŒp‰¿)%Ø93Ÿđù/‚Ñ·Ăù) öEi†¼ü·2@•Bl(́í¤ôöI½Tщ·?v«pËëäªGóîè[bl?p‹x@sj[¹ZÛDơ§Ø”V1NpOºYÍ ®¨JW¥•¤{ /Q²WReŪ1·\¸oÇÄúÉt3tox͉4mº =¡̀膴lÔl†fŒVˆ zLj0½V¬¹GU¿L È]d•^kûzJqÇ Zê 6"pÄ8WW¾—ˆÊåJ|&Í ü.!™Ÿnđ.è²n \»_‡`—wơ5Ïñiàm~ÚóÚ’| &¼}!køÔˆG0yB†u1PàøuílAU1Æ!Ç’B~c«&%‚Ztrù”Ǵ́®¿„£"™ qFx)A_~.‚BŒàíç‰Óe€¯Q.Ÿ;3B$rÏP#(=X!É6¸tÉü½{̣3ähÖí®Î’ö́Zbzb2çA zœÚÿVZ¹̣%û¨c0đ¸HÍKêåô^h'Ùè[–Ô÷¹ư g/x„¯«K0˜ÏL²¼́©ă³¸«“Ë/JkQn9³$Ç=́ySd›¬Y/tK^îÜ-/p–%’–§̉vÏ’Û§HR ¤'đ=pq{™­”Ë£` ÷†xnIe3÷'&^3²›µkU7]ZÓ ” •‹ÊS61JFÅ)n-^c0OùÔÉW醳ep)èáímuÅQ:”ß]xSÎ? eAèu§[#%dËoH%u _k¬¦”lFκzj,©*5¹Ó¥[E"KßYʸ f—b40÷ápư#ĂPï̀¤ŒÜȶE¢:•“4€—$-£`ÑÉn¡CHÿ«-ăÙƒ­~=ߢRæüíßù@̉{ÑT¾^ư< öØ™I¼NîŸû9̀âÿưÍ/É₫¿-È)ÊçVh5˜^µCÂ%úŸûÿ ( D endstream endobj 1444 0 obj << /Length 3227 /Filter /FlateDecode >> stream xÚË’Û¸ñK8U#…o¹9¶×qjmo­'§8ˆ„$́đ><|}úÔĐ®-4€F£Ño*¸ñáÜdáMvˆö‡(»)êW>Aûó w~ÿ*u;X¸[¬üûĂ«¿₫’$7¿Ïư<¸y8-Q=”7ÿö^wƯƯ.ÓĐ^!L÷~ó̃ư₫ñ ”%̃ëOo¹óæó§·>|₫ôIºfB²Ïƒäfäû <0·KSß{«¿úAܘѴͰÇÍ7A²O¸<Ưg–m_ƒ(~¸˜aŇ[fW¯Oº—™±åöÛ]˜y¬ ˆ¸iO¼g¼èÓ£%Ócfú]à<”ó˜<_(;̀”½i»;xÓç̃œ/ز8 =U -÷j­»€3đ®7́*óˆÍk*…ƒ'Ù1^Ô(»®z `ná*=wMSʼ'¶Oˆ§í‡{Bo˜ „\Ưàníá…èBƒ®MÑ6åTŒmϼ©Ơđ8¬o¿zäez¿ơí¹Wơ-ܳ? ÀTC׿AqÍu¬“%›G³¿äÑÔ”xá,p¾̣µG°µ‹£̀{§́…˜ôêÚ_Å —*Ë^|¼½0̃ô™ÈnwœHDC·²»)çơ½¦Ç6Petƒ29Ú…µ²¬€C ̉™§y¯h¾™öL @ ³/ÑögƠ˜ÿ©…º\½ÈĂƯ–áûæDCƯî̉œoª¸yBrˆÇqrEJ•đçGABÏ”yÏ<:ơmͽ¶çªTƯ(˜«j9—{êe2gÅ“ăöøî¼¢í¤† ªîÆ3ơú¿“éMsF3¼"‹‘ík3  éóÀê .jlOs§V-’‹­]¤¿«b\Ÿxwˆ=à̓E‚3U£Ăâîøq+€iNÖfÑ¡g;À³¡yÔ¥³j±jbûØE³=Óª¯ é̀.ÔˆdGDtkÏ<*'ơrÀ6âÈÉΦ¾1-.²í-́Ár1t†áZƒ¾;y[có'®æ®ë+ó/X~ªI(9x™®o;uV#ú0ñ0œC Ü'Æ–A¥àăF‹äfà¾-Eñäq JëÖ0́‘?r85¨đØ "cHƒ]Đ—°A4™I\đÓ¶\P₫‰[f*.Z÷BVÙj”¢2̀Æ':µk†ª©¹5W¢h^´‹Ưđ¥Ö#qÈWµ6ßë' Ăœ2r>gk¦̉d/@ˆ[ÇÈ„aº“pJ/O>̀ƠñÍØÚ•Å?´ëđ%ZGh¶ª/zA—KÓgÿ4JBwă£ù˜jüƯ ‚·ÁªtÉ¥ ˜ă@“Êư6s¨âñ²îŸJá=[_ u,5O¸OY©­÷g¶ªŸ²Ăk‘«¤wkDœl´¯aë¥w¦/q#û(„H¦ª¤äÉ+² W‡æR¦Ï’¤ °b“ÏÑ«ơ[³™eQ  ŸÍÀb~Cªø6W¤Ú˜K<§ç­ 2g erl0đÓX|&?, •è0ÁÀå­Đ.²Ä±o+™¼´ƒ` oX¢nÿ£uu-uw{ÜÈ[J¦YËIä±ă >Boèµåă_Đ¥‘÷ÅêyÍÁ eÁk$Àù5«]7ơ"¨äƯRyÄW ¶«ä!Óh«®‰àS¯¥'q¤`™MÉ–Ư¥Â[XÅĂ^ọ́S €©¶Í]kíP84 ûØ]?aLv–î×ÙĂ¹@†˜)æÀ̃Đja°ÈWÈEưBµ̉~»†¡ĐŸ"Û¡D=›„ƒ3 !d 6÷ ÓlY«¢ÑÊ#¨\|”çí8®́5 ̀²‹I%%KUû^Ê ‘o3m]¬ ́—ÔÅ‚9Ñ[{s:lĂEɇ&RwI:„ås£à7‹/lly—ăD4©x(²µ©Ú”döƠ²ƠwkS`í••sa¢ä²0ÊÚ™ó¼Œ?́ă$è$+Ÿç÷8G;¬u9aæJ0¦¦ΖjT<‡eª„4†3óŸy5cÀ`×Ê"€đÄ…øMod‹̀†hW8aÅ Ú̀qÖMÊÅíÇñŧÔáÎX%íø?—ÿ“]z endstream endobj 1449 0 obj << /Length 3156 /Filter /FlateDecode >> stream xÚÙ’ă¶ñ}¿b*/Ë©ÚQx“²Ÿ́M¼•ÔÆÙrÆv¥â<`(HB-…‡gçïÓJÜIJ@ƯèJîbø%wUzWƠٮΪ»¦{t<Ưqă§o™÷‚™ß?¾ùăEq—Ä»}¼Oî!ªÇĂƯ¿¢ï.—û‡´t0_î²,‹¾û†¿~üyôA÷zT-C?-O­i¸ưÑ4ºŸ4 HöU•åư¿ÿúæÏî@EŹ<û?OogÿöÙ®:Ê]\äLÄăÎUô~G=!EU4Eư‰áÿ–±¡9eÔk}`h?̀Ü0ư}MIÔ.Đ:6Ơßg^æ³Ă3ŸỜX–I˜G°QŸ4"AlÔa65 Û2Í2 ~H²]R$LA£Úö…™z‡ù>̀g=2đ¢ÆyâæpäQDMtCÛÓ]3Ư0vâ!&}ç6-veR†l”7ËO wl<ÇA¢øóŒ¼ÆÏƯƯ?”e}¯&+Ÿîá̃ơØ™i2C?ñâƠZ+ơ-JsG£9q+dnºßG§/.eK ;€¹ 2ËÉ=‚Ơ( ^[óZËp₫|–)3At‹i† ™;ƒ‡̃î©y₫§qüƯ»-áQ=n˜§rh¸Ï߉…tzjeä‚—0 ‰¿›ƒ–uóYÄÚÓ¬f oPfdå₫NÏÀưt₫‘˜‚0Ïèè/°f&¡Æ•¿ÅI9vÓêø|ú:ç¬ÊA0–¾5¡`WŒ“½RÎÇÅKyVÀj±„¯¢ƒ}s‹Lx'¯̣¥ÁĂ2_–™Û¬|‚¼'EÀÚÔÙONlfm·jÛ%i !y’‘Äă7\5̉ÉøD2Àm3Dà8à¡oe‚9̣0SCDÀ;bÎÉf,[j¢á"+L9Îs0ä#§+{„D9¹x̀1;ï.1EQÛ0/q5K¥wx¬.“E$Ç{VíñC8úºĐ¡,¤̀¨›™}5tÉÊaƒø \£ø£EJÓÈβ‹PA»æÉ̀2‘ †ÄṢ̀•·³”¶¼=q›4¾î°›ưỆ3ëóP2r·“9hwgä 0bĐ-©÷}ÂÁ,üÂc¬›7̣÷r]g.…&G§/Üq$ÆŒÍ̉ÁÖ7́_9àÀ¯¡f&¨ÎÈ̀µ/7ØYëløá| 7x&r̉âÁN@ÎA9"è­ˆ¶÷Y½0‹he Y¿Ă·"¨Vt°“Ä–ûlR…‡ £ØIàỢè•L!“Lâ¿7°úö3æpoÛG}²÷ûSÀĐˆ̃%eß±Y0ï‰å₫¾Χ„a¼°•ƒüˆQlUp̃y±†ăGèMg2oØc§„ôJwvf‰ eGU ¼ĐWƒ÷ÉÈöư¿;ê¦Å$bÈĐ'Ó¨–QtZMË(ÓDHnÚÖÀ© ưœk¤`æ%dâÎqiѶ-±!ĂS‹r²>a²6ÓXTI"kü弿₫åÓß±•²öV«¸f¬ B{.œƯ±ưÙé4Æ)‰₫̣E, ǃq”́÷%Ås™qœ9AÎ̉*²'B†ö‹É†a»2îy4h®K N¨híQö[(¬>3TnjÚ´)¿9¨‚à:+;½0\á§üP¸ơB”?Ôkœ4¦$ tÎC§eæ”hpæó½đá”ÚÁ¼Û“‘-›¯+%‚Đ̀¡•P§UÜ£Ư*›IU¾}™%à>ñ™́­R­X(mC$¤kÄAÎcæ¼ sc=6f’à1 SŸ B¬FÔ®-_x«ñ-vE°r²d°K57nB —îmfRÇ>´ÀÎÁLM«LÇ=w±Ø1R3 ¥5Øœ2ú {1Xפ„‰)k~]ä́Ăf™p䯓I˜fXM U‚F+ ·ƒ…¬WG CàúŶ)¦_Ÿ̀¼Z{μ$”„rªO>₫Ưë‘ơ0t1ăÁWó 2y˽ֺ|ct1¸`Ôç4¯ù Ø̀@§Eă†q^ (€k½O„TÓ’?‘ÄÆú€£ơ9̣VsÔú•ô¨xỮÿíº”î_•û/H>dR¯?¹øú^{~dÉF}&( ™ø¤&Ú?‘÷‘D́?Üûô æZûá›7W‰#,ÏBÛMŒµ?"/I8ß„Ay—¬_•ăw’}ămh™Ut'·H{`Ƚ•Uë·²Êçä!kÁ†0]†‰¹́|å€*÷Ès|­:ª…ºĐ¦;Ó>I——È£«vL¶FEE=—JÁ7„«Øí“+ùR"_üàRæaÄVRɪâ’öñ„t¦sÄ£ÖT̉¸w%enơ´ œ,‚Wa$ăe&¾}o•¦AL™¼ơ8ͯ 6G "xP«]åâç5ơO!ơè—™†^P°CÎn]₫r Àc@V'.ÊHY`ëT @ [4 ®Ü“Zó S¬ù&Ê-7/Œi`f±³ª¡×9Đăù{v#˜èåàƠny0ȈÏ7đ@à)…O·2;2“•ÀἉ 1vỎ̃2æQ¾«K²ü3E}䥳lí¥CÎÿÁ̉¸Ú¯¯º‘«ö¦ ÜÁCÏ?‘¤¹¥&„ ¬ĐÓ kZ„)Y†neâ™?Ïg(àÉăsn/ZWû ²X"(zå×7XŸ;‰Cyk†"kp~nËĂ4iy™E Ù‰œÿ#€ïÇ„S"ªÑA›¹7ă,|3ƇâuNffÔ`0e€c.Xç%Å'̃A‚‹<óá¡]!•(ùGÊbƒ endstream endobj 1453 0 obj << /Length 3197 /Filter /FlateDecode >> stream xÚƯZKä¶¾ï¯ø50Ưѳ%9'Lj ÆÂ°×‡ Î#±{èí–:¤äƯù÷®)ªG»Ùs° 4Y$‹¬ªUÅ̉d)üËêü¡nCSÔƯơMJT{~àÆÏß¿Éd̃&÷æ¯ßUƠC–Ú´Í̃bVïú‡'ßÜn»}̃$zèÍÇƯ¾(䛯ù÷û·¿b£L¾×ƒ¶êÂÔŸæ§‹é¸ư£éôà40ÈÚ:Mơî?ï₫ùæ謁:Teñ…§÷³ÿ‡YV@üxH«’¥pº›̀8 $yRóê{ƒD¦Dy¯ h B£ "ÏGØ·=ä¹øS¼ưM̉×›¹(qJ@ ëßâÅñ•·Gb„́™éYÖ̉M£¦CܲđÈl•fè5^‰ư¸f”áHœ)"…‹ưl–ƒV(ú†Ÿü…OÉ!ËÍAM3¹(hë8Ôq%-̉L| PÖ:–‰^V:–HBôå|ØU~6 q#ü?™!°"Ea‹| lù è.·œ-b ‚Öi´Wn)₫¹({&uCûÆGü7äˆ:Êè8¬’„ăe¾j>­†Ư4ZpákđÉpÆ3»ễ̀aGÇÄb ¡Ù N÷·¬(ƠùŒAg̉_q|2÷l JŒ`>”…fµ›/“Î~Å`Íù™î®„V+ù¢BX/»L¹˜«‘ÁpƠuäV8&f¨… Ë\Ø_à0Ă¾û„­̉Ç)hÄ"eÉ_dºSi>q à@ +ñ ÇY1‚d₫0ưŒ̃H6W»q…°/ë6ùaè.3…Ÿ )è¨Gºđű}}áq̀ïÀ=²xä×Û“9ÄóØÈ…€F§f'S&I 8-h$Ô·‰ºƯ(ĐRă~đ18²˜ Œ^y øÅp@"«Ă±©Ö!̣(!̣ÛqXđBCoÇaÿ øåNbów;@=ÜHÇ,Wåÿ¢)3ûªBF‚NƠïQ'ú%R³¥₫v•ä,ê2|üH °vS`úïEá7°5ƒËµwê¤dSø $Gu¼wém-P¨·@₫‡Îmz¨| –miÜQ7r«[)i¥\Àă;Wp{«U¯.2̣íháî3Æá°º7¶EP>†Ö$è§đOh!L‚­“!Ï£ßq4Eđr:Äé:a »¯i“êĐfwxP›m+öhŨỤ»&k¶-[³fkB× p¬2+É1ăÍQ†ơÁ†7„¶2YñâÛ3Ñtä:`ÚÖ̀¼_“ü–V©AÁª-8 ¹ñêè#m®ăD™Ö'€m†‡É!9ï­àƠ`.›µƒäu¼*k|ÚÍѧv›Ún\?•XĂÛ§€€åŸÎt×4Ï€¢7ä:§ñ?/`tbá`…ΦX¡ºÚH膹¤ ÍÎ]Å?>‹ăùäg}Zˆ ?°!Vˆ̉y*ÊZ. …™Acẳ•œ}Ö.Óî´JC¤qœ́ø÷ùbxЦ4G¡%/ÈOÑéxÚ–ŸÚtSáâp{í¦jŸäb‹ ·Åê†Â£5ÑBÅ?đ”ídUkđ£g*ÙL-å JHÙ•ƒ*Eŕw£›¸E–Î*€Wo!,Ȥ$NÆ mÍaK!˜Đ°ûÉÊ Úê.Ÿ˜7:i„J—5|Ó€ˆ0̀†9*ƒăqK¢¡Eé̀í¤éqÆx²£„%x½P̃øpLmH2ẉe'CÙs”˦u»&ƯV0Aơ‰Bé „gá Ă#ÀđËg­=– «KNj_.9tå+a…¬4¶Å/ør >2“ºZI-}ÖÁ¯ ’0¹j#CÔ‹!€Î†À¢$Ü3)JVèûP#X< y°AŸá«L5—Ù*´.¡¦±_è:å¨vËdŸ(Ăø0Êö[(ß̃Zn!Y×K‚-;`¢â|‰#@¼«üÛèilƒÜ~ ˆ}0Í_jÑ[n §x(~j´•mqxí¢ÜüÛØăÓÔ#ï³²w ÿ¾!¨!!‚Ze4—Í©!ôưMÆ6_<¢̣O¯9ƒƠ)]„>Tî:በ)“‘µè(ˆ‡¤{̀åEÉånJBSRº(Û(À₫ïl$¡Đƒ,Î-µú%…´Ùv Üp>²ºLEĂEkóÄ©« Eo•íÚ¾ç3VƯ¼ƒË‹J–cK”…£\ ạ̊=öO³• cGif¶<‡i •2s_ÊD’EXa (77#ªqæ†(›^9‹¼2z)IÛĐ×ơ)oW.· …‚ï?œ˜eX!ꑲ῀÷–,T`«¸,[ƠQ́À¼Œÿ‡—đ qíß¿Ơö# W€2`9?«¨N©I1JÙ—ô†ñà»̃ûxvd,.IñcÖ¯¸Êđô-W©LRÙÈöÜÄ´™XpôæQ$LSfǤ­ ‡‹È8p°>€%sïqüM£MïKuä‘ñUI…¿[<9,?Nz€·/­`€4·¸éï[S®}"7]Çf’ú'`î^óÂ1—M#¾›(z„‚,9lÉñsô™°„ïÉKø̣Á%J¤ÄÆÇ‘gÈïd2»¡¢̃ŒÏH÷û“ Ăwé1_ÔŒ¬&EÓdP–mÏâÁñằ¸$H´¹ö_øjTüYÏ8ŸŒ…¯xPŸåä´đo¬Bs°NüDD|íB÷₫#Üä?»`9½,u"qÍüéüÜƠ;·­üV—ù,Ö¸ÊHg Ÿ[W™Çxp‹₫đÀ£Uù*ƒ—’Te1ù¿Ï¡úÏ|½++ÿ•@‹]Q…•â[Å5]ü¤4÷H‰̣C²t‹o}'s¯¯U«4»”Á¯₫ˆÅ ÆDă3­e?IÈ7“à{Ă«ưµ$¶ƒ.]´6匾¸‰¾oBûGód•ơùs™–₫ă(Œ‘®'n‡†®\ùi”Û¶éæ»±ơ€iÓû¢[úù8íáµøĐè]ö ¾ úö+}HÇ̃OVî*T¾b¿@¢ .*&¿!…àæ«Ÿw³ 5©Y|ơÈÏ’øs%̀ºj5È&ËßJ@g‚€a'X₫ámưqÊvÙ߇öÉç Gÿm”̃Ø¥ÜåˆoX{å‡RåKÜQ|-’> stream xÚZYoäÆ~ß_!ø‰V oÎ8Oë$6ØĂ–qZdSÓY9á±ÚͯOU}Ơ¬0¿yzó‡o³́. á1º{ª×[=Uwÿ ̃].÷ñ!°må>Ư?$I¼û¿ß½ÿ•?̉à;ÛÚ̃4€₫4=7®Ä÷®´í`iƒèX„A~¸ÿ×Ó_ßüåi¾PgYüÎÛ{́ÿCÂ1ỳ‰ü1̀RQÙÁ½´¶¢[qĐơüC×(¤(\[v=\–]×zø=ñ`́02ø©^h›Æµ/÷Yv ¾Wüʶ?»–fx=Ùñdơ`]é;am5•#&Üà >ÍQ̣eˆ(»v˜Î²Çq»øíưCæAƠMÏc=5@(Í`|'Ó4 !LÀ{K,ø(DT€¸¿µa¨Luz`Wë¾ƯÚéÎ]ôZçΦ²[£W¹|ÏÜI9V±˜' ”» à3`¦Å¯0*óŒä…Q4\©.¦¶MMÉ‘$0p°¥̃®SÀ̃€øp|@Sưh¾(-àưv;êgØ;æj7iTl|Ơ[(²i+`©W.®ø Åóê¨Ê©0đ9v+J­3ºcO~Đ(Ơ p-V¬r‚ƠÉyĐ»—Ó́ưóëTH:Ls £fœg "ÉsåH«đ ô?÷L`Đ•ó 9#ó…I9¡4!v¹̃…rHwqs4“Åz•V¯¿ăÄaôî?×|„°øö…%Y&ÉúüUÁ¶röà,ÜæJ#ưRP¡S^1Đáû *iS°̃ô4g)ÈØöX÷¢xY½ïóàq‚_¨ÖæĂ¶(iväÍ!>†j ÄPơz<µøÇX ‰"°˜’²—‹ißñYÙ-kÆ™£Ÿ¸í0øf̉ưå"·Ú…đhÏ‹„É̀*”;4l;“_.0É"p5@­u®¥ÅÚ»ĐŒ7ZÓj–̀PºF_.f´̀ôv4®¼±zä³kܬT©jhÏ¡{/]{₫”đ‡&é5€å’˜²ẺÁb¹©7Ñtö%ôµ5#†°oâưdΗ†Sê´È–ơ‹£ä‘8o>çÊy§ E₫Âdf;´ừÛưíGÖà]G/a:>nË@É{è—³0V]W)ö•* dH ơ¬<¥à*ñ›Éïc~Çád7;8y¤ï#çḲ?ß)¿6Qº~Tˆí?RoD3}Ôf}oôxQ2*§uºÓêbÂ&•­ÖµŸ2ZŒ¬´xǸb_|̀qÛ¶€ïä`̉ÙäJÚq-•yákLúØ8_ÎyÈ-bêưÔøXaCSùk«© ‘â´Ø§ Öi¡×€Z*úmæ[D?x¦àq¾we ¿]µÏsDŸæH>CD²b.Ͼ–æÁ̉U¡Aeáù›ªĂV÷D„µ»¹MP–k›ÚÀ̃_“ ¾Œ„Đ‚¥̣¹<§c·ih×D«́LùPeÜù8×Qhlniơ M~t]£Ê·^ÓO‡á’#5!é0-Ñ")uÅvZ§Ôï…Û²ïD ”'jÁŸ^_o×¥́GÆGFA/)}¨Ùd±„Cî:IM”đÚͲr3¬ÅØ 6ö¥f‹ƯÈé*½î© 5}Ư„8%`NDÓB¢îQ7ÍWÆSRÙàÓ`wÖÏPè ¹HgV*z‚ª,§óªà H:i nË`£G9~Í­ô|®$™0ăóÜHvVhºvđéZ¡WyZAuÆ!åÛ,¦˜>Ÿ …Ï*‹“x‘zsLµzä’¬KĂ…Ï¦>Ưë½tzu$€_¶ïɦöµ̉Ô^Œ¸¦¤`o¡½5ªnI2U%Ù{ ió¬¬ù!Û*mÁmÔœÚWU嘧¾›₫Äq€’̀k÷–r‡d³Œ¼®7ơ³“$|ø `#\¡Î[ưD”8¤¦ujuđåév…8 ™s ™ûüÉ!›COœ ³gGÁ§̉^F4#¸ó]³iJ‡€=v+2œ;ơç®÷Z;åẫP²‰ËF̉‚Ï·d­¿b J57ăưÖœ-’?beƯkê°ž̉ˆÓ@S!)÷{…Q {é͘¾ëg«ø@H#© Jo‘À,ÛvÓËINRƯôU»1iæRù‘Çvº‡J•1V[Ăn{ôØOă’í>YÀ—ƠÀ.¬aY2¥¶«0ôơ¿T\Hp3ßÔˆñ¿rBOÇs%/ˆ+±đ̃·bÁv’±KØnñ¥Ư/~/áüV•Ă|i„†KA{u*i‚£–Fß¼³d%á€Kø$¨F›ƒ¾g%ˆåƯÀ  Ë®©Ñ³Ÿ§Ñ¯PD»h̀PưI¸xÖƒ\Ë˺;‡—,iĂh¡!1̉ W¯n¾ÓÉ5ßÄVüî*¶+×sMÓn°ư;jE-Å”´©|­Y UC0ă§.ùQ:·ÁæÉmR€ê¤?HP•ª­˜Z$É›Œ›«ôzÄeéñOW'誹̀̃3öúƠ·z{sµ5×:…£/h¥Ñ¦ê‹ĂÁ‘Gí» ‘3Úm>‚^}’®•‰e2 ]½kóï;$áäYø% )Oœ­•™₫‘#[•ïhÊl_í7‘¯œ½–dϱ•g$/ŒfîÈ‘U¥u ÀÏ#aà"[XxNo„‹V%èHûˆơá8_by•̀÷9̀]À¦’'hy­ư"3ú3A$!7ùØúŸ%ù_¤¿Ôñó_Ë̉́ñ]e•F̉?»^´Ưy­ÏI®›2…Nƒ†°Ç¿q¾'6#²uR¥²´çÇ.l(ñ–vÑ£uÊåiơù„“,ÔJ¢L³ª¶Ú¦Ë‹œ£\Óóü¸aÓçôÉz₫HíÈ-o•7?‹»œđ̣Ú£êYzêè¹(@ ÿZ ÅA)È/ỊÄØ EèSÔ±¢i/¿Ó( vñGz¦ôkÿ^Èöw¾ùfø\Q6ÿúë+ưœUz=#À»ÿ ™pC{ïoÈđÊ —FíÆÿGI¼²xöçT†₫µ̀øÿ“!t72ÿño'ú¿Bÿ#\ï- endstream endobj 1461 0 obj << /Length 2975 /Filter /FlateDecode >> stream xÚÙăÆñ}¿b' X)l̃Ê>M®uÇ0ŒÉCÍCƠÚi˜"å&5ăưûÔƠ%Nb,0́ª®¾ê®̉ª‡ ₫©‡&hÚbßÍCw₫Ö}}àÁOŸ?(¡Ûá.¡üăÓ‡ßÿµªT¶?dơđtJ·z:>ü{óx¹lwy»1ĂÑ₫ºƯE±yü?ÿđO”›Ïf0N÷ŒưñúÜÛÇßÛÎ “ Ô¡É6ơaûŸ§¿øËS¸P•Wûª,~ăí=ơÿy‚ʲ½Ê‘+ơ>«J~G·ßîê:ÛüèÆûlg;|…;fjs¶“3g&3lá³í8đÔxâïübá́W{7©gÙIÏÆYƯD°bF;óËƠºp^B?göK¦JsD̃<¨jŸ5‡‡*öªR|ơW¼—qÜk‚•MÅg7åfºv8÷ÂX>Ï=³Ø8k÷ó6o6p Áôø:£§qĐϽá-̃p;¾ÉQzbJºeaœp‰'On<ó4³¯ǽVm€Kp|P&o¹{Ê'Öà’íT½ÏA|;ỚÛ²eê£È́{{åmÁGáà:Éà„¬ÆÁ…tÏÎôr¬Àăd&F!÷đ;èó-ª'…G˾ú:¿D$ÑæñÀµñ¼W›O,HÿøøđT/ăä©FúgÓơvà·VÙfF©€ŸN{¾#Ôđ…À‰áëp4)g§†ÄM3= óæ]á̃Úđ= ¾Óx mĂÄÄ&Đé¼nâS×đJ²ưɸWà&K™–|â‰À†b_Ơå’ 'aĂOÑfrRW8u ;éÄ>s1œîé¸©Ë fôpd̉(AẠ̀ºJL1'ûđ¦ƒøg¯?¸p`5h0Œ{{yY7;æƒË­ª“Ø #èKVè°&ºx…x¿’áó/j6˜±3¬W<~³ó àR¤NwóƠ¤§éz¾̀~&́Ñ[ưl{o2©Å÷!2 ª,«B+>óhíf̃€oK<½¾¶ƒ¨™rg´ë¡N¤)¶^£TbfŒ₫:âÆrâ4̀zăF àçÄØ© Z÷£ß]̀ FZ–€0ïp³A­Jåøqí-‘»‡œC°V“0ΛOE÷ 1æ,F˜ÔüéC̉dGv*Ươ7̉Ü0Ư/®âƯùáîŒxÆÀ![Dơ‡(´̣0gø",¨:çÀ_9[üc˜–†C ŒD,˜QA₫x…SW€ÉÉ̉Q₫¬DŒĐ¼¡?1Ḅ>Á!$:³[1.¯C*³gWU0s%ù™̣GA(Ü ß§ÀJŸáx»A8&j %[¹ØĐª]!6—U,É¢¸‡l"»Ư>́A\JÔDz¬¢¸ •eéÙ„8ÍñçNXˆ¤Œ”„…º?ZÑu£ód¢´5é âÀç±ÅíJp–‹‹œ¸N3C—^w†Ẹ̀°ù­o m^·UM­A3(+HsÆ«Ắǵ{Ê•JL…œ•‰Ö‡(Tü’LqF –UúrÁàGÈÑORt»?VVäÖ"•$ ™•í¼7 ¿jÉ™RÁ;ûX)iLI—…\8răUmxL£aY3%*Ô­D»6áƒ`eoqƒÑ)Æ5’–Ö˜ĐS̃‰WºÎ#D)0·~]3g%å–Ê»;ÇPZ+ ÆYxs¨ÁP»•ü¥É“$¨QTØ¡ë¯Gv€ )='½å-bbˆ Vđ’œàF©4êÜdåÄtĐ aƒ‹„#.UJïÔ©Ö>K#Eäw#×¼́”×2 ²àñNÜùFYÀ•RIè…PŸ8u|ÏăW;ö¡'ÔJÛ§ơ9 Œ’E‘u e"€bÚ·Nđ0₫`l»k¯eA7^ˆÛk©H)ª9„í±•µª0Q‡Ôλ£+M-å"L‡Tc"×Ü“çÀ'Ô%ˆ ‰lĂềüX¢¶çÙUrSd¨W¶†/Ö,.¦K½™u¦sʼähC°ª=ñ´HÍ1½pY6~̃ú̀oEª@ô ‹ËP!è(±u{æ'ŒF´îz̉¶Ÿdåø^˜%£/’ „¢Åé&¤*V”1»ÄˆB {h¿>đ–ṬMb6Îú@ı»ÜÔĂÇØÓĂPr}́wè@äI0¸ âÿI=öG®B¯Ó”HZƒuÅ©xµÔïº\c1’•1»Èr©Ë¸Ơ@yʼnW¼“­U%bÍHjÔ}™¹cÎ=_DrâƒDrzÉ!-K±i“a)Ÿ/ũN7{ă-Ü´¿Ï–útm–çÙXs@”’±ÅÓ—ƠzFm2Iä|ñ–¼94ß0OkdœF“¾kÚơÁ’Y¢8 b‚»ËCÙŒ£{iÜ{:ÍGI˜|}7jî5d¬>;]Ôa›"cÊÔ0heªÚd|ÀDÊ ’xl‡êƠXt“i¥ùpfÈF¤±a 8E©’0ˆ@Rï!È¢•1+à d5B₫.dfZu; è°½è´Qp+0Ñ­‚ZyK9ÀARÁĂM°¸†ƒJÜâ!f‡Đ—Q̀ÔjƠPe™¬óûc #qG–ƯY"¥B0Ăÿ̀¡$^Jàk|¢Û¼çu`&ú' ©»‡YÑb£_ ÇÉ‘£èè÷¬róƃàV)ïD̀IZèw½NÑÇIŸCß=v›‹ÀaêÎw1à`CđƯá 5Ăc‡é¸|åø=Vs¯̃—='oiß1ÿ1]öÅåŸH9~Cµ‘ûViN½Ö™.„ơ¥‘®ă2!§_¡$›E qWø…®u·’ <ç©₫b™¸Ê"Íï¯̉üÏQ0æé~M4Cé¼v(ô¬ µ‚d•̉0ÊjΓNHă«£,í„ %]~Óóó?-Bư:ö¦—#¨bÊ8úfÔđ›€}†Å—œx….₫`Çè¸q»yÜ­=$H¶ i₫D…97 ÄÁÂ×ùÂ)UkE¼ÄOä%B½ư™H̃́$d‹>–èÀbÛ_ĐmZçw ÊI=Ñ6ÖÀÁ4ÿ'3|AƯ;:éï—*’üˆü.p,è¢Ăr2Ó„¬\¶5F¿Ñ(“±NÄ…£œ¸¨b*Ư·ÆébUăøç•BA/´ó¿û(lrPadj‚9oG¢£€ü|Ey°<‹ÇVyâ±Køyé ûIàŒp?vNóôÉ·QË߃½ø†¤öưÈÛ.BỤ̀q%ơ†vªMǿز.ƯG{½puiÂn§›ÿØ@y€äÇÑḉ{ÿÿ₫ ÿ\Y endstream endobj 1465 0 obj << /Length 3371 /Filter /FlateDecode >> stream xÚËră¸ñ>_ạ́%t•åđRn“dwj’­­©sHer€)HB† Híưúô ¨¡³[®2F£4ú e7)üe7U~Sí‡]QƯÔí»” îtĂ_>¼Ëoˆ›óÏï₫øcỸdéĂ>Ưg7ǘÔăáæßÉûËån“ïÓ́ËƯ¦(äưŸøûáçbC%LgœnúizjlÍíŸlmºÁl_¥I•̃ưçñoï~x *ọ́¡TÅïܽÇ₫Í#<¨-üß>¤¥âSÀèƯf»M“÷ÓØ·z\nĐv'>Hdđ_û;8̣s7ŒÎè–Ç~1µ½XÓáÈ8<àIṇ́!S7›¬zH÷[^é]#Æ&í¶Éh[Ă­W„öwêÈ|Ăæ•aÚÍ#ÎøL“Ư—{èî÷Éx¢.̃“ñÔMC”KÄü,±w®3DK–Iăo aG×·t¶ÎUg…’»µ£¬£\¿Ó\å€wªëÑöØ»å1¤s5uœp4Îщ"²8º¾a*‘)½;éÎ₫ª‘\‰ªđrx®f³ÆåaÔ²o–B\€6ÊDƒ̉Zøí ’%̉¡['Áùf¼Y$̉ ₫Ơ¢‰­q§€ăÎn*ØôÇă|{a$FyÁ¦¾¨#yNjY-ÔƼZrijđ`Ø!5bBđú&] {^&f69‹QŒ̃Ë—T… ÀƠƠ[÷¾[vî±±'c`ùi¨û‹—±­ÁVL gE0è¿`ÏĂ×d÷°"¨¶0ŒqÄÎÈø(3ă*¿ƒWÎ8̣dt–ÂÅ™¬= ¤°)h@Ç–ù ·5Œ 9ë£*ê~jt²l¹7u#8lk }³ưä—ƠNŸœ¾œñ̃2•\?¢̀ä™Ị́1Å{„3²gíA†øB‚çù‚€¿ô.²Q¬ ÿG?92Cr]áZü¼H:¡wDI!™ô·J;îáM2Hä/qq65†O 6À×î‡)£\Ü ¨âY‹é³#ư@M€“cŒØp‚úN‹yeúœfEï¼¾2 ̃₫ọr—´ZÄ:/÷lơj[Ï|Ă6X‚vœà¸Îâ¸2ä,©ÓÀèx[øe¿(æÅ€›đÔđ>*Ă»Yd₫ m8\舶„f8ÙœlëZ¯p7Èeæ] ´bßW%?̉ÙɼhpW†d4A`(°;́ ¡±` 4æ:Gă)º‰À?ƯŒx×»JdÔï¢gFb“›v'³¢äsó]órÇ–¡ BŸY¸@¸ƒs$2Ø…Èà>>üJÆfâÎ,"Đa†í,ø¯QvÑ@Çûưœ–©íêf:¬Ú^ÖRPd`^ÖoêFÛ–áÄè'o¨¢QRÁjdz«¤¡ >“aƯLÆÆœÂ:âpÅ/‚:8@¡ÖØQ¨Àk1X—¸9¾Ϫ¿X 5N÷ÜŸ0p¾g…LÓ̀½ƠÓ¸W‡hjĐ,‘ú³È!CÆ€jOæÛŸ\7ƯÆ“èŒhjXd8ï¢q¼Ù>lVơ,“”à‰ïø›‘ư{\¦¢¨,ÄLö ÂmwË#,rtåøñuö>÷ˆiÅ^™¦Lă"ë_˜Xø+”ioyiÎ6ˆveWĐa-©Äâ@Ăóí{=ëEI4Ḳ́'HÛ:₫>Ÿ­DIÈóu`Ç+Ù“̀ Lxd̀<̣çL©Mƒ×&ÚúaIs ^ñü₫˜®\ K{u‡îơv=ØF_W®¬B` ÁÙ;Ṇ̃ĐB³jÖp‹­¤¥¨÷mtÆ–l“ÂJb?\Æ‘yăǼÜCûéê(hù¤g#₫ c̉ê ^1uưu²Ób¯À5ú8̣Œ‰¨•>Yƒ–£°ËA»a³e‘1±²ĐúvÍ´ºƒRYˆ`„FM1ÿµ¢Á@Ä0%hó‰Àđer!²4Ó¶9`X§Đí2‹÷ÙR±ûæ–…›TÆHçÍE––÷+¢Ÿ¨“ZV¾?PơJ̉r!»!Í]P_ €Á°œçúâÀBèüÅ”¨¥^çc™Øay‘Vÿ·@0טrJMƒ¼̣u 0sà~ˆưrÎiÖơƯƼ'ÉÜH¹•7ÜÍáÙÜé#ø_&!ɉƠ~ií°ïƯg%&RC}$ëÍóñªƒA¹âx˜&×Hï̀@ÍøÑ̃WÛÄaëØG1ó..x!´5º–ˆ^±¹7_éä»”' ÊQÚ™µ“ŒoÖâEóoœI*m'm»a¼2üóa '^5ä%h²Ñê»ÇÜYH)d¤’*$%óă@¾¯’/+Ük#lt¦y¥8IơƯÚ¹£(_®|¾¥s5jç«Q+ẃkSù>•$ơOiœ́ÙJàWÄơÎXBm.ùä ±~å¸í- íA¨²Ô§sä—Nµ/sµ—¨Áḳ£DœƠ¼ß Sóvó×̃FÈ̉åû8Í1°qưt:s‡êÈ à_ĐË ù¨%NH.é̀(æ¬̣fpMƱTH:Xä\7 ¾È’c-VlX¢Æ"œoG;0\§™đZ°n.ÎzÆs°ä V82¤—/ëvû­u±1R6#-Üca‡¢Éâ“ó«Q=5ZFâg?IÍŒ',¤]9áưz Ư(¿ôÇBôZnăèUüw †Ûe$>J‰/˜ÿùH¶Â“’“ ƶùÉÖäz1À3lù̀ ¬|X,R.ƒñr~˜\¯ £j®jæ®jÁ¥äÂ₫̃ù@‡-#è³XÆ[éƯ 4g€ÎYÏfẂIùˆRÎO¡Y°»8ĐxFañæäÍdzô¤™&OëY£Ä ¥t¸ª¤Ẹ̀¸ÈP±3đâàÅ•Qî1_qe¹1åï\I‘ªØÜ¤…'-ùE£œ+•ÎÛV\Üoy¹‰Åp<_RQëS¥¢[Øøî ÑûSÓÖđ«ưŒhkTVÙ^NC µ‚wd́đ̣Ôpüm{'Jn’y ³#B:³”‚üơgĐkñA¼?‰´¼q̀Ey/m~øI½s¦ºHcMŒ^¶Ù66öđFÈqÏ[…Œ|˜æ\XÂü̉•îähG/Ä‘·Äb·÷9.‡%øÁ̉ ù—ƯƠ‹sLM̀Tµ§yü³ˆ]œƠøè‡ ÙtVcç9RQyÚ0DŒª')D«|E9(£åç|…&ÅZñ³¯ÊW´De‹ß'(ŸÓ©|QZP¹'±Pa;èË•JmßÖ\rD•—ó  FæÉ%CÁUẨk}ÊcUǯ?óĂ9/Ö ©¿SlÊ8ÓÀzé/’]Å₫jM®¢[ÅÅ+¨1HT ¦ƒR œŸ¥±Gñ›R>œ(¿·Qƒ"âm^HK£Ùj™dANMTGA*¾[́RĐªÔƠ¯mV.ưœ9,5˜«Â¤̃±¯kA‹Àµ‹ß̀uÀB‹ óRCèo"ø+¬ÿWĂA! endstream endobj 1469 0 obj << /Length 3232 /Filter /FlateDecode >> stream xÚZKsÛF¾ûW¨r T%)ÄÜ›’(¶dY%1ë¤6{APD…¸hIûë÷ëÇ $»\%N÷4zfº{ú5öÏføçŸ¥ÁY…WY˜»w3ƶÏg2x|ÿÎWºK^:”?.̃ưđKŸù³«ùlîŸ-Ö.«Åếß̃ơ~~d^Y¯ª×óË0 ½ëÈïûûßhyï˺ló­`ËmUÈø®*ʺ+ÁÀŸ§3/ơÏÿ³øç»›…ƯPÄWq~ăî ơW0¯œ#¹Å‘Û‰|oŸ÷e}Ăôϼ­ÙMVü₫é‡Ñªê¶ÚUũ7í¹ï½}§4kưU«Fd£ŸÖ mz%©‹ía¥¼_ª~sN8û⻢!é¦Âáâ^™ íøó9QµùsyA2„<.ưđÊ}9à¾m6Ơ²’of¯Vʸ|-Û¢êjÖºT+ˆJ?)(˜–­º\)qmØÑ×áÜ«›ụ́˜Ÿ!UĂw×´. fôÔ3¯­7¬…nt9I¿ÉI‚~́å̀ÀO¼N-°¨₫œùQ‘o·oBñÜæ¢Nú̃J‡zU¶2́7|:°PC¼:¿ŒẦûă< ½æ S»œX(ÇƠ,Ä¡bÇÂo‚Ë…†’êL[êª/„kÚ¿b;ÁoD„…&4Ƨ‹đQN? l³íu#„íAă€BƠâ¬ÏåÎÚ/!Ù¬„L¿ÚTíj‹•F¤äN‡µ™,å£å¡«ê²ÓiRaqú¶Zúª~:J׬y©úƒsÁÂ"?°˜'̃Ë7±0°ËÿbQ”bÛ¼éáœDBÂàßRé9 眓Àẽ•:ĂÖë~U¾ö#¶l˜ĂvÚ k̀‹¾ú\YAfbÍô;6’ £E”°0`FL¶S¯¯R‰̉¹+í§F‹ºZh ¾S¶l&˜ôщᔯÏ]V`D[^æ{mYĐ*«ÏF9 If₫İø Z·ÍNˆßøj`väzæß#PŒœ́›àFđà¡ü9‹g9₫øS§bß… —º,È‹œè‘™½[M›fåD<9h“̃¯Bl†ĂÉ"cr6¡Ri—tà7¦€ưăÑnvùJư5_˦+'ŒR>%A@“™øÜ8b₫Kƒ{H7o+ö–×B‹-†e†ß‘̀«̀@ÚixR×+HÆ® ̀f·¯¶9±êĂgB_*Â>çM„‘ 2ÑHb\@:׉ÀC½e7EăAÄÔz†+A4f.HM\‡ Q_–ÏáĐEc‹l,râHâÿtWClZ)o¨C؇v;A&đ‡¼-ˆx#`0›¥Wv…ä 1KV¸oàÈƠĐu`Áe¾‰rÀܹ·¥Û PÊpis <ÜùÁÜÚ\¿-_)_QæđÜU½]̉º^·ßV¥ú  ]„Z¢‹X³đ™ÁN–³*×´g 9d-`«zƯVăxÇ&ˆ‚6ß1˜Û §$Dµ”lAærqT1<0́r¹UYDZB×LWd³á(́ó%FÛ©›xb ä_D}È{¯üHu8—oüYH‚[{߈¶Ÿm[j¬I—Bï#ªû^€_(ciËrỚ„³ËXă–ܾŸJ&§7`É4üŒƆĐpˆ$ ]x"Äà‹—zÙ”ª" –&¶à‹q²tÓbÏ’QåÏØœ£,Ö5ŒvÄ1ÑÔ×|B›¯ªl‚¹æÊ4pE0É)˜’ëVz.âˆú&Äœ¨ă—ó;"„¹:ålOO€¸ßoXY/̃Ä1œdÓX-A8«(̣Ú Úx’r¶DdG:uä 9D#‚ºF~é*Ó—½Âüp·~S ÚÑG‡mŸ×esè¶o£mµ5lêƠ³zđS‹·Ùờf×¾ăwü™F`g¬̃xj6$¤.蛥]øÂäïe­L;ưṚaåe]è¢&Ç`ÀÉèEă_6µ!¿GÆU] cî†ÿ„cdR|ưØ%bº|ÍáùJNff’ê§™³ƒT¯ƒ0aWŸrHÚu’à¤YI‡@–jIJh¶Û²0;\ÛÈ)Ül5?œ8#ü`ykÜY?‰+Ó¨ƯgvȯMJY¢NÚcY¥ƒåkưöR¨apG’ÅĂLSo•X"¦ºrâ8fOΗGd¥§¦hÍ;LSuú ç-©IÆ‚OƠ4 '¦ Ô`ºi6Ê-ÏR9ªÛrƯJΤÚoƠ–œd¥FŒ47!gYz2wxhYTaC½;ˆ%lüÆ»ELĐ,mHlG-¤k¡Md›okÓœF–¹M;¸¾Ă‚܇d AWˆú(Íf´ƠƠÛ—ĂƠ~±“ö”Ëûç­8¢Y Æ´0¨´ S±Æ–Éqâ¹²kË¡EËàØJ6›!/ ™^Fâô‡0ɬT2j I.ëÛAxĐy¾ø¥¼íÍE͆¢•kiáÆ…·¤Û™v₫2\̃+úÈ©@æ!Z%ưÑWC› º:µ¶ Â$I\úis̀7Í1 Ä€ql€ĐÖ0eï.Æw'‰7múëlE*?dlHâ+ʶw„‰ÊÔK¹POª¤mÏZäâJjS¹́—XW Ê÷ …„‘=áà­ØS2Á\wJ ṭÛDEă#ơˆ%Ô{¡÷/ ƠrÙ”“$ÔÆó|‹¿cs ¢TÓnsVF&̃·»RÛ¸Ñ¸ơzÂÙD„€=)­ÛĐ-CÜ´Øca¢._dà8N0́A#íÖÑ€M…ă˜+ÖT7M³mê!U;ű†è—JŸY;¦OÛ¿Ă¼I"o’¦Tù~ê}¢üjàèÉ}Ưª­´ßj—̃hÓw¢µùÄerÖ%®-ÆÊ^Ur‘l;@°%:Ûq5Î]˜Uk rL®Ü‘¨•;E›"^¯R7®ÔƠ„nrăa"<|Œ"@”̀ÙåĐijö× –®¸¡˜‹xTLY€HüŸ8qͨÉÛÆ¡‚‰i(‚T“ Á»é\x'&'%â|ªă„l“í̉‰…Ù’15Úd -Ö`ns¿Dmv>Ø,”䉡8< ÷Id'߀6“ä´±y¡u¿ đådyÆñl†̀½¿8®~ƯäC #Í^®6×̣»FzΙËhÊ¥7Án¦E FÅ9`v,¸¾·ÑtmÄ^Ơ2›}AêÇgö¥'°KCÚ@…HĂ“ƠcÉk?´5Ư,Ó˜èéè%À¡±®‘ç•Ê­áSÛœ$¹¨Ă|SEạ̈ăX…µÜôH†B)f35®•ƒ™¦Ö™̉xÈ^ĂY4®[·ÏE ¹9ÖU©UÁWƠGMŨ+rtpiS8:¡ö̉ êi£ôª ¬f&Z·ë£WëL{êLäy&×'–\_u¤xƠG"¯¿Â‡üFzúF´>ô‡V§EvîÓ Ư„¢°Ë)¹jö”ECHÄØI2cƯV9…´‰¸ƒ;œ+‹†}ß)Â2EƯăR9/X™¦úøÍ‹¢Ü£„*tI‹—WùS/7j´»ÜtN¶ạ̈*̃¶ú_yÚmâ%âmLđ¸#~bykÛ®6–5ªR åN=Í;¯6±ï¾©0kNSĂ8p¢4¨‡‡¦ØéÈ„evR©K‹}Û5VycÂJ å"Y 9(đׯ&næZ‘jăDîÍz´`5iEf½º ư*Bø b0n´FªUy§“f¬4%hGÿ!€¤bßÈezÓlW¥’r›/á^Ryé–Ö‚sz‰ä‚q‡ HÖxFîBr"A›0!fb.ăß4¹cÍÍÆ#ß6G†Ù“ñO”.󌜒¥Ô»Û‹_ooäÑóö‰~cï₫£ÀŸÎ}4ú®¯ïêâúñQ|*<<2úưăơ}?]|‘$̃Íï‹›û…’ß<~¸]LÚÁâægĐD‘÷#-¡bx¸»ưéúÇ»Áß]ó¦>]ÉôÍï´̣O7 ™₫ôëͽ̀|¤ƒ íí“~ü´ ×|ṂĐ…bïö^¿|Ô-Ñ£ù?ư7ƒ endstream endobj 1475 0 obj << /Length 2820 /Filter /FlateDecode >> stream xÚµY[oêH~?¿"'#%¾p;óDÀI¼C€±!Ùhgh‚µÆF¶ 'ÿ~êÖÆŸƯY­V‘âêêêêªêª¯ËƺjĂŸuƠ³¯z}Ḉ;½«Ơî[›¸ùûÁĂ7Kän@đ¦&y·øv{ßé\YmsĐXW‹M]Ơb}ơc¸ß·ń¾¡̉uü£uă81üÎχé ×xP©Ê£„¹óĂ[¯˜Ä+• Xƒ^ÛèÙ­.₫öÍ[TúÙq¿h½–₫. ³ ~tÍvÇe'üéÔî‹G‰Ñl₫ø >Î&c¯eAÈăát|; ˜Á"!ç­¾k ƒVß1¾'²ó ñ™á¿ǵ]l$³7è9xqc9¦Ơ±Ø¬‡`øR}ÛøĂrÜ!êÍ~ø 3_üÅăl¹`îK˲lØ;N¯̀Ư³Üp*Œßüéøy/V#ư÷yà…¡7æ!øU·E"ô4Ÿø­îô ^£Ér Q“ñYÄt&ÄẠ̈¤‹™È±×¨€ƠñM·ÄtZ§‹Æ7DäÉ£pA£<¼ó'>úkwÛx(LÜû‹)8$o "ø°ÎÏi´œ ez¾ æ³Đ3yDÖ"á]×dOà‡¿µnÜ6X̣s1“gëÆ2P~_ÙL’D3‘˜{÷4œDÖóZW'çÎø²ĂI½Î–bÙ1_ø‚êzZfèô™±wï₫³wÍcP)á Ăå“w¦Ñ‚R ̀j>³ádÂƠ>ơFp*öWf…pxøÏ₫H² ˜7§³ơS¡ŒŒfA€vͦ&í¨aZ.lÖ5mqÈÖML™Ä»¸ŒÊ8KYG¶a“8z‹¡“¸Ä8|b"°¶¯Êü)ºÛ‡¤ÆgÏđ!˜µœN(Áx¿/!=Æq¨½đ¹„ñ đ¼© '"ÎÁ oäW X.à3áµ€)Ñ0„ˆ(è´¿XẦ!`ˆÜ?®ÁpÄ=?åpe(_;S?„|Á-Û`ÑBĂѤÀởî´kA‚tœ#HGNé'˜³É, ëÀe‹“”H$æRƒÔÙ,8ßpwáö¡´¦Á´'ŒÀcÿÑ2` óI7<ÑŒ*̉á2ä ü©^N• OÊ’úºÅ£Œ›Æ0 ¾˜Ü¶%X́^/tyù“eà‰À=ÏH¸­Ëp[<ÀKÈư“'0ANS”¤j´É¸“ÖÎÏ¢b±¤˜̣1…p ,G̀a@`«µ]u/ë̀ƯWYÁUjÁ¡°Z°lLơé‡X¡ă†ó£ÔuäC̀c€=w˜«r_®‹ èPvôj̉óâ¼Ơœ÷S”-U¾ÏŨ‡j…̀‚¹V‡ŸQºæi¼/~₫ ÀîuŒr‹íi¯k¬ăb•DñNå<‘m˜D¢<Øü÷É3´ &µË¨¾4ÁË(Đèˈf÷y†J>âµZ‹¢7| }àœbÉU”¦YÉ2,"¶¾Ç,&û%µè+hÁ¿W¢̃±5·{°ú¶å@Àx­VY¾Ów–`g&äVŹ*ßtÅô\}ÄêX-Xe‡¼,˜.¶Q’ˆ3û}̣ÉÜ]<Đê£̃$×v˜7Y!£U’ 44”¨æØưˆwQ©pï>ø‘Êó­È’C©ØX>6‰SÎt.(I¶±?b!ù¬âê|AE,WYrñø—[¦8y€˜çÙ{í0Pƒ®qHU ¸û³œ‚™,çgT‡Ư^ïééîW3]:ÇƯ>Jcˆ«7YeûºbRàh“]m2bÙ́ ½©lá•¥¨˜nïûö•åÛµñu ë· ÿ¦mËû–‡-°™IÏ4!“C=èØÇn/Ô‘r,s0H=f-ÇÂ\AÑ2“µœ[¤q«đÅ’ÈÖÀ50OÏ…_‘ 9Ê£©]âwÁ®œ¿9âi LËîŸ0Qäă˜x°VX§*đ#âGJ±¯rÁq:'(:S §OrqÉ3d=<ßø­›íèđxÏ€¬Ư3|Eü–ˆÀ‚ăt*}Ở=½Ÿ_7e'ɸö@oúqÈÖ „!•â3Zá̀6VµhrĂI¸NÛ gM|ư«&‹öM®ËÙ¦d„ ̣¹ă6æmXHöÊ9©­Èy™Ço„d$œÀWXd•Qú®–₫­)$Z@‡Ь4tM§«û-¼O1¼–c¬éé‚ xî˜_–‘6'8₫ ¹É’$„›vE@EÀzø^Rˆ|v±N̉ÊÄ(@¯Ṭt,âE´átI½´Á„]]¹£•Ặ2ÊE#äZCj¨“&½<ä+ Ü)®Î:l»¬tÖWN,Eó) àºT‰©~¬’C!7ü)ç›°̣W©<][d]O[W·¨Øf‡D¤¶ë¨~Ç’²ÉƯDÉs²¿ÑhLÍă÷-™ó %qªÎlrƒ¿e±îcD©ê¸U¹:Ûä$)”̀¥ÅÙd‡t-8Üí]ơÍA·ë"vÙ}³ONt{â|3ëÂ}ñ „æl…ü‚àu æ¤ÑNæÈ)"øñ–ÇjĂ$t1Ầ„s¤‹æä¹ÎT!&;VÍd zÛt»̣B•í)®²ßYFØø6øÚídÛ°~ª(¿´XÊ-Üc_÷¾76À¿mKEtƠ¢!~“‘ )Dª# Ôw~"®#A0„Ä9 Ơƒ±¼ÍÄ̃]¶7•§nĂ!ǧÀy«üâ°J¾îêVsôY–ưYú³,̉ƠgY²G{ŒÅVÉI¿ừ¬jŸû*¡DCø˜¡Ô _3CA¿¤=øP9—8œŸx öÉr,L¬ạ̀̀*IºçI&Ê ÷§AT^Qú‘§S•8Åé…ñÛl_•Öe!ăDăMdà†zOAmSÄ«ïÀ(C/H¼È·à_µjHôƒ́£>Ô¥YñnŸÄÚè#áiùYÅÿkDáK,}…­¾ÀÖ¢úK|Ơ$Ó$Ó†AơÑ•ÆƠGW ÑØTCÂ6¸ư×̉wsª%€kxSŒ“¢ñx_u¥ê‹,̉h˜«•h\£QXkæ†I‘ÉŽ–~!N›³|W}w€®D¾?lu wj{|Q¤[>ZIïđ‰Ư÷ü *¿!­°÷Ă/D¬Ê<Ăö“6«ơûH~|“¶ayƯØ̉›+‰ /f'đBî:“~çđ̣ˆSú½Î%ăÎ$Z f;n½U'™’WÀ́%ó"~@å2[µ+.¶§ơ]ÉjäCĂ“2/=Ôz6¾,Ç©₫£Ï£f驇ƒ°°k¸ÿJ_¤cóµ)pzf·Ó×}Åÿ¹!Áø¿‹p endstream endobj 1482 0 obj << /Length 1321 /Filter /FlateDecode >> stream xÚ•VmoÛ8 ₫̃_́K v,¿{ûÔ[±C±½‡âzÀ\[I„Ù–!+đ̣ïGă¼n‡±H‘/b3~l–³4 ½,Lgeså®ZÏhñ|Ŭœ ‚îḌnyµøÇ3æ{¹Ÿ³Ùr55µ¬f;·]7wƒ̀ám%~ÎƯ0 Ûô½ÿö‚‹È¹ç-WEMܧí{-JZ?ˆ’·=,O}' çÿ,ÿ¸ú¼ƒØ‹£đ7½ßKŸAÙ,ọ́$‰ó}/‰çÇXnD?Gu§Sr­†ˆR6Ụ̈¡7´º½ûóñáeùùá•èoôưëöùùöỤ̂ơ‘+©hQq]ˆÚÑ»Óê{?gÎFÖüµ‡Đ† ±vê×₫»RÜèåJ…â7DmE‹ÜZ²’¯‰ơ@̉WñJôZ‰÷­¶;B¹@lÛ[ %W€¤Ư‡î[ ÙöŸÎ‘°ÊëËÁ0`O3 ²îÅe‰ÇÆk“Q9›9dØ-u¤̃p-JL'Üd `ï‘ ïÖp25̀¢ØK³ «ä¦ßpÉ0đHr+|MvMtñ¸‹„¡²đÜ~ù›ö#ÔÙB>ÔƠH"â(Ma/:HÏN‰B[FW(Ư“\ …ñƯ ½$! ¡Çb›Pc%FpOp¢-F$m1zs7e™óˆöŒïVơ˜dQW€^ƒ¶l­\÷¤?¹ ØlÄn-u4‘ïÔ$ˆ¨Ä›ÏB®xK̀$RFy‚}îç.s^¾y‰Hä!ØÓ\­½Ă6c½Ûß­!0¢Hn±Ë PÑă…QA^É­&%Qóç‡CẠu…tBLï É¢î%­Ö\Óâ.¤xÓƠÆöQsĂeΛûbu$OÄ€Ræü°ôöKư†+0Áˆ'íQ}‰– ‰ oÏOœư1EK^»£­ç½X·ûCÎc!+eg”•¹̃̀±‘«øÙăm•u!À§ÈèBqarÖí̉3.·å%ïûB§<Êè/ó,röú Ú6ÑàV³ÛM-ˆ$ö_ =ó†–¦jQx,'# °ÙÊ€Úªw$=ª­d7–:¶-ˆéd{z°HzÎO‡WåË‚Yø^çàđ̣bØóü₫X`¦Ø1g:ÎöúîÄMä£îszŒ³Ñºû¸X Ăà­Û­'ƠzQS}÷‹S?#?‡±ùùïCv/}îƠQ›;5j¼¢‚x¥dâ´×‡,µ±eÉäƠÜñƠëL¶‚(\Q®ă¸F‘VjâÛljj„¦Ñ–RÙI¢ }Ú5ñ'µ Ôø @¶×Èq Z0̀1HÖó±0áÜRù+æwO­u°ùf²#³ O¿}WĐDËi»ïÊÔE„ÅăĐ%`»)¨–. å^˜ym kâ6¸‚&¸ÚÖ´kà /“](‹Z´?(Fq~Ư0°h`›wpß¾“p%!pa‡â#%¬¦ùgØV¦O ÈFœÔ¹4)°SI L’Ø;æhØÂ\ºêz‰RœM²,dlŒoS$ lÓÔ‚OE:rE"IœNi ƒôÎL`Ằ‹T¯³0ëˆq xÖÇ <Ïÿ£Ó́¥Ư‰ø…NsjôĐiđè_X'Il endstream endobj 1660 0 obj << /Length 6448 /Filter /FlateDecode >> stream xÚí]ßs·‘~×_ÁG©ê8™ß?îí́œ]NÅeŸ¬Ô=$y È•´rÉKûrư5vĐ˜vº§Ù»Ê9ÖTªbIÄô×óá#€nôÅEÿ+.º̣¢ë«¬¯º‹ë»Wùá_?^Œxûí«Â·»„†—¤åWï^ư¹(̣lȇââƯ‡‹¦¨³¶ªƒ½w7~ƯƠo₫úî¯₫ó]°Ô”MÖÔ•[a÷åEÑeeÑÔÛ½FÙf¹û›ƒưnw³ù‡<6¬³ªnK×đ2ÏếV]VµcÛ¯ÆvåEŸ m{0ç¹çroñ««§íơ›Ëª®^ÿééêăÆư±|ưĂÏoÊ₫ơæñçíæG̀ EVw¼ÈÁ¿¿¹,ºbüOư­X₫Ù¯æ¤7˾κº¹h;àj8tfÖÀ²|€ÿ+ÊC¯ÆÿB»¿œ?ô.íŒâÀeýÇUMEưàE…SÔX*]‘5đö.²¾a¿VIåúöñfóóözs¬]›7¿-E|z”¿ümÙ–Zƒ̀Æç/‰Å ‡.* ViÄÔd½Ú¢Í†Â«ûëû»»ûƯ8Â|ó¦o^?ï®÷ÛûƯÓ± Àç¼₫Å;7ûÀ3àGÚ9+âF°D̃fUUúå~÷—¼¨?>?n¾¾Ưo¯¯öÇZè¬k‡/Q ₫×Sf&üè@û¥iX1_4bA ÍĐ„˜áƯ›¾…ƠÇƯvwµ¿œª¬Ë«_‹"Rª*XÚ mx¹w›₫’8î¶d\=ôG¾Ô5Ḷeä‹Đm¾µŒœ˜< ÿÛp XßIđÏË®$ WêúØ—!k›AK‚o½€›dHh›¬́ŒËÄ#ÇC9¬Ư$­dÀ·–“ ~t1S€C˜èJ2a-7„)IÀ!LBvCXßdEÓăöđ¦^ÿăqûñ“  f&³ªÏú¾XWÊÆ•2̉m̉d€íÓ¶f…D|Ñ)Aʦ̀ÎC£ Ë>\ß̃?ÍÄde™uƯÿ‡̉º¶€œ$H@ú0j¼¸ëđùKbà¨ëR1ÈÉ|éRԾ밵Œœ˜œ‹®Íʼ·“àŸ_p%I8Ê) 嬵$øÖ2rb’!G9$×̀$øçeW‘„áè—8ÏáÇ…’l-"§&™)1o µXIÀç\‰AÆåáqv©€!©èµ$øÖ2rb’!¡̀aŔ$øçeWƒ+Ơñp^đH£%Á·^@M2$à̃JB$W‘„ t$„@ABNL. VB  ¹’€Œ+Äœ t$„@ADMÊ‚• $Gbˆqi“³‚(HÀ‰É…@ÁJAXßI®$ # lÎ]IBXß È.P€DiÛûí#Ht4ÏOŸfmEVYÿâá7åy ́S̃d€Ỵ̈(ÏåÀNyÄÍ”'!'&¦<+ aÊ“\I@¸Ñç' aÊ‘c“ S•„0åI®$ \Zç' aÊ““ S•„0åI®$ \fç' aÊ‘c“̣”gå§<É‘‚›ôq~̉1¦< 81¹0åY)SäJ²”Ó‘¦<ÙMyPÉPD̃v÷đ<“«Ë¬‡?ư“bGƒĈ¹©yq—û§/Ăă3C`vöp˜ NhÆ=’[ólïF<̃‰€‹wqh̉¼xëLjNçlï£ï5ÏÍö8ĩ:Œo<ßMøù’|¼ü “ñE3ßIȉɅùÎJB˜ï$Wn̉ÇÉIGB˜ïDäØäÂ|g%!̀w’+ ·ÿˆ““„0ßIȉɅùÎJB˜ï$Wn̉ÇÉIGB˜ïD䨤<ßY9ÀùNr$†àf|œœt „ùNNL.̀wV Â|'¹’€,́:)Ió€́æ;à¡k|RøĂăæêf¶̀¢îÎPf‘Æ™U‘µm\xqœéŸ¿$ằ„ù¯€´ißW‘/B°í[ËȉI&Ø®]©¶“àŸ_p%á2 ï«9˸±A†̀ Y‰'É“dœoøÄ“‚x’“ ‰'+ !ñ$ºƒŒ$đ‰' !ñ$!'&OVBâIr%áV˜%R‘0%äÔäBâÉH´]‰A¸œ ®u$„…¸„œ˜\Xˆ[I qÉ•„[~áªYGBXˆ‹È±É……¸•„°—\I@¸®u$„…¸„œ˜\Xˆ[I qÉ•d$-ÿR’â"rlR^ˆ[9À…¸äH ±”x̉1âpbra!n¥ ,Ä%W¥Ä“„°ƯB¼­³¢Å¯Ô®¯vs9'˜F›nự,ÅeØÛx»¤&¼¤hị̈ljP_4’¤ê°ôôŸGÂ)₫‘ñ£·››ÇÍnî„n8|9ùÅ(‚̀™!ØE¢îa¡®h$!;I@ñèàÏ0ùđËăv¿™dNú¨‚ óGh{”çƒ|̣vBŒ?9¢ ñØØàB€o|ưßK~D ѽêí1¸@#s ¡½ñƯCd/¸C,Åơª—a½\ê¯bzÉb)¢W½~èØØàB8o|ưÍ ~Äc›³±¼æơ§P‡M .̣¶×ŸâxÉb|ư†âU¯‚x66¸Â_?Dđ‚1ÄRü®zư¾K°‘Á…àƯøú!vüˆ!Æ µd#wƠë‡À]€ .„íÆ×Q»àG ±³«^?„́ldPØoñºàE0ªü¶™êƯC°. ÆBu㡰Jđ#†_¿bWĐª× èvöÜ™¼­}~à[Ơ±3ßnv›Ç«Û™ªC5ÊÑŸăüÙjh„›Ă6b€ Û°Í¡ĂNtÔ…ê$`Û*Xo5xöäÇÍ̀÷3îØeĐê?CGL€ƒ>#b€ q""؇º²䈸±A9̀13€qèI22Đr‘’ uDäĤ́˜IÀhGv%Yˆw”$`À#"'&åÇLÆ<¢+ ÈBÔ£#!„=rjR|¬$„ÈGv%Yˆ}”$`đ#"'&åđÇLÆ?¢+ È\¤$C 96)Af0 ]I@F.R’€ˆœ˜”C!3  ‰®$ # = )IÀpHFM‘™‰Ä\8́C%‰À‰I9,2S€q‘èJŸHƠ‘©²[¤ ‹Ô‡íîiµ9°ÔÚ—ë>¦°ª=éIµËe2ÀË…ö\Å @}ÑÈE@vri]\í?ïøø°}?ÔôYS®*ù|‡åcØƠ5àƠE;ßû¦¾hÔ% ;uÁ>h‡§£º́߃­̃­[c]ÆŸÿ_ÜÀÏ₫o\ơíÅ/‡–wp6për4·?½ú¯c¸¡Ê\~(‚䆯[%ưâ" äÖ.ÔÉ/TÚ‚P‰/¡ ÈN¨u•Á«k„ -«±ÚăD¡RH¦ä û~Ơé‹uꩵët2Àë”ö_ÁÖ§Q_4:N+8k½¯5:­ÜYêƯtJ!÷Û»ÍưÜÉAA/ªj•ª¤JO¤]•“^•´·U_4ª*áÛ¤aè4ª„ƒVÆØåDQRD®‚ Ê‘Êz•ä‹uê¹µët2Àë”v  Sâ‹F§²ÓiQL;†?~÷ƠlƠ]3¬’9ë°7’nWSxéׂœ'G4Ragw ~—{àïT[ĐỤ̂z&†A-_/ØùüC[ÙÂq§ mÄ«Fl3Ê‘½‡ú¢Đ£„ C[ [¤x5ª×X<ĂưśÙ• \Í ÷ĐÙgà®ë-úđêæfæÆ»b€ ˵¨Â¸¡Ô4̣lWlx,éÊ‚½F‘8¢‘+ëÔZĂ.AY)ä ë¢=ƒ\)"“ÁöơnŸ*XÏ´]±“^²´;Í_4¢j+w«z«P-4́Ëá ª¥ˆó9"m̃®£́©¢ơDÛE;àEK{S-ñE#ZÙ‰¶¬áZêA!ZhXÖåDK¹Ø¼̀Úz ´¬WJ"Åv¹Nx¹̉~äJ|ÑÈU@vru±P‹!Uùờ€gëæÍgÜÄ>°«k2À«‹v4Ÿ¢¾hÔ% ;uåă9Ï£º\aÄíív÷Ñ}‰[¾¾ÚƯŒŸä̃̃_Ư¸=¾Ă.Â-ª/âÎ_f„™k¹‰¶–;êvĂº¢Q‚ J(†2+ñrW"óøisû0{÷q^¬ûæåƠØĂȶYFÄ+£¨KÙO¨+ IÀNF}‘E"rç”₫²Ư}¸Ÿ¹\£Í†µÚêÅCĐH±]9ø8¯›©yƠ'4‰ g3ÇỖ ƒ¯ơú£œ9ö5;äf%Xÿ×Íçă¥¢j7›¡̃&¼â|y£®hT—Ïë.‡³Jr_\ó½JwwWOûowlÉ|$W»<ßÉéW×Đ_}~Bzlz][û&̀ÇI¨âˆB^,̀ƒpTMYø̀Æ÷÷pÍJÿúæư\ÍqåÎÊYƠrZ¶Ê³m–Đô<+!Ú¡¼„ˆ# ° ¡¶‡r Ÿm¸»?ÜÔsó¦x=¯¢êPÛ´Êè$yÆÍ2geD;µè9G2J`ăy®Ê;÷©h ¡z;ø̣‡ùyÎ}{5˜àú®Æ«.!°“Û1;0óƠ¸±jovk `u€TtÛA5 ¡ Ÿ¿$¤•‚̀/¢WÉŸbQWxmak¸Ê{W»Ö¶PÂÖø¡ñ‡]¢±fEÓÀÑXë¼' J¡[=½víLxíĐ>äµC\Ñh'˜ÜÎ^ƒ÷£40ye?\Á‰·›¹C+Üç[«¤N ûªjàÆÓz'o_₫>I «.aG ²#¾hd' û! >̀ÍrL°₫èRT¼¨àë†un]YaO#áf9¬œ¢^=¾´B}QÈIBF9Á¨yăÓĂñrå ôË5,»₫„-eW/wgÄüW]ƠªÜS•뉶+w2À+—ö&?R_4ÊQ¹đ1l>´ åBC8Ρ\ y½œs wºÍÀ=ÏL|Û<àL;µdÔ€dp ñĨ) «sÈ—̃\A€3[6¹®COw=ÏvÙNxÙ̉ÎdK|ÑÈV@FÙ6áI¢l¡aU”ç.…t½ÙÎÔ¨»#«óuÑđ‚áƠÓj×éd€×)í;A§ÄNdÔi]@ÚR!ShW•g_ ¢;§efxugî­UégZŒtÛƠçÅKzôøBÑ ƯÉtcØÙ̀RǸeóV“̣f Ê}En ‹uÓÄàn¬„CŸÚ—Ïøü%1pÔ¡)³V»ïŒƯ¹ÿľK±µŒœ˜œ?˪.;(Øní$øç\‰AÆĂ‰†ä\倒ßZFNL2$ÀAÁùPÙIđÏË®$ # ÇJh`Vp×èHđ­eäÄ$C|Ô7ÔvÆÇ‰ ˜3køH±p7èđ­eàÄ$ĂÔ·t}g§À?/»’€0gÖP₫•î×V‘à[ËȉI†„*€ªtàŸ_p%aÎ8t¼÷ơ %Á·–‘“ó$49|·ƯfđyÑ•„9æ°ÊÛ¡U’€­eäÄ$C‚_‹˜IÀớJ 2’Đs+% ¸ä‘ưj½îÜ-Kư´˜y¿Ư¹Í÷·cùȵûËßf6ca4o×|ŪÙo—"Ñæ=Yb€Ư“z³cUD\ѨHFµîl²$>́èÏ®­9Ú£0́jO¹]O“^O´_y=W4z€QOË)ù›̃n₫₫¼}ÜÜmÓ₫i¶2dÖúYEekWÍd€W í=6óD]ѨFFƠÀ-v¡.äqótû³S̀æÓưÓ~öS’²Zsîú¼̉k_Mø…íĂ‚ƯÖ¤¾hÄ“ Ï&àø Ăæư“&ùó´yÜÎ]…Sº¤Çn<ëæơ1ÜƯÛEH °"Ä6c₫‘÷¨/ JÈ~sM7XëûÓ¨®C]ä_̣&ÿưæáqs Å‘WûÍ üC1{Û­ûÓoXxœ,@.£+Öó&O,ÙAºíb đb¢}*ŒºÄ˜dS•o$bz8dUg§́j€SË×ôØK÷±C/{²íR đR¢=ZU¬”ˆ/) È(%whßÎK ¾—£7£¬q¨f̣ôÚÅ3àÅCû°ªYñ_4âQ<đŸOÓ}½tʺ₫¹gÉ%/_ơṔÇ% «/í|₫’8¦#aN®àZJ8W„ºÂ÷ƒo,ăÆç×Wp0ñaqbfÀ?¿àI 22p”á¨óJï:%ØZDNM2Ûï¾^ÈJB(J]I@˜•6V)IÀ¢$91)%™IÀ¢$Ù•d¡(II%‰È‰I¹(ÉL%‰®$ EIJ°(IDNLEIf|Q’́H±P”¤d‹’DàĤ\”d¦‹’DW…¢$% X”$"'&å¢$3 X”$»ƒ,%)IÀ¢$91)%YI˜’0‚+)ÈXS±I SFBNL.$a¬$„ơªèJ ²P”¤$!¬W¥åɸ^-a•̉â [°^ưư»·³_Yëg'§&`j³ˆVHQV́Æ ơE!$ …䯴ỡ¿uG°½ûiöˆf­L:Ó÷!t»¢Âó¼ H¿ zÑȉ‡E5upMåwo¶ó—­·AÆMƒ|WØE6àUFû»b˨/ È(4¸¸­ËHhÉGtPj–kØWÍIßĐÁ̃a# W»”kÁÔ©®gÚ®Üɯ\Ú»r£¾h”+ £ráà¶©Ê…†}ƯA¹‘¿̃¥Zk!N®'Ú.ÜÉ/\Ú›‚p‰/á È(\ȵm£.4́›₫ Â¥ˆÂ/åzr¾uK)¶Kv2ÀK–ö£ Yâ‹F²2JÖ¼Đµ ÉBCW vºd)âA²ÿ±»y;;æÂ ŸĂq—5'=O•]z“^z´?é_4̉Qz ,8Ö$₫øƯü CƯùœ ó}`WØd€Wíh~Ëú¢Q˜€Œ Ë¡”yÀ:{_ê0w*,́¨Áím«Đ>CQö]a“^a´£ >—C|Ñ(L@ö +†*ø¼ÀÆ#å̉ƒjàüëª94̣SªÉë&‚|ơ|óx5·è«`c6_} z>ÍúœgåI»¬l8uGâ`Q›p dW–qBË¡hÎ!Nù̃}Xđưæiû¿›Ù­—¢\Óåú¹¹µ+u2ÀK•v  Uâ‹F¬2ªµƒ̉ª̉¨Ze{µRL₫0Ûf­~<1íƒDÛ¥;à¥K{S.ñE#]¥Û¹±u­‘.´ªî̉¥˜pcFóüôi^¼Ưª̃SƠë¹¶«w2À«—vhÙ²ê%¾hÔ+ £zø/9Ơ -‡z8‡z)&\¬°Ư– 3n °êטºDí đÂ¥})—ø¢®€ŒÂ­«C1°B¸Đr8Ë‚B²ûDƯ°æ¬Nr=ÑvåNxå̉̃ä?颾h”+ £r+а$+Zc˜wªt#̀ưưĂûí~₫B·¢^GÜDeW»R'¼Riç c,ñE£T•Zº¢æA£Th9ôå9”J1÷Û»Íưó܇°ƒZ¯ŸÎ¾@¨V»P'¼Pißñ‡P_4BQ¨PùÜçªLlán|®Ï!TÉm¾ĂëQ'/<ÓvíNxí̉î–Ä—#í₫K±Ơ7 endstream endobj 1434 0 obj << /Type /ObjStm /N 100 /First 993 /Length 2226 /Filter /FlateDecode >> stream xÚ½Z]·|¿_ÁGçÁ\~u“ q À°d ‰ E^KB.·ÂƯ ²₫}ª¹S#9·7̉ỪéA§̃N›ƯƠlÎlŒ½ºàbÉÑ•hÿ«‹R”æ’&ûB\f”€;i¸\đ¯;­Å¥âj,ö}wUÊFf×ʸE\/ƠŒäz‚‘€5Úw¸»Y‚›`a0ÛŸbƒsÖq0(bƒ‹¬n–OA «ÁTíf)æ (Ư¦Q{œ Ăư\Âgph…ƠŒ̉|LÙfU“KY£ªK̀£a '[Ēǯ6c«Ư¥ ¥¬ă`Ă…œ€£X x™æl“,øXz4@.! d$Ù@’ ”î$W»J^öèDƒ±aI¤¦´l(XDéb(]†qêKdVuÆJöæ´ó²#Âb1—œ*rV´¨³’Ó&X+ Ùi×nß!‚y$¨)Œ;ÔƠ«YƠƠ’³YÍre #kÔ<—\­6‰ÑƠÖ  ÑB àˆHªh+‰•p-Y´$kY 9*RáU][g›x«a w×Z ₫´>r+÷Œ–nÆ£…ơñ8Nr¥F+wPé>b‚hY|C÷^B÷v†Ơ4>o¢/˜8¯èfE“OöL'Û‘Í>ßw:o_¿9?\̃¾₫°{ÿúĂ·˜À·ç¯̃û××ÿ=¿ă í„€5 Xë$-œ,e|~èÉ oñ~₫i"oÑÙ©†I­GÙ¬Jê&̀e¥Qi0ßó½‘F¢‘iDîDîDîDî²ê'#̉H42BCh(J£Ñ r$r$r$r$r$r$r$r$r$r$r"r"r"r"r"r"r"r"r"r"r&r&r&r&r&r&r&r&r&r&r!r!r!r!r!r!r!r!r!r!²Yˆ,D" ‘…ÈBd!²Yˆ¬DV"+‘•ÈJd%²Y‰¬DV"W"W"W"W"W"W"W"W"sgî ̉ˆÜˆÜˆÜˆÜˆL 5(Ô PƒB 5(Ô PƒB 5(Ô PƒB 5(Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨Ô RƒJ *5¨“O7¿Û́ní/ZñÂUlà Ư¦Ö}†µb†qó&ù—ĂÓƒĂ.÷MºuK₫BÊàí  µ0V’gÊœ}Íù$eŒk9'7£úl˜9Sö¡èIκ‘›¡xÓåL‰^Uë$¥ÈJÎŒv Ú…¢}€,S)Ï1‡è{§£ÙVrJđöÀgæD·eo–8KYÉ©hYúGÊZF&-RnΙ“á\àƯˆ³e_PđȉZîóhhorêÊ¥E±ô;'ÚoÏæ+ê@µ×jXâÓ̉ + «ú„=€„M¼=ú] \Y"Vo.H˜đ>aœn'́+ĂÄẃ$Œâcl „im…MƠ®Ï„©ûFçvÂ\6ª;áTvûFEg"œjÎí„¶©8ßTpnçÓ°‘ô'B*ÿv´Q’âDßË'Y]¹ÇÓ»rêå)9™¨ œ«3‡©JNæêçêíÙJN¦ëgƯ&aIÉŒ] ”­r–œLÚ%ε[dAơÆ)GqpéÇp¢±Ă;ëíMR2 ”«+úMR2 ”«…Âh’“Ñ\à\AŒ&zf<:ûMồu<~¸h’’Ñ\ Ü*¤d4(7‹&9ÍN‰Û´’xÆ7aϽdHO¯´›œ9ÙN.qæmJrÎåçF=å̀Éízs«¶ræäv½À¹Ug9s²",p–°MI˜9Y8×je* 3%KÂåV-æ̀É’°Ä¹Q—‰Ÿz{ÚÈ´Åg±Ræ´%ç”¶Kœ«¥Â´%ç”¶‹œ‰fÎ)m—8Ë6Ç¢™rJÛ%ÊƠJaÚ’sJÛEΕ]f̀Ñ+^ à5=₫ØXñÄfKđđ§=È#Kü,ÁÛ›¦™o3ëg(óF6)§ {‰3mµa“sÚ°9·Ú°'NnØ‹œ[mØädå[à\½y²̣‘“•osuE`å#'+ßçê’ÀÊGNV¾%ÎmÎ×3%+ßåf69Yù–8ḉ> stream xÚµO‹ç¸†ïư)tL.jƠUI0,lä’SvoK.Iæ°fÂ29äÛç--ÿmb †µÛÖ£’J¯J%QUI%QUMD…X( –D= Ô8 -UoQèÉ:>¨µ¤Fñy¥Ô9>¯x±(¿¡$¨±Æë¯²oï×D̉z”âåR£†ñV ^vÙá•V£†?t‹f%.M¢Ä‰©w0L¢±ñ…ibƯÚm0 n 7Kl[ËQûÖtk‰ÛÖvëIÊÖx/Ihk½SÖøÂ9‰TĂ%úa{¦Ij‹½&ñmqôR£¨Ù=I—¨ -u«¹'%‹[IÊ-ji”TzÔ‚_µRồB‡M“ºÆ·­&mщµỶï}x--¬l tL”zªBñ¬—T•ă½N ½¾=ă„q0º`ô<êƒùø>F¡×deTeÄÛŒe«¥%“­®è0ÂÛÉ¢‘(Q2ǯ(q²Fè+C—Xg¼ÀaPªÉ …’%gßyrtV”ẒZ¶{̣­ ƒâ­7˜åmsâäƯ ’ÔJ´̃HSăm 4 2øpS±(yjá—(µỒ¶Zzj>‡.ˆZ`t/áCÆœ:Iƒî¬Q kê>M뺵®̉£Q̣Ô=|ȸ¥̃¶ÖsO½Çàz7ª Ï,äÛÓ˜!Ü¢»Db²”¨=§Ôp$‹P¶†×hfŒHiÁ[¥‡˜àO(‡mĆqÑw$Ÿ…3“j}ûôéíưçÿüëszÿñË—¯ß̃̃ú÷ß¾m¿ÿù×/ÿ|{ÿĂ×ß₫ñù·ôK”¿¾½ÿåóß¿¥_¸•L ™bµĂ%ÔK–NxïÇôéSzÿ)½ÿéëÏ_ÓûÓïˆ~Ÿ~øá ÿ₫_¦f‡ i•³j0kÏ­è‡L†$¡¢J™C;´ä“R{f̣%f’Z®páÁ¬5ûÿ@ÊC¤Qèè@b£‡ï˜\2Ư2tûd¶•ơùÔÎN¹`­9˜\Jf§[¦<´“KÍSy0©f¢vϬ™\r¨Ă`rÏƯê-SŸÚ)5Çj1˜ª¹ß2+?dÖ’UådB ¬ö{æCI`«™_ºÖ5×b·H{,|»Ø̀Cøî˜2Gl¥[ƪs2 gùÙçŸ4Éîv–tøZáÈ]øn™6Gøs¾;æ,á;˜‡đƯ1g ß`îÂwËœ$|ƒ¹ ßSiđ æ.|·̀:Gøs¾[f›"|¹ ß̣±¾ïÂ7˜»Ư2}Ó%¶ƒ‰ç]hÍT9˜Æ9öOƒ¹É/¦wfå\èŒà®Ô[]ËÄB̉ÁÄB&Wr;ˇ¡û‹™̉0K×!F Ô@rË̀²–IèÙ"ÏU.:v’Ó"•ƒ7˜́ˆº}̀ÔIL„í4“1o\ ë$¤Ö½“YÑÓÚ×2Eśơ3¶ŸÆk™¬¹è©{Œyƒ„ÍZ&IV{OꙨE3å{`Ë…À~a–@÷Bæ ©CÎơÔ ê-̃±ô@6ÊçԤ湳/Âeû«Ê¹_Ø8i5i‘₫9'&6,E–DîĐcÛuÎʈßu-ÑZüáADèƠê…Ü=Œ̣*G˜ƒ¤o„?ÏʈniŒ_2=*ôû‰„Ơˆü– kR³HBgẠw !Dèä% ¯ƒYĂAqd0˜±£₫ØÈ>‰ˆđ!× âVÓZ+# €«&> stream xÚíœmo·ÇßëSÜK È1Ëg²ï') @ËI4/dƯÅ8D©¤Äé·ïp—¼ƯÛáñx2PÔD€Ø–fç?7ó;>sùªƒÿøÊ•u’9iW7w]ÿÓÇ÷«á/ßÿí‚G»5®‘åWŸ­ơẁw¯®~Á®®6«Ÿ^}s¿Ù₫yùóƠ·+¥3R£₫V‡Ÿ^|uµ÷®…fZÉÂP’ơAü₫|H«”ຠJˆŒù¬grt@S‰‹–áÅRBfF9°iÂĂ¢gkŸN|€€)¥¼&䀄iRWNî-áX `+/îuj#˜³qÈö6»×éb€¿o–6;aDåMƒîă­h˜>iw‰£ÄhÓWQ“}#¥„ÄŒrhÖ Ăë̉H/̉5[ó ª7g¬xzÎWS=b“{æT[¨íƒSëaаâ:f`E±”ÀQ°ÂB¥ÑcV04ĂBÿ™¸bÅÍöîa¡Ë—Œ·é́ÉGRfë)Đ”ậe(E±”PQ”ÂlÄ)Q@)tÜÔ/@)V$vă=ëÚªK}›3\Oë耦—Qk’VK ­å@kg˜Đ¾€V0TZ¾­X‘̃+=mC¾`á&å³ÍÑÍ&.Z†MK ›e`SÁ,ÊX{œÍ`è^ »ŸRûñp:¶NOïđSn«1EHL'¤1ű`S˜Â±ÎÇƯÿ·_N7âaöC2ñ&ïÿ×8Q<ĬƠó0: yÀ¥ÑÉ¥„‡ŒràÁ*¦¹˜ñđ]Xr~x\Ú}‡E·±Ùé-J̀s=A£ \̀L‹‚b)!(£,;Çǿ&t~Ăæê"@Vm[u®ÊLdHÂÁåv¥á«Ó¹̉$Dë¼̣̀%‘ -¹ªÏÁđø‘@&Äû4t)v‚ 3­óÂ3—Dàb¤u¶>ñù|(3âÊq8Z,J“­óÊ3—Dœé_¿[„øü‘P¦"ÄUê₫\µ̣¥IˆÖyå™Ëå$hxÙ%¤«: éùl(s‘áLÖá¼VJŒ7…IHÖyå™K" iDZ›„ư°7ÊTdH‚#G3eIØf2Êi4pøx½ß|¿¸>©á}hâSߢ ‰i¬‡dt@C‚k%- ¥’Œr‚$¼œă‹ïv÷azôîö!¾t₫÷ë2µkoE3¦˜áúÓè€1á2̉m ¥ŸŒpÄ't:Jy„Ïíî~aÖ$‡+n —£­\Ü [E)±§÷ÏĂókä`¡Ôľ‡RĐ=g…g.óƯsuRË›e*räÜxảW'§œ¾:pnÈ;¾:Ë{‡̃|ÓNŸ¹l•’]Ư#d#<©(ÙăPJHÊ'’đM¤åQ^¸ƠN˜~¬ö:ÔØe.%ÍE†e4Üu¨ÿ“̣„Ă endstream endobj 1716 0 obj << /Length1 1558 /Length2 7763 /Length3 0 /Length 8801 /Filter /FlateDecode >> stream xÚ·T”]6,Ư!"CIÇ€ Ưt7 Ă 1”€„HH7‚4H̉RJ H ’J‰„t‡|£>ñ¾ïÿ¯ơ}kÖ¹¯kÇ9{ŸkŸu‹!¿‚̉ªtCñ„$JÚ@!€ˆ€0!‡…€₫Er˜@=½àH7ÉÿpP̣„‚QhNŒBûi#ỮPIÅ$…„ÂBB;"=%Ê`¸@[ ‰tƒzr(!Ưư=áN(ô2?¸ Ü „„ßïp€‚+Ô»´Á('¨+zE0DBàP”ÿ¥à’vB¡Ü%}}}À®^HOGYn>€/å0€zA=} €_tÀ®Đ?• rŒœà^xC$ å ö„Đºy¡#¼Ư ôâC -€®;Ôí³Ö>À_½€ÿ¤û+úW"¸Ûï`0‚tu»ùĂƯ08 ĐUƠ@ù¡ø`7‡_`„öĂ`{´Ă ú0ºÀ¿Êó‚xÂƯQ^^pį¥AwYÅÍA éê uCy₫ÚŸ2Ü A·Ư_đÏɺ¸!}Ư₫0¸›́W̃î‚Ænpo¨†̣_.hđ_Έ ‰€¨êqü•̃ÈßúÛø›FWàtÀĐE@ƒà0(ú‡0À ́ <½¡AÿiøoDàÀêw#ü7;†Â₫`ôá{Âư–BhíB¿>ÿ̉£ó /ç—ÉÑê dï̀ó…d{"L u÷8™ëđp”©ÁRªÙÊlŸßŸ_³1&›a8đ¶wƯíÜ̃1îà$;WU5<$n¼G6iả¥\3́Ü¢mc¼̣2¾/Î5̀sºO;àu,s2¯ùf:Y£¡§ ü(ză₫Ä7°8›œPY[Ñ[lVa²]{C)Åûûzùçơ9ư·c ønú&ïúB?Zó#v•gºd"Ÿo¦ïûaƒ¶|­¤÷ÔKuµ{Å‚y½wÄF\ïS}Lơ[#)×,Ÿơ®x×?ä́jh+/‰!:ÜÈưLó&QåH°ˆ#Ï{tªÑ%#²câ²́PÓê5nnO³‚vÆX1‚Ç@kÔ–`FÑÔ™̣~¶ØK½ênƯ‚û?‹E½Ëñ''óÊøV¼q[óaÀ́<̀|™ö’2z+**äËJ{QŸg¡Ơég1/æïj[Ÿdiâ2¹c'Øa*ùkÁü§iĂFƒo¨Ÿv¥7AÉƯè%µđ‘lgSă>lØùQwOô˜âùq¨÷™“IK6³$3?ă ÿp*%j±̉=¹åÊ·8æd›xrÈ,qô:“ái—ç‘)¬Ît¾zœË;:!©ÀÚ.Ó¶`uó1w®Ï/1ÏÛÉă’Ô f(e­µ…hoªPÂ|ƒü¸³êi÷,s—Ö±Øß墯ܓù‘-êö܇(ÜŸv)2HÙ Pb ª̉lMƯÀY§0#‹—£¿|ô!×»Ïs7₫@U>3ï‹éÓ=ïå5‰j́¦äQîähzÅ…LÙnU`àk|’&úÎwÑzî¶œÊx»‚^5$ –4aäÈA»ÎÍ/r/µÊn¸śºUî­ xH9Q‚o?'·Q¼NàW]mzÛ„á|Vw1Å~(¯¹£E¬Ÿ•ºOR(%P]ư^S;°Äqî1 Ù‡9B_ZâÈ1ļ澾UïQ2—LI_Ư`,†êdo|( ÛwN…4Óßư¡(ë|9¾/–‰Ó ‚3e8ö¿YMÍ} 46lûy‚-ú—Çó’.Ơi­í~˜å!©zÆd9–»Áz±¿Đư;®eƠM÷F¤×¡ăÙ…½̃JwÍ·×Ù?(÷̣ƠÄjÎĂ•ÀáŸk*r=M窬/t!:=–¿R`¿ñZ!‰Lwr½̃l>s¿o/úg-|€ơƒésÏú/1†¦̉BK@i²thVJoưØSÄM³H7AëÚỹ(ä<î¼h\úí)†ÅđÔúA¬¢̉Q2;Ïộ́›´5¹¼…©a·‡ bb”Ï|¨öqÇ̣̃0Ëç ›‚ÏƠ_•@²|GK¤<¢b¥ˆS|¬q¼2uù¤ú4{öÆ×e¶!Ç“øä“¢>~ £uGNûÙàîˆ̀w‰F',ĂóiÅDµ4o$‘aFxcàđ¾êƯ±ø¦Ùi 9ơ™‘U9ïˆ|UÂÍ̀ăg1G‚p¿iÇ%x—i9¬Û™,>´Kƒ´×¡ñV́Qlr­§ –t“²xöx₫2‘²o)´ụ́•o‡ë÷í“‚ûù̉weh0oœ¸±¹Êv×ë¥Û¥â]3ĐDhÀ´̀âN,ßôu6“jÁÎHkånÛ/-QÆÖCØ˜đƒ‚»[¿7“3à‡'µLXúR¹K/Éé4Ă;$ôĈIJaQl9–¬ÉZº‘_Ñ:f₫B·ôÆ8:ä¾`²Ek¤îéÇYÙ[‹†qƠX«ƠswưB¶à2$O$^>‹úJ́~)àÇŸ,œo7Öטñ3±íÏŸ¹‘€æ¡ÿ g8óăƒ÷IÛ›>- •ë™MÊ…=ˆ¥ç„É@O÷\ë™dœÚü©eC‘çÖçơ#",µ[3¸v–a¼a”ï·][G›äŸ¦/\;•e¿â²MYf̉-Vzåffñ_ÍDî¾ƠÏÄu"±ZîF¼€†ûƠ g_±+,…è̀wâêK%Á̃;nÙTyư,đ⛽GƠFDÓu;ÁO öơB`ÓÈ'“í/tS„±^Ä à zé¦ù¸T}]áíñ—:¶zMFƯ²¸'qï ¾¼8 ß07ÜF×cÇO=mù;ë¹ă\<ö.|Á³YƯp!qăÏ̀’¦‡;§ªKøS®̀”AI€{8ĂOé$F+Ç‹ UƒüoûNûG EQ8öÂ~=NÑqŸe0¶uÈÓ̀F”³£ßÈ„¯F§gh,æ»@6w·qỘ=!Ö¦Dø€'·×Ÿơ³ö2ú.ßƯM²ôUÛÇ[Ê©¸!Ú¨2Äw²đ†®ûФ²¾°'°¨Bjy-­7ªUE&#sg§[Ij¹sç5ôlΜ%EÆz=ÔE§}~6§@%'7¶S±¯ûÖ¦Ê[ÿ·f€¦È©suoé; ââÀ‹;đ< Ô}›”g³ó‰ ±F̃Ôuiñ±ôÛ×s.¨Cî0g¬°QÂmûÏM$®·öXÔ*hΈ·4¬e}3²fƠ’ưÆ µ“ëưèæmAĂÊ/à÷€nw߬ÊK·b6öö/sq±=‰{{#Y®VD½̃ư¤“^Fă†î’a3̉„e*ú@Mçn¨O«‹¿,j^—¦xÁM 2=0œ»¯’VÍ¯Ææó=^ˆ¦ˆÅt>÷ó¤?j́=óªX[ªÿȰ†=¶ÚĐa±,\φN˜]§ăơ&³Î£‰?s LG̣a¢̀CÆØ¿E‚[– Úó³M̀Œ7øa±B7`Á:e͸̉hzÜ·Êu9Él$&z9DZç@d3Ê5t—x(å¼dŒ!—ùƒÎ—úœdv²,ư4ó&̣NƠ/‚S$?幯Óp"¼XfàíȦxe…–¯³ Mà<É`aå—×០î˜a¸»tjiHŒ(>©(lÍFœkq?~¨±™"PB¸™³z"|| .úà?h(%Œûüi{HôAÚå#\`å^dÓºo‡ï¶„öåJcg-«H&÷¡¹́Œ â 'K8†ÈBº Ñ̀\Ûyx¸Ô»†^;Ùü O…£­Å½w|ÅÖN=rù^™ï4{¦´öñ­—$|¡§ û̃Íf”—́✑Ư‰ÜúA¦|ÄƯÓÓu¢‡ø¡ºˆ‡úA1Ư‘êí*^VˆXgn‹¥-‘xa‚%×PÚ́K˜&Müª.bÔ5¸4øsgèå°ƒ±ôÅĂù\#,Ă6ß÷ÏΣ— ŸîéƯîGN¹”>“[µÅmé ¾f)ĂrÊ· ´C½càÔgúTÏăcɵW¹zĂR¸"M296íQv₫–đI½åx%µ±Ømº}öGø‹lÓ|¿<{æÉx«>Ï̀rÏM‰X» à£Iɘ«eCvV₫ñ¡Oér`&ơïăơ§"³{"N‰ú”QUW QăæÊ–Íæó>Œ-Y†fÚ-*‹Íioc“‚3&±#yÑ~4TJîQf¦»QZˉơH-ÅóGñü;,B'$S„2á¬Ç'm¸û‹æQJÈAü–B¥+ñâ3₫́±R“‘Ѷv¬Nßw^ߢyûj9‘Ñ”Ô[Ơ"â¥hơ.æÄØÓr?í1Ú¡$&µ¶á{–£(Æù³¡­hú–UvvíWÊs~̉{eư|ëßvj"‰^—Œf‚†x̃ƠY£°±Jˆ™º·k&7Ƥ͟;t2Ÿê“–4\œP ŸZzt­zl@1’U•f®†k¯·uÇ̀ª±}b r».˜árQ:Ø´9¹ß8weúÂMEÚ2‹ÏëD.Çr‘J¤úwäÚ·é >$ \É:؆;‘©éùđvç,®N¯̀ÂÔ´ÍläFˆÊ» £×‘JÑ‘uÑê„u9ívLY<&̣;â©…*F t÷sZNÊyûR¬«®of_qRg̉Í ¨ªr­Øï0äèUeÍQístIh‹±ÓR1by¼ †¿–•{ZF -å¥ú“s^m ÈHS¹x([DùMɆ¨̉–æG‰®Å;K)…¨7#>)K ̣2‘…ß'ľ÷¶¢:/«q¤.ûU%M¤‰ÜÔÅÚZ‘¸?Hüü"ô¸àîđOââˉ• ײy’b½÷LèÊxç³]CÚR|9ï4̣ä+̣jƯÿd*/NÆ…ézEOœ×|0E¹1Ơ} ]iRÙú‘4d5°Ṣœ/=óEA«Ü|AxíäµZ rơ)£ƒ̀‡êŸë¨R2ˆûº) îÊä̉n@gZ¹Ă£Ÿû]®\aÿ4KB\;‡~X!ÀZ«x1s²ÔÎ[-ñNĂn³ÓI­}ˆ“­)XL½¨-Á‡¥l=|V<‘¦Ê6uÍ₫ăWOHüÚ–hº¨ÍCÏj›XmëÓ¾&(.rî;—~1³w,©â ‹p\ÇȬy€!\]‡z}~P@YùüÖ³ ¶YpCEƯ—Ä̃˜ƒ¼q‰ <’O*(Q?́ vgOqkƬÙ!ÁÍÑ ?œ×’ĬÄÿÔ°u²ë&?̣½‰2'RÊ'ÙÆëY&û̉áÖît6ícç̣Ÿ–{Ö&³“yƯ9c”­Ï·Œ‰2ʈđ|@ÆA ơöc­™ªMAỤ́É SKnw₫TF_UăO”Âk·»¼ó.o³”bVJoÁÄÜC!IÓ^«uYÏFFKö…VC÷Â/uàú6Ä¡é>Ư«—0g>Çà­Xaî\Gưj̉ñưÎ?:IÉââôö‰•cJk7 ú&9= D‚[²$z-SFĂ¢hóṇ̃ä³0 ö0.8\ùLO bnÂ&WVGXÉ8q@%ÊNÅV&O !}­ß5̃à¨MDß/Æ—(Å¥ˆädwØ{?¨6-€~U.„ Úă§WÑï¤9‡hó¦\§²WÁÏzàb9–®]½is4«Bq++‡tÇÉ{ƯÆÏôÏkhgĂFO’̃²N‚§5YÚIM<=)\á¡ÍbAOËó­‘?_–¼óñ¼\Z´‚úÇ™P™½j]4r1¥(É£Ïa pƯagG\n¼=,ŸŸ+Z{öÁ=låØÎ€_C­áv˜c&®úôx“ÇÍ÷×pªÉRNK¦¦'=¨N{Ưå…ø@·‹nËÀoz›₫×ê*üÏ ºë°/­\ÅyIḱÙªđ³[:Xñ²™Y¿>%eÉù˜1.LUˆáØ# ¥¦yb‚ËïA¶lÖ»Rơ\æCT´^*Ù£¤ă†q+¬†‹Q‘~e™ôT¤eß/¨O–HLTævƒ́fŸ̀2ßÊé8_ Î;·b¡´k Ư-€|ÅR3IuD–ÇơV’K<ï>¼h*ézqgSøÇĂåñĐÇqâø±‡2¾1 ®ƒØ¨&j±Ï•ùÉêÜXÚËuQCo#£KỐÔ9Ró*¸YúbI¦ª7¢̉ăU—¤W0™H*jÅTw´ưî ¹'È߇˜­3FeÍ₫`!¤JỔÅƯe0â³èP1Àpđ2~¸JnÚoÚñ+0¿ÿ}Ôw‚í\Ê\84|\đΩ>ÿ-'ä>\”đ+לu@øa½6—1¤úÂ&‘ăi¯R Ba&Ï]ºñNƠ4zÓºC—©3₫̣Ͻ5ÇB*Eaâ×n¼ă -”¸·bä#ä69w4ÀŒ*ßè)‘ßJœ9æ°Á={T½Q­ä$UÔשømü°É`Úû@Í©ÑC}¤đh»+eR&E‹¾ ́º.:*B´ñ‘F¬Î%X®ü.¥âe¿¯Rb®eÔZ :—!¹iṕ²Ü¢Ÿ¹m5…ó&˜ 7°¬ăÁUdÆLkí·“´%‹øe:‰j7í¸ƠÔ;ÛmïÇ?Ś¥SVE<\;) wh´ŒéÅÁÅùy2º®¤Ç†«IF”%ÁöjÍiÏ’àQdÿĂKưaqî½h§ÎO‹Èò:‰¶̀­fí\Á*%>o8jơ‹ ¨¼oÇ̉7Ü₫ÆùÅ|ª«®0$À!ǜóf®·E’WóÖ åÑë½îI’É/ïÄOTËÛQÔd’j&,¹ÀZDm²‚=̀ƠÇ—·¢¶->ÓÔjf8`§Às´§/¶¢̣̉—ơ›³ñü â5ŹX"â. Tßá̉ç}>ó̃ôĐ`êX¨Ư]zMUkă}đ¨vâX[[&¨UwËÈt]w„S-ñ<\Öư¾"· `_y KjÍ́nÖæ£P NJÀNƒƯđ~§÷,HA"*Úó[<^jµsĐ”ß+ƠÍϔږVưmÿ-ÿƠ7i*_ÍØ5[b‰Cr†ûe4¦rñO⡲Wé$_à1[·' ́2³W£ÂÚ«5X5]Ëô@Àé…ùuøë^Ă–° ơưĆ5’â-¥9̉³®o»%€̃ÚwM—/æÀ,!̉âmû´ÛK”öÛ¬—5ĬUµzåó÷º©vüd}M ™đH©ƒ̣Ơz1ư&¤j"I)ä-@ó^DŸÅ±b äÈk¾‚q}A!\›dG”÷ôä²Í•poV7líˆ̃ê5ÎW±¸ÍSgF̀‚ßù‰ï H~ĐÊ,–ïÊ>‚‰}ut/]i2-£́Ù$u6oĐzÂdñàèYσăù¾–ĐoÎÔ¤çÉQÖéÏˆÔ L‡?c®ékeỀ@*₫¬ø8OG艢“xéÏơỵ̃×Ü<+z(́•%éFS€₫[(đLÿuƒc§ƠƯ`¶o•—“Ẓ‹=ë3½z˜‘3µ¶*C;Qv;|#ö¯@{æÙw5'¿®]¤àoM̀fEM2¾nå(H“úö¹Q3’• ©í² Ơ¦3aù€^‘¯ËÛg5vQ C‘ ,,GÚfu›)ïÇ’³(ËEƠÍ%}´ÈÙw`æ^ Ưå!=u•ĂSNè ¡¦n öKr}Z©ÊV%2›’—œŸ¾kÄtW{!ïPWăÇh¤8]%™Ô§é½·9ººW ă±h́°áå:i%œAfŒöi‹E£ơcưm©̀;¤· 8̃¤.rƠB̀¹™ˆ#]n/ÍĂßôƠUƒÜwá}p ÈÁ¥GÂû ¿÷ƠzÉ6‡Z©™]Ư¶%äÇüê½1Y†̉S¢ƒ×ê66̀àZ‡Êr°~(f&•ÎfÇñ8~Ë»D…Ơ½Ç®B₫Đ k'ÑgÂ2±ôåWr<.›œ›æ«_m/-Ơ‰úá́Ôû¼°³z#©ÉçÅŸ_½å64ĐH«›{ÿøa<ÉsÚEĂÏ÷+ ½cg÷ơùă˜ÜÇÈAG:vĶuËΛ3;¥$́Wm¢§m*…Fă}„)Ä”œ7=Éum̉vÔm;åx.ÙºÏÖwa·c©¬ˆß´ƠfŸơỞ+…Ư½»{rÇñ$oưÿf—̉ endstream endobj 1718 0 obj << /Length1 2398 /Length2 18184 /Length3 0 /Length 19577 /Filter /FlateDecode >> stream xÚŒøPÜḳ ăîî îîÜƯ†àîî\‚;Á%XpîîI Hp'ø³gwsöÿ}U÷ÖTÍ̀Óöt÷Ûư₫¦††BM“EÜ̉É$ăäèÎÂÁÊ.T–Đăà°³s±²³s"ÑĐhÙ¸Ûƒ₫#G¢Ñ¹ºÙ89 ₫ĂB̉tˤ€î`Ce'G€‚‡=€ƒ ÀÁ+ÈÁ'ÈÎàdgø¡“« @ èic Pf(89‚Üh$œ}\m̃[»ƒy₫ó@oÁààc₫—;@Üäjct(Ư­A`F  =@ÓÉÂäîó?!è…­ƯƯÙØ¼¼¼Xn¬N®ïE˜^6îÖ ÈƠd ø«d€ Đôï̉X‘hZÖ6n+4¬Ü½€® X`ocrt»x8Z‚\`v€¦¼@Ơäø·±̉ß̀€7ÀÁÊñßpÿö₫+ă¿œNÎ@GÇ÷+{@UF‰ƠƯÛt´üËhïæözḿæ`ƒ¥Ȉ«€à ÿ]Ÿ›…«³»«›ư_5²ưÜfiGKI'£»̉_ùIÙ¸‚,À}÷aû÷áÚ9:y9úưYÙ8ZZưU†¥‡3›¶£‹H^êß6`̉Ù{;€‡Wr€¼-¬Ù₫"Đ̣qưKÉñ—\C€Ÿ³“3À \(ÀÆ ₫@̣sz‚î® ¿*₫!qp,m,Üæ ÷6H¢ƒÅ «¿1øü]m¼†́àñă°ÿơúï7cđ„Y:9Úûü1ÿ׳©(ËèÈè1ư»äÿ*%$œ¼~,<\N—€‡đ¿qÔ€6ÿ΃ư¯¼£•@àïtÁ}úOÊÿú/àc©8' ÿ3èF́<́à7ÿÏă₫/—ÿS₫W”ÿ×Aÿ¿ÉxØÛÿKOÿ·Áÿè`cïóo đäz¸ƒ·@Ù ¼ ÿ×Tô÷êJ8Ù[₫_¼;¼ âïíÿÛF7o¥»…ơßặ·\û¯E³·q©9¹ÙüuµX8ØÙÿ¼]vàëĂ <“ÿRÀËó¿”̉N–m'/èê ôAb'À¼– ïM1€ƠÑÉ́°rrEúëDyylâ‰₫F¼6‰?ˆÀ&ùñؤ₫ ›ô;€Mæâ°É₫Aœ6¹?ˆ À&ÿqØ₫ 0»̉fW₫ƒÀ́*˜]ơ¿ˆ̀®öù4₫ 0ŸææÓúƒÀµkÿA`v?̀®ûÙơ₫ 0»₫‘Øø§/` û%ØÑü;ZüqƒMÁ·¤Ăç¿€Ị́ÜHĐ!ø|Ù₫½?àZ­₫@°¹Ơ?à_J›?î\AÏ?ñ8₫ØÿÑÿeîäáúè`ƒ÷ÿ€à|­ÿdnµ³5øñÇ,³ùwÆîÜ û@p3₫‘;¸ô?¡xÀ®àø‡\œÓv°³Óÿ¨ÁÙ;ÿQƒƒ9ƒmö «?íâæø·ÔơºÈ î«3ø&rúGçÿêË? ¸ô4†\§ÛŸ\ÿB Ï4‚lÿË®ÆÍèfư`̉?)€ïE6wkWĐ?\»—Ó?À1<₫ÁÍôü÷Ăë'öö₫‡÷ù÷Ê÷OràH¾ ׿©₫çn±đp7Ëư_·?øâù₫×ặY ­-;Y…Û6†wưn'öbÙ›Y ÙÓÍd`ñ[síöxDƒOg¨Ï ưæz'>6€±¹+MûnüÅ︽>ª#U½óÉÿÙ4Ycn¯iuox¦ôX¼é+)" ‹Ö»}ÿ;èvÈ^B~4µb́ß^C²̃M_«6&#—÷Ô÷ëy‘Ÿ«æYâµ?…”/̉™ç-P¹³"0b]x£/̃̃-`̀¼‘+$3!œÄs•ù|çLxX̣ƯªÑâtë#¤&4 …¾Åœ£ơ“8̀PÀ_ñ«ø”¨÷ÉÔdù‹h7:Đ…û3EïpƠÄ̀ ‚_¦!’Uè»s‘‰ê;4c¿́5 z° ›øÊç_8LKÜÔ{^đ|ăjs]ĂĆíÜOƠ8£²ŚÉÂoéÅàz£3VxW ‹‡¿ ÎÓ5§¼½K^å4/r7́÷z£ö@ñư¾ ˜™‘uDÈ7¼Ñ̉?Ơ… £sXSÁ™æë×a½Ù‰BWÆÏA)ÚN~₫¦Đë‹ö6¨’l&¶n"¼ÿđêû‹ÖGøªe•!h.!ÛVP¡ßfBñ)–S³¸Á0íøk„9–Ød2d¨Sx#_}XSLGÔơ₫¦ü^Tpºy®r>ù—e½„eÿœ|ỚY„œ‰W´2z]ơ ˆJJêœ#¯K7µ¤/†uröºWw¥n‘T8S‹Pý„²E4Ü•€°F%t7?e'Œ*Gô‹mÿuñX S¦ö«WưÛå.̉s3ủÏÁÙ£º*¬’eô:óFç*ûû$…Ưm\˜h°‹âbWö¦nư•Ê‘j_î«{|¬4}*~,÷Çœ4đ uN¾SÛMjPñp]fPñ°®LX •^+êèW[Œ3) ø̉FÛ×·ˆô“¥bÚW›qjƒŒ«æ đnW®̀ ?̀wO]ji ¾“mùÇkÚ®…wG^‰'ÁÇ*"ú́P,aáX̃ƠlÅǺ&È&ßgLÙî"vH†¾ WưÔXÁ•zœ1‹bH< ÔÊ">y¥Øå½BƯ·ö cÔ–\!XƒR |§đ¨ÏI!c¡̣F‘*‘YiG{§(w…„́F„/VJ(9®0«Ë0é]!ªCoë[S§ 9µ}èĐBáôătëûä!û­>‡¡>³•Yè~ “Êy!¬à‡ Ô¦7B¯ï˜Æ.†Z›ïÍ~¦v¾ÀN¥˜¥$Ư¼hú á3¸ ῭ƯL2f:öEèÀf#Á9´°ô0~ÛíûÎư ‡z-MGÊ€¥>£¿.kQw]1Ă¹¥嬸­µ(PËă¾́bYơ¸‰7¹†â!„$˜CËÇ]vûá׿|ïWxf‘¦‰*|‹}®¯\ „#üv_‘­OLaOá́;qÄ’¾³÷ZB¿Ü©ô .ö ^•fQOX ÎÚXà.gÙ¾H>)s₫4›äq­SJ¼,!øÙT:úø½¶g*đû«E!Ö²bÅ÷l +SQµ£ú™̉Ê»ZQØƠưĹôÖLø=îÔ.R~_”6“Á)́¡&!°(³\`Iơ(¤¶h} &Öv Œ~†l i8Ó̀bÜGÎß]IÙ6ûÓy®ŸÓ+On¾TŸMn‹Í$Lñï¨@:&ÁQ9€¤Ônæ²+¢y;ˆ“Ó>yXK÷™êÑû$Eªü΄§ *?À·äY.̃Ö㮂íäÁ¦H¼@Ñ“̀k&S¸K¨îù‚a´ºh¬W„CĐ‘AÖ\—ó¼fÏØ¶8I,¨ỎÂ"Jâ<Æw—̃¦ÔñÔ<²j?"Ø4bûp[‹Ơi™ÅQ:%Ẹ̀xOÁŒ3‚Ô½_„¦>Ít/À¥ăèIW·_>–­kiƯA僠"‡‚ôqaú±_}‰:¯Đœ$~ ‡¸ïyoËæ:»´f@ª†ÁÀƯ`µ̀¤ê¬gíàÉ0LÔ0 ¶.”ÜöẾ&¿|âVÇNó²6ï ’{಑m1D/s8ñ½O×ÀưMMºđ m(]Èí‡1ä́«Á¦ûđ ±3¤h*»ß’ê`Z²º¢ëj >0tÉùRÀ·,ÉîA¢]|Oz̉M[µ·Á,>‡èÅBÉÄƯD½]&:ß^)BUz§È¨ Ơ%Sïc:Æ¢Đ6‚lN:]Urm`™xQi•‘Ô—8$ê­rZY¼í¼›èư)¯]V)xMµ̀Zôº`Á)₫fḰ"¨b]AèBÉÈiœDđ‰—`|À;aÙ!D€N`&5ßoØ}8´æợG·Ù®ó È™DWƒ,û†0Ïëï&¾̣ñÄJq˜é¦–ƒ"¤6¾ ê°%ơëÇ­tdw6]¬UŸ™̃ ̃!‚r„ëî6uE?†5‘)ˆ]©.KÑN'"ĐѺAóZ:‘M8 ưZ̉›y¢Í•3,%o¯b<¹̃Ä7_s´O‘ó÷o!§ 4øJ«Vªœè[u!;ßô*‹ÍÚIơ,Í ·n× ‚W(Ơí>´́́ñD;è¾7Ê. l ̀…²¤1<ô>y|Fêó`±o¶¼ưÉỰ«Í·̉BÉ-*ï·–œ¡ lç4ÑsÄ₫1Ư•ßqʸŒ¨ *°6çgJV×V2‹låbÈ%“iNÓ“¦À)ÂMÔ‰#wă[ßP£nüØí4 ¶,Wî̉ăĂc<åÇ ¼%ˆœ¯ Ñs]‚ñUP³AŸÚ™ó(dÂÊJë'×z±Qµ$`øú´R* 4ñW¤ \̀ª¸Í{.Ù€2-Hº́ơ¢DÇ>ªQQ¨ÄùÂeºB–œ6˜àíàM™ß=^ʪZIơRn ™êÄÍưa~đˆO!ƯZÛ=_n8ët“ëTܾÍ'<]¡ơĐH„­[¸Ú &Ya₫q-Z°EtíôKñă:¥\̃L=Ú"z! ­sZ£B{Ná3}ëy'éHÎÜU­‡üV̉{VûBơEHÛ1Û‚ µf$³N_sαºÏºÁÛÊL_ÂÛ‡G¬˜)7Ù¸K†ê…î2øÙøúkE&œX4h‚c÷¿;f(H´’¼s܇|ăgÿ5`Ư‡£!#ĐP µŒâ—D_L›yAư-")HpâÆº—è₫í6QùͶᄁe•ø„&I _'üm=ZvgÔóK(œ˜™¦à÷cA³Æđdëúï œjˆ…[Âú÷†£[koF¶¡p¾÷üXă?¢~́¥¢!̀`-Ù‘"“^Zm[…e$~(˜@®Ăª mFQó"–n(¿¡Vé _.~©x‹¦´ƠƒíÔsƒ~Qv%Z=’®o>É[Rz¦<¤8a´"`Ê¡€ÔI‡BaăÂêÛơæË¸ä¥"î}R\ÇDïRb?½ ¥y”áÇ™·±¥~“ímڤȩƯU™™ÿØ]¢¾séa˜KbûDt/ œă„-¡qt¼ÆWÇZÈS¹K Ѻ«!Èj*RèP`ï̉’zcr¼ß/?®qÉ´KɈ<ùÀ0à茯ïÚ’3<¯Ë₫)„îĐô|7_bó«Ơë`̃‡êÅ2û j`â<ƒÆmü[`4è!æ÷‚1}Âù:’à̃³£Tl{sÓ/¢poW¶`9á]£àp‘}ÍăW7à>ÿáZlǼN¬UçfWÑfÏqÙ¤<¤°YûY‹ØÙ­±Ëơ1œl€&5Đå₫‡ÊJ«Ư¹WÆKưGŸ™£̀đmçÁfN2œöÔ¡yÆíf| ÉQ±lUÓ1HØ.îXÏ‚;éŸÍ¥ uŒĂ9Zçu.̀™Ă(£dØ-Í“€D'„o“ÛVܲ&“5v)ô~ƒS‚›HY-¯ÛÆ, …/«æDé!Kb¸Ÿ '­ÇîƯ˜°¦‹ƒb‡M[Üṛ‡5ñóI™î>6Ÿ/ç&]_Ûi¯d¸Ÿßc””mÇÑ+¬nTŒrHÙZ›Å¸zX~»º·i'6í9‹ÁEr’1˲°»UÉYŒûMîhVü蹂»ÄÀ™¾‘•̣“ê•÷aÎïơá¹ú`§®ƠHÆóVûD—¹7Ø₫ ‰ÆÖđ}ó"Æi„-o`–$̣"î&eJ‰½dă¹zÇ& É+9Ă,c«î’L®*2F–OmĐÎâAàµK÷iå:¹|qDơ§É ­Fï°ª¯ÆOU 7ä6îÜ9:‹Æ{1!: ÉëªO©!Áu·] ï!l^Û‘®hX ´‡ ­´ôøÙX‰",¢đâB´a¢™ï­ùÎù•‹¹gH}w'›~ؾ:¸z̃æ¨Ư$P¡¦"˜{_uî̃w~Pl*@ö©¬J k¸™áAŸÓxÇægu¬.yPm9̃‡0ºr¸ºëÚô‹¢»ó¥`.é¶óƒ•Z‰Ó—Óà^å&:æL´3^S¶ ]?ëƠ©±ó1¶˜¹́£IÛƒ&Í€ù×S…(_ä9·ÈØ¥ÖŸ±?–mñ+¶›}s”ü\Ä 4æ­©â}U4”¶|HlṂ‡̉FRH[ “†IÈæµfg  ÅqƠØaCáÔđéEvh˶=ûwL̃(Â`{º£ôxˆE¬¡UæC*«•4ñ°;Ëp›ï=Å‚¹y›øBäî’ñ)^¯[Tn^úm‹wT¹I+ºqÖz̀·̃öJÛă!Ư‹d®|®ö›ön/iÏư®½Ô ™ bR]Ú˜Ú¼C>ßupd₫f«́(m%â€\¡!KZ¯ SÛ¬VÏ?ư[%¿¢ä-O#VØx¨T‚¢ê+¾X°ńùƯ8ë]ŸŸ°ÚèÀG±=j6óâ] æÈ]0Œa»WÙE88ü±ä›*è¦ZyGÙ­(ä´gŒ° RÚryÿÛ‡p¦·eöÊJdAdÈ$K|Mø‹Úễ:m¯[UJé•§ ̉Ù‹«c™ÄAáạBô9CÊov̀Ưä¬[?¿ĐøÁ›mrÖp”S₫‰ºVÄæ₫)S Í{KÔÀΠ$óƯCEƯÅêcíBßÈ+È»â¸q•¼Èâ;fyÀ,è̀ñÊ^´ơù ö‡ÅnId,›½Dá\ ´oÄ=Ë~!r l®..¶®E§kâ,ö¯ˆübA:̀–ÁFÔBŸjÜI´4úhp”ùû¥N‚Úf• Üôưb¤©¸‘‡Iù+l…¾P;–aXĐMM)J£dĐ9§î¡Èî6M%1ñ!9–-ÑĐÇŸ̉̉h›Ü”½Ÿ„ Æj`ù‚ùhV;²‚íØ8å[íbèj˽ Í…'%̉±îüG„ôw’‘ëzíûdüV«˜qïr÷˰é˜EẮIJ \\̃5˜áÅàHÆ5œ1£ñ®û_i6rTúưn›ÜÛ÷»1m"‰·}^—aưmæ¦tÍnDR.m³"+»û/†²$ «‹Û¥Åk¾t¸û9Çle¯==á\dÿ1ỖßEmÛ^œTă‚₫³]¼ÛE+Ür e‹v®—̣á̉ e7‹—Ùµ1ơæ̀†Ù̃U¡!?F1ô#̃}ÉüîJ¢„ÿ¥î‘œkBЬLœO21PÉt?³GƒJö§¸Î»q¬Ô¶%jO3â2{đcˆÇ7Ø ßóŸø ¡™ ÄÇƠ®ús§ŸUb Zi®çß#@\iëÑZOEó&­ªö\?~_Ôæül²Nđ; ÍW¶₫ô`£R8?]ựâcƠmªùF¹&úÄú̃́H‚WöéeôX"́yÔRï,©ç6¡]O:âsîiDÄ>H«Óô°À̃^½›÷ÎÆ©"<$EF¸)‰ˆk1ëÙúukG…o[ÎÄk`+,nĐ/‡Vºöƒ`±=æñe6‰DÅç/̣₫eéHKë9ơV•6ṽe€Ä3ß~‡–6̣×ăZS Ă©’F KYĐ—]×N¹ÏÇnë1ëÏå{5U¬0ƯưÆøÅ­¸Ö “€Aÿ+C9Ü*ûÍH®qĂoQ¾Ăh_Ùpåçaú/å̀‡–sQF×½¼Nñ™§ơ‹«}‡íD̉ü²K†óØhVÍå>ï‚ùô Q0â áYbé̉ñv*ˆW<É̃*°#SJ’&P4ï¢îĂ(+6!‹1ÿYĐÓœ́€3Y'£^´-§ù/ơ‹µ&<̃ô₫ºgûK¶v‰M$5Áúy3¯±É}Ú…üä`WMj˜zc¶†pÿ·«VÊsAVèăÀé¬ß´µO‘k-ZˆiJÄ*M²"LÀén`ÛăJd'}3̉R/ôøÂ›«@•uÛ̀è>éN‰c÷< ²b đæ„wæ‡P…êRƯŸÖñ:ĂĐôSè@mÇ«WdŒ¶a¿²åÁé±zOÖë¶Us ül‹—àÖƠ­ñ¡r‡PẵäÛçåyŸ'YËö[%’r^F2ÅmçïÉ̀Ù»ÎưxdJºRL₫nă–º²¼u>đæƠ8đzܰ²eTCg|s\K,®xÉÜ”¨Óâ ×kXÄpé?Èq…X!¥— '6B >Í •x™{_wă…Q<‡è²9¤Œ÷”₫̃Åá~‡#‰ïiŒÄ§¼tÁdÂ{¿:soÿµ‡¢Y3H₫»’VÛ'üĐGNŸPkløªÅzÖ&˜hcó:OW¡î<17Ÿw:|“ˆ;~©₫̀miwÀè=æ*p¡gR%åD®¸ùµrĂpœcŒóă†Ç“ ‰Î dn’­lbhÛ<•1ü‰×CW2À¶¿¡‡?æơ`¿ËF)S‹LŸÖªé龟~ơƠDGÜ¡ê¸GSwn\ßÎÂb¬1³|̃„ª+àü~ĐØA©ö¥¦ù¢l.øÈ¬Ä¤€O›.O2Æ9J6$đ₫Á:ˆ‹ăhâÇ­†?%´PÿÛ¾ÿùe¹ù N8¼A-µ¸JHù¼/¡«n̉1ÍÍÚ›”ñf\Yh9µ^!M†rœU¤[6AJ-c“FBP‰‡UGE)G+ƒâ+꘨2Ăñ\¦«7LÁåÎçû‡₫p?‹SÂH çÆ%CR ¤–.\’@3®cQço§ÀăZÛ'K'­é‘£,ÚUăï½ †£¯ [†‡ÁïFzi©dømvMrZ…S?@†{ÍÁƒ˜XÊí¿tKYææxbŸ‹₫”¨„Oât₫AfH‰wM`»®Ïl\Ÿ¹Ù…½r³Ăa×…¢ßÔ­¬8å—`Í%+™,b²0#‘UĂf×€ơ#ï váƠ¯åƯ íon£}äC£É}Ÿg¶½‡ÖÔjT đvU¤ơñ=̃ăÀ‰?Ă}øî₫јdé†T_Ûëăơk2ld&̀n¸c˜¶€JvxT¯L5Ï̀+¬ăÖSV÷Ăï·₫ ›Ăơ¹ö´`ÁeỤ̀Ÿ·røqeï3~ ‰{¾Î•°îàÙm7·PŸ¼é°´¬S¨}YɰÈút ?l5 ñơ³Ä«“ËwJ´»Ym1å¼?½ÏH–“GîÄGÄAé5Ơ!ƒPâ †ÆÉ&c4ŸS/`́ĐÂa䮜K»8Ûo[̀Y ;0³æ×ˆ—‡kđÎç¼U¹ÈïµÏ×éOkØDœ|Q´̃8yLNO\ªí‹T#ñ§ q†W(¿X ouJïư6ªsJ×₫æĂŸ£'¹Ơ°À‰̉ơ²ŸüB₫-3çí z]:ú'‹»Ç…×9¯Ư‰俦ơ·̀W ă·r @XsèFÁPæщft&?2…c`™IÚ3&üöÑÇŸz Íûܘ›:élÆÆ‘đK¹ª *¶øºm‰%À©ª¸C2̉"ô„-¶”¯¤tT+®èŸ~Ø|¾~j×Ơv.™A˜¡wJVôæ.C5meMJ<æ¬;V¤S©œøº¦[Î|`̀_¥ÿĂưćtsøñ‡ ~܃óŒhæø¸ß:}i\•.T'ÖfJ »5‘復‡Î˜®·Â¥?¾±°2®T€}’Đº’âà?"v;—ÍéinLYÇx9q̉:¨¼ î ˜µÊçGÎƠµsUjdÁUûYÀéơVÚ ¡>÷$'›¹Æ*›7¡!ñ‹Fà9A“so†ëÓ˜ọq̃é`U ™e*açQ†ÏôYŒ¢z††úäfƒq´—œdƠÿ̃UÜN€“Y›‹ưPöÊ–rÿ˜™Kê|0$\­S›±5œ`©Tg¥Í?oc—nÿ”₫…QU 㨩úx¢cÏ:~±mx{5sV;ÇዱđYºZA °;,ŒÀ ´óá´•.ØBă>= Kginăç­ˆâQ°kqÎU¾Täé•C´R뉻Hœ}ÅK«Q¡k?Ëk?†uø>~7º»©À·Öd M¬P¿“c9ÛV…Ëx6«nZ ăM¼"Æé™ R”OOGÓ›æL&OOiĂ¡$û`øCkñËgW6t΀|íơqiè´Ñl‰IZúÄ×RFÓví+¦ùo)úbH]đÚ¥~¦YíÑ­üS¾MGoÔJ½;U2éaß.µ)µ‘lI:aơ×tá'ZSQëzí¥À]‡̀B·ēqµœ¥l+,Ù̀»ØÇí¥—ct9ʉ'<¹ư0ÀMŒîc@ ZC̉>×-ø­ ßĐŸ%ƒ™WSA¯4»añ“*û›¨´}Œ^©j•êTră ·<‡aqE)&‚‘¥¦#¹€1ÖRlt}ÑtĐ#…fô¯%>ü!ß¼Dh”Ëú§§ÈS”c?¶ Tí¡7Óˆ.(½ Ö2µwjJA7hM˸“,óíô÷üœ¯ŸóâXv"ÚåÈ\ÅZ´^7­Ÿ_@†ơùñƒÚ¶¯ér˜@8á'1Iè=¢*ú0?ɶMó-]zfµÀâ(ËüFNUÆjÂ÷´ÀăÖɩ۱ âGă¬d,‹G®̣—adHc¨F₫‚Xá̉×–*ˆjkcÔ’TŒăk¿'é­%EöÎïÅq₫ê$́]Óvs›shO#2ŒđERç¬Eme\à3ÛçØéï¼T8é®yORGaÛ’sÄq– QÂe„ë"vt,’ ÷ÊËÆ})¼ô¯¡.Đ©½É`i3F3Ä‹¬¼é/¾1L!–f̉M‡±˜0§… ÎmÚk„#‚jå¤ư…)́ätV»y5óI›˜Úw“X’ÅÑYöˆPèjôăóc[¸ºÍ8*\×̀¶vˆ)đx¥{º _—FLZú—ëë)‚Å=•ª"…w‹'n¥‘”o?ÄS %§§yÅ\!ç̉‘–ơ¶}jA5O¾7Âz«ØÀîÉε•Ç̃\â)µ̃₫º+ôî¬-ëÖEâ0ix<[§_Çp$á™íÓrÂn îeÀÛ/ÉhÿøŸË…Ưă´f2Đˆí~Kµä†nä¬eŸLϰ†ß‚5Xđ·®­K9ÔJm?ùÿJ)ô5‡àæ±{È-í´äD˜“9X*ƒ~·̀Sjªbu 93›UyÜR–Â5€mí&ÏÅSv^'Ù¾qÙZ'âíïyU(Ó¾¬Ơ‹4…‘è©,Óà­Ăêúø½ùÈu¬]èó§§¼tç©̉Üfh/8x’đáL¸°Ư6;tUC&û}L”Ưtli8Ígn†ü°“–ÂjNư° m?k˜H‡Ü³FÂCEŒçƒ#q#膬_x“OͲ«56’Ùz;Đ{.á¯d•qƠF&Ö#׌”̀×»Nµç=ØYm÷Ç ’›ÖBW¤*x¹;̃CcsrËLe.’&?Ó•<-V]$n¦t4S»̃4£Éߤ‰§Fóµ”1)³̉|ˆ9ŹëWŸÍ7e‡ÛMé³́‘Fª2.níH+––në¡ GÙ)`½ÛILœÉ‹g˜Ä£Ñ™zcR‚ÿđÏU³„&€zÏņ ±ëi;:@1Ơwd{bj ÷đ.í×ü´Sdß¾Ậ„Lÿo;rc“í²ơFÈàö¦Ø©Ÿ)IÙW³îă%ÅAçd´ëđ³Èd8Q0Úđ1'‡RDͯ±Äçc4Ô:́`‰7¼̣#áă¹­nÔGoËMd“†8̉ë5ø%hW̃-ç…–*ù“!ưôƒÉÁ₫Ász(¦¸î²4Öéåó4xư¡FQØ6<¬Œ¤±z[LDí ®e~Åi”Á>ÙíàƒH¶ôÈ‚ ‘÷›â¨é$RÓ‰æ“곜Íy}p¯üÑ¡¢ö]9ùÇewÊ*Æư ‰¯ùˆ§_VÎɳ縖c?}I×™âLy—¼¬D†T2Â'ưPl“íø‘É°ñ<‹qø©°½à·j^í¦† ­´Â´q}éµß:üŒ@0~Ê‹*Ÿñ©măÜrà‰U Ø..uYÉ‘ăqÖ9Ù ª$—ăÂÆà½ôÑxa¹Đr\ÿ̃èCûÛ …ù½&o ‡̀b —ïĐH“X9ơ¢5»—Ñ}0Ó`´‰±Wèå)₫ÓY2tåjíåÿ g8¯½k ¿̣»(³¾ÿ‰-|n+q>‹×ẫ_‹̀¹yniæé˜k#]u:H8+C©Zr ¨¬Ï rêƯ­†Ùä*3(V2Ñq_‘¸D8Ư 6>̉ª,đª®ür+;Dà+Ÿ™ŒƒZƠ4< ¢)BÔ ˜±ß§{ß«~ôp-à³Ă›tÖm?°éWQ¶ƒÚ>¨ Œ>w¿RçÑƠ⃘`ϧƠ5ÆÜP%₫Z^Ăó€á3º[+}Ù¼É)§ø¤½8—»Ö c¼QÑ]Y₫ÙåÓ®º÷WÈóXvÙ{́gι–ñ Üæ‘xˆ̉…*ơ á†¶ÓY£-˜ 0ụ̀TúµyM«•TÊßE¤²ÆđxdÔU”g Ô;Ȫ½»§ö‡¤2h–̃S«›¥LIU¾̉áûêÂsâx‡@½')́¨ä‚Ăëƒ<èÁθ?ó[i¹¿fô¡Úo„:Â1]ŒƠ±lèoûÊâhFüh$Ó½Ræ̉’_GƠ <̣^3•ŸS¬ aTßñ€µ_̉|@1kq•·³«h˜ÚÓlßEëđ5!ç×4Ÿ+̉iăt—øJ*rÍ«,¦iU9'ñÚËé ·8—^¶å.9d„ơ_óeé̉IUÍ‘f•°Î‘ªCyq¬bëS«‚Ư9Û‡dĂ5£Öê‡l¥Ø¨9-ˆ´ăO©bc§}k6jlq¾+æ]„£˜„j‹è~˜ ÀFiß?Qñ2=èMxđ$®HlûXÿ]lÔ¿{Q ?©¨é—Ú]‚ä:đv_ܶG¹f)/|F°Wï8q½¶öî¨>Æí‡½ú’ø¼Xm ®ºfXzÎQtVĂq(7±oukFÇ y“ûLÿv́nxâcG›ƠĂ)ŒD×)ű¶†Z̃­2öÉ‘[ÂEÖ ¸£Ió×°̉ ”,cŸHªA±½ịËȃƒ”Üx(î䀯2ùqëø8p—ø/è´®Ă:(´Uj¯§y?¹|¶rK­^1X~> '²…3̉LE[–w/¤o¯ ‹»Gs°¾ÁÛM@o_kd)Í3˜®đ"₫₫&dHW‡b%ÏyñØ̣JYlä ‹jøùhưqÑÂ[ σä̃fƠ‰i†ª‰ ®RN¾ïßXd`¢ï—üóS~¤§¢6«C̣à4º¯ôt4§lcU_Åq9 YC–´™ơy\b́7>ë¯bZÇÂêzæ£{_5stăE –ögaúƠ„7SŒ´ ‡EA‰æOKæ.ïæIá*£Ô Đ ¹ªÈ·è s Ăhư mVß)–̣DÎ@ádÑ\‰¡vOÜÑ!Ûhî6|8èmă1†|iHØT₫úkü8ê)¿ÜÓy4r²¬6#Ï“†HáĂĂ$4~¢ [”ƒ¿Ñ”²cĐ«̣w4çÚ’™lë:<Ùhï´Âô%äó¡…\ÿưœB8³ă ø%G¼Ú§Oæù´6¿B1B³Ñ3 ÛĐH¸Â–qqCm±U>“Eßô<³­‘ơnôx É»wÿ4Ù×YJ˜Óç%¯¿ ùÅ“k³– ¿•’Ë!47‰y­=×AÔ³ơÑïÚÈÿ–Âq–†Oư,#›èå=0©ÜAh± ‡(̣ÄBÖ0èk, Ô±YgÉÆ”ë ÛûÂb?N°Ï„fÎY_V_ñÔ;Ư¸5)Ă&ơ%s|u)’‡¢Ä9§tZÉ• ÚåÀ-¬Ë”[µÇÅïû1Úp†­gù×u©D̀~̃4›(}T"NƠ(ˆf.eâدˆE·ÓEĐBŒ]Sï;JÖÚ‡jѬ–.ƠÇŒÂGơ° ï峩•Ăºw”Ọ́ˆŒø._§9Kđ̉Æ´B4®́bÔ·åŒ~?¯6!¸¤G üư‚G÷T|ï£Ôúp›á†ă6Á Àƒ„6e÷̃±´æă½́ÖMÀª 'ô‚b‡k,Àd¼îx«*&»‹™Z@—¾”üLkoa©%Ïœ`₫˜bsY^#̀ú¢á±Ùafî@›s‘˜¯í–B2́Ô罤{Ñk®[ÉÂAṛ/¹6!‘›ùjN÷Đ÷¹©J¦¸}ûú‘¾ámöà¸}œØVñ3ÔùçÚKư oU9&î%϶óGœh^fg(®₫ömÛ©QÈÇS™7úëî2!_¢³Ñp2µƒ-́D »Auu±wđŸÖ b`¾bpôÊÇ(tr\çbCÿ­Í8^eÛ–‹́–#é,/yÓDµ°₫Mb‘#'>ă©½YÔÔ>¶¥>q„ê ̃¸xg½$„¶ÂƠó2­î‹ø¼ºÙ6Îå$,[)IÅ€±”[C³ŒVëYFGQ˜ùẮ̉Oê|ú|"áTe*ë—Đ¹wïEUUôçŵ9C¾ê÷A f„,r-Đ+[êA‡%›ư­l“Nù̀k™{1Û|^ª}†°]ăĐ”,D·éđ %XŸ®̣«È8•,¸ầ 'Ü`Rûx,اñ¡ sÊû‰æW ǃđ߯Äơ$+BR)Z‚Ô¨QâËL˜0¢çĐđÄS‚?nT·1§ C+:A9GF„1 adë7^3^́î±Rª#bµŒ.#rØV±H*éî SzØQWmÁXmPK*‹¶±1L3í)Ÿ—î¨%IđzÓ)½v´@Nß©ÿ<É‚+³’Đù¶FlSụ́öæ ̣Wô‹ú¢DfĆĂWƠ‰ii§à“Ơ®ÏƯÖª5¦‡¼È§’×.]H¼*zbS… ‰¬æÁđăĐ&r™UËïÆĂ í_4M ×Z±ÉwñI—ˆÛ”›‚CÜễØeqßvIụ̀’Ø4"ªù™Cfqă0Z¿hŒ{=caø+*.zÄÂ+¡úÍđ Oë:aºENø´-ăöÉD|~¯§6’n…(p`4y¸«©·÷©0j\YUñ>Do1^-Ûy²ÈL­ĐÄ;Ạ̈Æù:‘SŒ§Rto-QîŠɵÁM^Ÿ‡…C^Í Ê^K÷ö¤fD;đDM³¾ }Ô!!ès#y…̉ÇXƯ´ª ‰ñI6ƒtĂH‹º”¨ÏªögZ{’zÁÍ¡nÄ*¦R¢̣l̃qP*€à8Ó¿tƯlˆÜ†¯¥@aÙï7ôÜ+áµHDt ƠÂs¹#Iơ–cS‘ø$ʻȸÑö.›ú¡ $}w‘,C8µÎ4Ï´ ³ÿj_UÔdAar®G"ÙÖ& cô'M°¤¥È¢̉÷Ü0gÚ‚èIß7HăÑ\C^ ₫4‹}³ F₫³–Öí/ i¢y/í"–³`ÜPo§ÎhÈ’rq_" ª)÷RLj6ǿ®DƯ$VHÑ© ¡lưCiz_œÇú_PÛ̀ÚÆg™£O£W.O¤©rf(¾Ÿ· „Í?´bùͲµ7rá€L̉Ûáø¾ cù¡Ó}!øú1êajºPBf¨®ôà¥ĐKäɺàB÷R¼j’@B¨zA5 §±¹Ô½±ô½̀ k&]í }}ªdóí̃̉”øˆbíưoƒù©!?Ơ`w·®Ca$.×ëyIvÑS$³Î†­}±’·`^Û^&y"nóBôS•\z¯P^ Ê nª“Ï"ëÔâ ¶ÛgƠ'©öyÜk‰k§ÉäFÖ˜0»̃ä*µâăß̉PÛ˜ÜÄźÑbq¥^¾Út…Dˆ;ÑRÛ™G¢dÈ~|û~ùI?WB̀Ụ̂Å~„t;WXÔµ#™We•ÿÊhÑåvøç&VZÿx†¼_²DÅvµé€¦/ßÉÙüuë#z—_Í«%=}gầm~*èPZ ®[xón.M6¹ù‚¨Úc¤€qˆw«VIÅÜr/@^´‹­³UU’Ù¯×é̃9§½đƒ—jÝ“‚’ÂúfºW¹ë ¦‰ú’ל—ë›™`bEWđêÎI[øG¯̉ \éú÷œœ<÷%§̃«Y¢Ö |‰üÂe[í¨·‰•Ê›ă¬¤VF.,Fí)̣ĂĂnø_ÎúuÂUrâËăûXª¯Éc¬,UÏLpÙ’gơ>q¥›do®ç3°¤Ó¯áuE„ëđQ™ñ.pOTEÆU’kßSçGµE4¯U< ´<¸xÛŒí̉™7 ÂÙ{xeP2N̉üh̀VD#ÚÈ^+×ÖÎ2×1C‚wÔÓÆƒ>cpekHÀ« ‚z³Ö*'6̃œNª¾bƠ,öÖ]‰>é%nçºLÎäë´;zE0Œ›ËK¦V¬¬ƒ_JQ" â«PâÑ"b́Ö,­`qFßYHÛ|îÏt-Û—₫Lƒ½- j ±"¬ÑâÓ̀¢{&2JyÑÆeMˆÀLgWµ¹hÇÓ¨«œ1†ä'„Êø¤®́)e£gh>§Ót’ïKơ¹-Äü „êèÖz¸>›Å`óă>|XÅÄKSDsxæFxP{ℵñ]Û¹“iéBÂÍiÍrUsŸ¹Ÿüơø‹Sîö¨Ưœ ù[bÂØ¨¦«TÀ†ư  óUµØäÈ9Ï4È2{nh^и ^~…Ô¿çeïûưÂëhEöëÎåæw,Å£XÊø ßĐ c’Ê/ÅÖ«Ç'®F^hªíb A“E×!ÁÍ̉6Íáo\r˜-œÏE¢½Å6‘ÊAé¥r#„È@Fç̣̉©Í6Äy¸a ©f×f3ß]ü?÷i..o©p|ÓkœÅÇ+á"FTœkÚ†aT‚lNKÚ¤:–³¡âêoRéˆN%!ÍíÎ"oê¤BˆÎUk%ó8_ —†Yîüx¾9AÎĐ”Eox3́Q±•ÆDĐ̃¶¥`–j¥ÜúcĂB*Ơ Bk‰—<è®Øîœ¾ư¨}1ĐoÔè(—̀g\°Çkøđø’¡ ƒ-=° ±u¯0>½úsŸ´è»—xˆøá{Í„×WG¯˜ T8̃*9¯öUËw| Ѫđ©)¥UÆÚ6‰ß*°)kMPml~ Å–Œ,àÛœz=qßÀJXEvô@D ó¢[Sô¾…Ínu^€ˆ¡©́S‘ó¹̀0%‹ÎÜ<çÂŒ e–ºfoQP@P2*ÚÈéÔê2qHñO%¹̉#dÊu]·PULVg;¥vçÓ7çƯ0ÔX¢ZƈiØÅaæàß̀ot•º+!Đm›ï{‡nId]ñTf$ÄghqOOÆ âù±r̃ 1Æfa›×”WHơI~|¦øz•7Îëơ¬.“·ÛÆÓ¨Ñ3+3®“.Ɖ0Ï!;-¢éw™·Y*GÎ4z}$‡|1¶b',*‹ù\zUJß”x±‘¿+¿­hA‘?û̃ä|Hós³üQ¼àV¡ĐjDÜpưeI§ÿơ³P ÓÂ₫¯e70;j~Wi»´È¦6U ̀P±ÓÖËZ#9Wh̉ˆ]'3+ƯÔD5V=):ƯùpúlKT₫v9:ƯN²e´×ÙŸ£.΂̀âE>M5åË¡ø+E÷Ă¯ö‘4Đ‹HÆöܶê8̉éåæ9¾̀é¸S?h\‹™ïb¡&Vo‡ r4̀¨o#™¿ e£E+ "Æ !8ؾç•W…àÎC©¼»¶m‡"e/BÆsñ =°9]?{f G0Rù ëWQo ̉ø¾4ô¡ êVöç¿Ï'N¯øp¯¤ôÙ4VL 8ÙÿưP^o¤ßh¤ÀŸ́C®«ÿr}=á=O%­K“ܯʲ‘ åU)\ÔØ¯̣&¤0¤cût?’lùƯQ̃”jĐ®  T§Úy'²~9Ëá‘oǻ2ÉŸ³hÍ!È á́~̃óû™î~iL=´Ù]q€gcÁc+ƒQëY W!àmïÁ́˜…W\æñêUfr@½X"´Ñql“Èx́Ê/ @™b¾ç µ|y™ùá©¿4{ñnƠ¹x+ ¶´&²{§~ö9÷H“A¹ógï̉̀}8=ë½LîÍäZöJFÁD̉o¥ưåwµ·‘Ñæw#ZEanµ°:¾¢vNƯMz ±RA7–EM̉qˆ¹>å÷Umw `î—ÁMơN÷ÈŸÛhŔbơñ]›eBÁ®?—œ³j Œ6xñJƠ8Ăœ¾@“PtI«êV™»“OLE3‰ÚzæäØZÙ¦tP¾4ƒøP#¸_ >W„ªÅk^Vœbq=¤™:z̃” gë́J×$m€₫ˆ²ŒuJvÛÉ™‘˜Ôaʦ8V`¹ éÙô)¿² 4©ÉéúI/CÀïĂæB`)3zcO° Ú†§*íkÒ'₫´"Ù°)₫†Q°È÷MCNŒÈÆ*Û”Û^F-ÛÄƯŸ ¨‰{ƯöZ½²!3J½Wé ˜Ù¯Qùo´_×íV]ú[Ù'W*µÅơ÷0TÉÉ6ÄùéQIMÆđ|MÆœJ¿XHLø™×A#k¢l­îhµË|€º₫ ®ÈÆ-¼7¼Ód’ÚÅÅœ9ÊêKƯ+ IÑfå9‹öhk+Ÿ¤R‹›Ă41̃'R»œ]…€'Ÿ²;—±I™íÂóî̉–y@A[_njbô>…{6§˜ÇJªZ©À†.ëç·₫W!TĂIî‡k,·î”—ÔưUD*5ñđ%ßë•‘Ëa ÜA_ơNú°ù‰º°ßă%:o‰ó`-Đ÷3W¬¼áÚˆ̣tN€~^Új̃ă±3=7«5eø¹µ¢³m¨Èü^Ï´ù>-ËK98̉”w¡đ[}ià3}cuVÚ“ bT× ÎÑ‘€â-rñ¡ß̃7ÑÑ’Ûơ¨;¤VY/÷°7¿ˆÆC™E€IĂ,¥ÄiƒÙ×E›kM9§Y«C‡«D¥FMv¢…û5{탰««·U¿˜œƒŒ¯qƯ[g~¯—̉îëéđ”“âüRço=ÙñäÚn^Kç(8¬ˆ¡¶dœæ¼Há·# ©đ°ªút`¿¸¿™A!ˆÚÆJW};ôvA?£>ë±Ûḳ/ »”1½7_́D܉BÑSà´áùË 4ơªw’È”ÖóPŸ§Ưú³uíỌ̈ByƒMI©]­TJ ø'́i DŦơ0£¨Ö ååic_SVá#LáÍÑHrK›MĂÓ[M™‘6?<ĐÙ‚/ĩE¤̃Ă®1é6@GSÉátœŸcB»AÿÔyreæÁÀ×»yûKá«¢SáÏ“ów\‡I0„¨¶ƒ«´LC>…U"'xüUˆvü>| Ïuî¶øF±)Êó;:&Àÿêd „9/nsÁóÈư|Çnz‚ Ï@3Â() ¿ÇÎ"7̃˜±çÁSù’Iú]³stE=4ă¯%¼ùÈ›$C¢Ơ¦GihùO%½MÅS½abL³öA›m9"Ă>‰uèä^ùăÙơaV#ÀŸc.CÈ~M·E!¯]᡺: FÈFFˆËY ‡Cmßóç½æ"u|_—R‡+)¸äUl·f0»g²«̃‰à#]—ϧ ©´acdÛ¾»1G†ÄW£Ùn·Öú̉…©NYTñCŔ Gj…Êz ómÜW]…ÏU đ^˜)¢çÈsø!̀~đ·Ÿ§Êk3Ö})¼ßuf=ØöL$}m›íR×FŒ¦¼+đ€—àÇŸˆTdCß뉧ç#i¬mˆN}§X¶ç¶̃y“f„«̉êđo´àv_ü°2”…sƒ́$e2 .2~ơÿ½dăÜZlµ&º Aï€Å½ÁtpYPÑ}O¸D¼1z–BLñLåÄĐWµèmÿ:5®Ü7 "îѸ¿Z<«‡)ÊẠ×å:#…Öe“1’̀S'CÖ·Xỉ@;œêy°»¬³Kw̃‘Ó¤«R̀„MưJD±zØ}}fx÷zGêá8ÉS߯ü Sf%& ̉ir鈤Èg’P)eêX¥â·óTRV¦3œ̣q•‚Ôà~pÏpɇϩûPŸ„i/…í̀›B;ô´̀S‰lÜ,ßÓ¼Èc3WRüô–UJúlµ]₫˜Ü"ké{œê@Úû;¾of`Ÿ;WÙí/møØÙ¸₫i×Ç1‰–. XZ–¹ëí)«Eơ·}ühºjT`¯¸ôîrñoJ9ozÚ<¥¯…+K¯›µù-´NÔ.´’ø¸«·®Ü ­[Á".ṬêåÎ}TLb́vư|̣"“J+›[OV¸ “ëïwÓ9/> Œ àCó¨k‡Sđó' É×àlCMù?‡[k´=rç!¡'•|ÂÖ¶~g}ØÖ$xÀØ´ cCæ”̃Μç+˜nËDùA¾ï²u%ơ²™!̉<ơcŸ!¾­p‡Éî,— C`öQm—ï’·¹f€uáUç‘N o¥5‹l³r™ÓA ük…)¢0„·?ÂÉçïư-x=EöE5³ÿâơEaƒ̣ÈÍ3Ux5ÔôøEúµ!;·Ư¡¥{ñÈë¥|A#Ø1D؃ӟ0“–|†î«ëºíe×kgæ$%e÷WÛ^YQ”BXóN(B¤µ¢âî1w˜@ù)B‰iÇ43öw+Y5,Ămđ J.ô¦”éêÑÍ Rù/º»LhqäChùfk~s?/*¢Ö”_¶¢SOe_å\¸öœ™ ¼¥?ƒĂM-ái„^qèæqZ®÷M†ö/ĐÉÂï8¬÷.ï¢2}:£¢ú#¶Y^Pp^¸—¡o—öë£B§^ _ú«3p%Y…9ØFQ^t-ơRC hĂÈ S ¦½5éçw.‚Ă³₫» <*uÓ‚Ç÷ Ür§V;ê[¡Ím kI¤¾Ó5ù ¹ùydŸƠªU¯ư9Ÿ »Êî\ƒP!n"!Ä¿èÚ87ó ß»IP ÖÊD¯éˆXYA¡KiYhÉØdt!¥8ê7.\=BÓEEđƠ´=8,`Aœ×(ƈ‚/%Xï'.8µ‡9{á@C•aöذ0€ƯeVV·ơÊ"kw;α„>'¨æ£/$Kª‡øü^OtÖéKç¢ùØiå™a‡ëƒæÏ%oøĂ„œ!ÅŒJǵôw'[öá΅,ÏOÏÈsđv2+M¼Wc&¶a¯̀5̉̀î0~–Âj¸@¬1F,Đ¿YêF3&÷mÍs9~ă‹"ñ°̣ƒ3<Ó&ƠêÜáÀ<­°¡4|º È.­eñị̂́,:é‚V0öz̀µ7»2‹_BbOÔ’Đ7.C%ÈZÜ>-.ŒÇî0'r$·\;*8|£oû{a_5±i™}BA ălïFJ¡³£ MBü1h3I* q|¡#ưXªœn¾6ÂQ́ Q³Éø₫ê"Xºef9óÎzöµÂÇÀ Î[K:Ô*ËêƯeàøó+ôâkí̃åù8'lñ~vçÿI•œXY¯èe#üiªí0(4´Ë¬¦Eû‚Oøù¹xàw¡tëËcL Æ9Ü̃I?MŸjE¶™ôµ2ơWDiÑU‚r¥¯Lx(>•·#„]Ÿ«'„§Ư7damË)Öñd¿¿Û‘™¢U¹W¿×ƒ"NÊ-¤§ˆsq&^+2¯˜‘äâz ĂÑî©tX±†˜Yä́ç;UK›́?©çy jKÓæjÜÜ"fT2ÜN [3RWD¹Ø)¿Đ½üéá2@©Ê^̉ V³ È´ÀËelă­ˆ`$”áQŸq‚¶†<&Pùk¢ó>Ơ&¼ ,¼ªgÆUª 2¡¥ï{*ûpÀ(»¥¦n`F̀-Ôid¾}ßÀD¶¶…ơ ¡˜}#…jđÚ,©llvôXˆ1z¿ĂƒÚIÖà¤gkeSwÔ,₫'Œ¦†ÁDñöÛ%–XƠÉü‡â=‘'èiVz¿³•ù'“ă2°‘Wb₫åQR`Û±uü<7ù (íÚ”-P,„NQ{'ÁAcU(ôÑ&WírÏ.lĂ] q ₫Ưú›PA¸dÙ×ú=zꬅoûT±*g7—¨•â-`¬Àÿ¶³(Êü ‹1„Ê»;•₫d̃l^éÈÄæ¬… <̀'m~”{óÜ8©q‹[eǿÔ@̀âÈêó!îàáåc^4ú÷;D¥r•‚x¡‹‚”Jâ"£WA3#¼‚PÄØë¥2Đa¬Ụ̀T…%b—ÿ:>ï q́ˆ#…wÖ‡J¡(³ª¼¤.ÊP™Ó…@WÓg?µæBƠ©#B1́wcl7[:QUÍ'˜aa ÑJ-¤: ×?è,H8~ê†| ₫ ‹̃Gơ±ÁØ~huÖŒ/º÷Cc¯„đµ‘vQ£j7Ơƒ\ÿp¤‡DưàéQ%&ǜ̀~µ€ÜèO+6ÓKsƯ˜bÛZ4ọ́R ßàûƠP\! endstream endobj 1720 0 obj << /Length1 1398 /Length2 5888 /Length3 0 /Length 6843 /Filter /FlateDecode >> stream xÚwT“ë²6‚´ RD¤JD`ÓIh"½÷^U@I€P’„ ½)½7é*½ƒ(U@”ªt"EEéEàuŸsöùÿµî]Y+ygæ™öÎ3ßúÂ}ĂĐDH †²ƒ«£8!°0H¨¢§§A 1aHÀÍmÀ¹ÀÿÖ¸Íá,…”₫„ Átª¨‡BµƯ]€`1 XR|K‚@·ÿ¢0̉@UˆÔj£p,€[…öÆ q„<¼P> øöí[‚¿ÜJ®p  Aơ 8G¸+!#â4AApœ÷?BđÊ:âphiOOOaˆ+V…qçz"p@c8ñ€Ă€ç-ơ!®đ?­ ¸¦́oƒ Êç ÁÀ…  Gb .îH$dhé Đpäo°îo€ đÏåÁÂà…ûă}üå BQ®h̉tÚ#\à@u]aœNAÂÎ,àñ€ \ vÀ¯̉!@u%# „ĐáŸ₫°P Ă c.ç=œ‡!\³¦‚ru…#qXÀy}ª J¸wo‘?ĂuF¢<‘>Kö$̀₫¼ ˜;ZÄ ‰ps‡k©₫ÁT€ëà8 Hê–˜”î„{AEΘz£á¿Œàs5¡?4 ´'´÷CØĂ ?,ÄÄaÜá~>ÿiø§ƒ0´ƒ; €G'¨áö¿eÂü1/ %ˆ@?0t₫ù×ÉÀ0 éâưoø¯‹¨˜ikê« üiù_Fee”ĐGHL($*‚AâRÀ[„ƒß?ăBêø_-¤= x́¼^ÂEư]³Çđ₫Ù>à?ƒé£Ô…yÿÍt+JøÿŸù₫ËåÿGóó(ÿ+Óÿ»"uw—_ṽ߀ÿÇqE¸xÿA¨ë#¬° Èÿ†ZÀﮆpwưo«BX%¤̉B`qaøo=«đ‚Ă 8¨ăoÚüÖ›/œ  7Daç‚ô_6–A ,›¿M,aåp¿y.Ă KơÏ:ÔṔ|ûD%$ â Ÿ I}À„5…Á½~±("ŒDá.@BÏ~@{p>h ) 0́\øGl¨;CH₫‹„ÄË¿Ö÷‚Că(¨L°SupËA¥«§Đ̣ ,éfêÁQ¡Á‚û¸.µa›…x“¬̀Igê`ơûNmúÊnÙ³¶}–j8j½Å÷„8ÔW8́bÇÏö.Œ&ǿ³qÓ4=±HV¾.]Œé"2d¢m§T€9t™pÓø₫UƯñ1Á“‡¡Dư–vH‹~k{eI¦.#Ûmó/ŸŒqMv½¦Ë;Lå|r}´m‘¢ŸÎ©#Ûzˆ÷¬ ïéë¦ëd¨íñpù;W(NM¦—MUœ¼Â|:ị̈Ïœbtz;+°®çs|ÉƠú[K[Ö7xÛo9Ú&ÚGƒ¿àÙéĐÓ Ê©˜Üü•HØTvIC|Â>Ö¼# ¡ùz¶́»³vXˆ÷ähÇĐüOw-ËwƯÁ¼‚zñr§¥K_üê¸_Æx؇7ÿU™L·¤&À˜É·îg”×Íå’5½Ç2j!j)•êØb*_4};¸9à˜µ"µǗ²HƯç̣»{>xñÓ¼íÖVeI·(d }4~¾fÚ7½àÉÑ&XäM-4­*Zï麰ç[áµ`­Ûă*ô+Ă·¸J|ÿ@÷(% äÈ~º̃Ă$ÜÁY6µØ¾{½”8FT¢Ÿûüh'ñm7ª…H àQ}´?Ù Nêеx̉g†Wè‡Û${̣º¨ˆå'Ï~È7§h‹»*NŒÅêÇ›øz}Ẓ›—èoÓ-„ Ü—ßé%.(̉8ú ]™â}DưÁ¨7h-₫qt‹̉üNSNßHëè×K-%r·Ÿ~ÎÜØs`eÙΔ»̀aÙjĂqfw†²¹ú]™Í¼`î¨ûa?yư–'ÇWfâ¥ú¬Œ×ó­5Ô=u¬A_pb÷&Lt«É3ZÿEÙˆ¦ü®ªßîw©¬¸®»I—[¾ÖVî•9”\&kÛµ6ej?ƒøÚ¶:ÆÛ=à{åy7hjÉrJü^}‡è–÷àJª#³ICHé?zô©Đđºưø} äxÜĐÅê"7_Û^EoÏ·±ÛÄÀ+jø‰ñ¾ÉqIá†Û|z̉2”CMÍaÅ̃=~́œ+x?Ú.>ư;¾¿‰BƠ"n£L¶¸~…”~ú¸{đ¼)04I7ræ‹E]µh•©zœù<‚¤ƠK¾Ï₫ƒfÍ‘%‡µ©Ú̃+§tẵHcª¥%Æu`z*팋Ô₫Ît<ºz''#Kó†ù₫t ¬₫F}€ Lécgúr Å,ôÓ×Ü2ŸƯá đöv@߬ۋ}EóGûßêæä¯L.Ơæ~́E}3öLY„]Ï€7mD¶(#WÙÙ^11zm¼́œ†[™¼“Ồy+`Ë 8ƒk1W’ḤÚ`ô8"p!°€€ ™gú¡¢ÖPdaO|ûLn“ư-&í…‡÷T…ă}₫W:U¾V;ïFx^©cÑÛÈä¯ëŒôđ~Vx»èZe§$¤¥–î2üîZº_,‰äSQ? Đ7óJÆÁÑäS"Å’í₫ư -gåøđîS—ọñ³wÖe?ĩ©́¾èåAỵ̈_À’ºWg†Ă ̃:¼³ª‘±N¦¦ç̣SAcg–3Ơ’>óxÙ™øaÚÎ\Íô™“†­Ăp˜Ñ³ªjJ̃¢Ï2ư•FÔfÁ*h»Ơ·2*D·ák<ê–¼Q€¼Ÿ!‡±‡E ƒL1¢È¯©-Í6;å!ätĂö³ï‰KrJÜA3ûq1Î"ñå<»—̃ —Ö}¤ ¬Ó½k~ï™Ưñ;Ù– ÷'FyµQçê€êwºÚuc[ëôÄ™¥Tîe,ơÂ\L5Ùz‘ç̃p³îØ¥‹Ó™‘¨1A_k`…uÚ̉ +¾)pF¿œ'‰%Qc̀ ¬X*,r›X¦gHëÂú;u|"WQk€ÙGb—ö’^nó¹́”̃€jO¿ª‡"5üÜGSvIÎ ?ïVy£¼̃×;•Kñʯ6y™Jbå]LJ¼¦Đœm¾úP»ùú!™G/«3$$×’?=`ŸZ@Ỵ̈Á^‹Æ̉YXQl„»åÇÓrÚ·gåơ¼¤mVB÷nD3_Ï̃Đîḥ±aŒöbëØ$ọ̈˜2Ùéú‰ÈJ8ÓaÚ—3̣̀38½Å(ñ3ü&«t̉Á<3F]C…¸º¾kú*å+&z{cˆÍ1êIù¤ËtƯïöĂ—/-ÿăÿàtÓ¢#Ku]j5kkÄw+ûFƒzä\ß@dă)ËÚ¤n‚ŒÍ̀(Y[‹«¾9¹ăn/ïG&FWc·Ơ+ûùÚ–Lñ₫öă´$·“ŸKÖ|ºf>Êñ÷R½ØxÊf"Hª~¬DAµ=®4Ú5çíÂûpQ÷BÓ;Ü‹\’M³Xúo_V)Û™Ÿ»*ó3Ç2ÜRk".´0pLMS©¹†^aº Ñ$»ÎIa…/8yM+2Z¹@Á¨*•a+s^©­‡ÙmF ª”»mwđ„ܹ²¡•ŸÑ=zó̉jª₫ơĂ7gŸá([ø…f ́ZáË»Ṇ̃Lû1•Á«dUOÇ›,H÷Đ¡£ÛÎdyAƒ½J¹´¼ÖzK̀èh(iö¦cï– $U¹̀¼{ï-ǶSr/¡ÈŒç:}Øư: êw6‰D?~©ôرƒ¥ ynKªư6áÔ9ª¥i@CÍq”gUájP0ÿÊ|9«mRÖ¢âí¨©(+EƯˆiµ1ê ¾­â/₫Wûf2¡BjC,Ë! ¨¦vŸfÚ$–*Ú~¾Ml•₫EÇËM¬£p₫ ®˜½,c-ö½ïÅîpP₫€ÜZœbEs¢đ¦èưyLM¡t/»¦|)|ủp`¦fT¦bÿcχ'Á~®™kB?êô”ñX[¬_lvôÄI¶Q‘Á&Û"Bœ’½¨̃Lc¯öúyË·¨YG+ [» {ëRé \¼³[½÷ÍÄ®T¸¥×în.n«r>?óh‹jÜu:¥#QHÍ9îWbiX‘.ÁJ·Z÷°Êh–‡¼¬Vpi«­†2Đ/îïÜ€SäO­ áÀ>°ˆôÄÙɆ&%LŸ8‹,û̀‘­ %¢2s¯?~ÛM²ø¥PJƒ›.=Ø̣f£»Aï‡ôḤ̉ä5Ô$`ƒUâÆ³ǿfPRä§IÅÉơ₫Kª”#7¥d.=x²U{¶½Ès½RÎAå{^\màŒÂáêÆ<¹LŒuB ÆŸđO3¡"B÷“ªc{URåé- ‡GM©‡oX¥i•ånsí’ÿèÙ`âÊàoŒÛ=êuÄĐ́̃¢ä€—ʬö_¶è.ùïkœ‚ÔR)‰ fÁKơ…1^ˆÊHógn—â+'–Ñ£?;è_đô¶·ÊœÆº¹~;UÈ₫X¨S´'ă³»kÚ$₫6´=çơăbư¼ÍQÚy²VçùNؼ×+-G5¹ âđBëxk Đ4¾Ưºù›ÖĂă¯¢3̀å7© Ă.¦®wYRV¦Æâ¡î'̃MfÆÎó$±„7’º¾ÖçoÛBƒ}[îæ¿́â]ĂÏ­»úx¼|Ô¡ăÏø‘¥%RM«`‰§²‘Á9Î ed­‹³sדª—n¦1_:˜ùZÍrDÉ ‡·<ûƾ›wú=¨:¥É)ÊC*„¤̉Ùô¯Œ°[Ü»!ç®¶m´–˜BÁ»¡*+SăTÙÙ×p47¡µ|(e`Ï«Ÿ;VªuƠHx«ỏ íưÙüC/:³xkLåÑ}åÜ…¨ƠJ¹ĹṃC¦‹[¯¨ơL[>œ5Kg5TĂ₫E¡x ÑÿAu?&uë2ĂU:[C“39™3µĂÖŒ íˆ|Œ—(%—å‡h¯q´X+ÑÆ§»fOJƯ‚Hëø‰ms1À§ûJTe fRƯ=]¨X~4öÛ!µZá‹s±"̉H`{@Æ8.™!êư.´‚1x¢̃ïú‹Uµ:æ¦A7ŸK±,Dg'¡Ơ¤[=û²²‡Ơ ôT 9¥rZ»kÅÚ=¶ßß$̃á3öÚœ_‹%éô¢”t,¹IѬªÉ¼3ê%†Öù¿jbÔ.¼´Ú¸X(ív‘±»×Ñ[g¦öT]FöîYÎûŸ₫¾[Ïæ(Gé®́˜`ÚN8*6•:íÖ[ẓk—\J¹]đ; tˆ?ös‚ª¡¾¸UừÖ‚ÚÍÆÈáư$Îơç›39;ñ&¹G¾ÚT|g;VYÉü‡=̀Teùú“7­ 2N ¾%½ø_úivMă}Ư«R¢†tS®U-½½ï(¢t)Fq=vßʆ¶›9r¶’,Ư¤Ä¤q8ê+ƒRÎ}×y«d²v‡I™9M‹9Lá×eä¨3.jL=x€—¢½e‚Aó„VsE8ï.½U\¤¨+J‚è„¿N¾Æp³¯î{œºcWñézƠ%œn˜ÔP(¥/Ü÷ƯÈz«Áu¾9·÷Ë´êI8Êdƒâ|9¯êÂæ.̉¨IêE6+]rg ´')Ă·—C•ü˜XQ-xß§”ó²‰~ơÜŒôÅăö¹'’aNÊ“‹R ! ÁŸ—UI_ÄűY>ÚñVMœh#wµ(²¹o9Köơä£Ó²§)ë@@ ¾ńK!aí,S4§X¯’"Ï·â˯ŒŸF‘…·'£Döă†X¨¼¨’¶wùoƠoj¾³90’Ưa{` ‚L/ÔL9I¤Àî`’5UÁœ-Đ·–Ư¼‡e{®/xQÉíez„_ü©ñÁ¯̣nÓ7<4mt§â‚ø‡«ùøo©nẓ¢…CÔÓ §˜A9‘*6°º©Ÿơ±'sÅ&ÜlxE•ê+T Ơ¥½¼Skz‘.ç̃¿—8óŒU÷ˆ%ôÖha™†À½ö₫å誹ȶu¹F ~@Ó[Ï¥ü„Å̃LïnsIz-Åqµ£ºëe££öqCÑ«\¶<^§˜3»e~F9_\4« t8Dßriج¬}‹•5oö$*í'î?áàçx¬Î´•"T̉1UsH÷’ê-œ~^+%¡U{pÜÇÓÁđđ#YwqÁÁƯ&aPíŒĐØâ¤‰­Ê%¢‡·Üà¦éŒÅ²v…Th4®ºav¸gja`Ê6ü]\ØÀ‹Ë+̃ë3ƯGw™sKû¤t4l¾jn£vđEAßú̉=d-[StjZÚ~›^ôüüëfZÚêøP3¹¾¥›À#mq7²³%-¸èđ¬ N&F¬CA­x,6fơÍD_ZêI>ă_׿(̀fù–Fí¸‡'QÑ ©«̣‘’Ô‹=₫|©”ñ€çO{îxJ¼á́_đuN+á…3s‰0Íj?oƠ jœO¸̃³û*› ¤·‹ºéˆ2]ăîÜZ¾ dœË+_È?xD9\̣¥WT"ܱeu³ÙWKXÂư•­‘a₫₫øC>ÛOSŒŒzê×x’ï‹'H0%ƠÜ/ ~È 7W g§Đà·Uxk¬®WB=ßp:6à°øhƯn?9GŒ$9%j•èÓÀJ â¾êtnĐ[ê¼Ư(k•Ûë¹:ÿbï“\»a±1Œ=R»Zß­Ơ´)y x¬eú+,ætĐ;c"́[ÂÍd4¢iå̀ê˜mÍäÂ35÷D½cFºé5­AÁ×Í̃Hª̉%DQtD!Ü|Ää ¦Å =¯„“̃NƯ”#¶×0z₫#é°qЦ¨ơ-/̃/ÍâhªrC©~6á‹́ÙØ~;ÙƯG5ÖºF¡ M₫ƒz¯IåáÂB“¨g#WOU˜Ë™i.&?épé£Ứ²̣g6¸ÊåÑJV-L›t£8ơ<\Ï]…p„_ú¬ªÄ¬̣ó•ăsË‚&,yºxÂÚÏVFº —Gơ°·Í¼/ »Ö9X¸Ñă’hî%¶kớ̉·®…̀Î?R+‹’3y‰ô¾†đô5Ö;ºªÂ)Ëày‹¨û0\æA®ïă³Á=)d½˜-”*ÓD/ŒRd›L×}T1è¯Î6‚₫ăSÊĨ"w¯¯ËÉV$Aí²–v–¬3ô/äQQ‹…§¼‹âº |æ½ • §åŸ\£û8̉¢AöÁ+}÷h³¤Å®ôPnƠ¹ç[²|2}u^c(hÅà>¡Hư\ÄI-u¯fïf[`¸9–Ç£x«úăUCαwÅ6z5tz0#K̃ÅiÖ²¹–Ñ÷x̀¯ơ0¸×H’“ä3·ú…æÑ8M¤xmL}³ù±Gv endstream endobj 1722 0 obj << /Length1 1398 /Length2 5888 /Length3 0 /Length 6843 /Filter /FlateDecode >> stream xÚuTÓưû6("LAB¥a”̉0º¤$¤[’±ml£AºD@º;%¤„$DAB:Dº‘₫3ßó~ï{Îû³}?÷}Ươ¹¯ë;NV=C~E(Ú¦FáøAB̉ÀûÚÚê a ˆ€0€“Ó‰³‡ưmp>„a°H4Jú!îc``̃¦ ÆáÚhPĂÙ‚Ä¥ẢBB@a!!©¿hŒ4Ṕ‚„µ€h à¼vtÇ á¾Îß@.7$%%Á÷+¨èĂ !`PŒCÀđ!`{ !‚„áÜÿ•‚KĂ9J ººº €°h \›èÄ!€0, ăƒ Ô;À₫Œ&à!ØßC´-ÎŒñ{$†ÂâCœQPˆ¯4T×ê:ÂP¿ÁZ¿|À?— €₫“îOôÏDHÔ¯`0‚vp£Ü‘(8Điêªj àÜp|@0 ú¶Ç¢ññ`0̉lƒüj TUÔ‚ñ₫™ Á qX,̉₫猂?Óà¯Y½vp€¡pXÀÏ₫”‘ïî‚–û…vEy₫}²E¢ ¶?Ç€:; £NÎ0uå?¼ đ ĂÅ„$%D$Å0' ̀ ‚üYÀÈƯöË úiÆÏàíéˆvÚâÇ€y#maø€'́â0Î0oÏÿíø÷ ¡Hhƒ#Q€²ăÍ0Ûßgü₫1H7 ¹~  ĐÏÏ,ñ ƒ¢QöîÿÀ­XPMOQÇÈ”÷ÏÈÿq*)¡Ư€ü" ¿°˜$$,”À?xÿ;ù§¡bƠQ¶h|Äï~ñơwÏ.HÀơG!ÜÀ'ÓAă© rưĂt !1!₫ ôÿÍ÷_!ÿ7ỵ̈̀ÿdúw¤êloÿËÏơđøÁH{÷?í›x,"Ö ™˜ù™-₫̀*;­jàÛ\?̉3Hs4~e¶gÁ₫Zkÿ®4v/DiÑÏÓ†ávI¯ fü&Y°ếwT<®¡kGơj DY·Œ¼½¤æ icäàx¬ Gë_í + €Æ¦êmư1đ–Çg‹êjà 0•ư“®DÜxQÁé™t_‰Ä¬TÜƠ¸ø8¹­(/A«ZùØ(iFÚ5’,]è÷¥µ= 'Åu%÷å/ Ë&5 ƒưd¶³ ·®UyôăŸ6÷·÷F¯O–l 2:T µ-_̣£®ÏÈë¤ë¡ÍÜ›Ô 7¿Ç"ªBªƠPpgít<¼xGBüÖ¹½óe®RïI¦GĐ•n¾l“³x%lÎ_ḷ¨q© Ơ‡_ëYoơ›Öz.±ZÁ½Ê\f@₫n"1”åïb+;²4I—jæ!#Ó] .¥te& Ú<°°…€Ù2?Ä‹B¬\éI¤Tj°À#•Æëư$ă>å— 7 4U[¿Ü\Ư¦RO”iƒÍŒ%ÈæZz‰¿ZT9uçª+è^®Br«4)O†=•_ôñ?Ÿ¤•LfÔ¢æ›]ôªc¿#U˜F ˜ƯÙfˆ™è}‹d€ó?ắ÷–ôñfµ|ª/s/s¬ƠU{@RØcsË+aÆU:¹•hû;®’¼®‰\•,iX ŒĐŔR’l%ªux1dûä"í%q‘Mê’†ư|á“KYfØfÊ$£eí“7ºQÉk.a+;zËÊ ñêTLù‰ư;„ÆÓă’ß®Q±đV·z<à́Dô,2¶NÙ|¸ÉNóƠès=¼:l4ö`Pxo-W™©übÂ.—;œhøæi÷+»>ú ?ɅŶƠÎSp.—‚wn•C̉e`aßP³èÀJÉ^!M$´S£Í|{º¿Ø1‡§K‘ ‡‘ügă ƯÇwY2³\ Đ=ù¦ï̀€|…Ç0³Be›¬éư˜µ©€= £~BFǤY œ0GF·¤¾B̀ÑŸÇ̃ÖÅ–LUTÁ}N^4\aAT|ƠÈ́å~̀üÊ“4¥0í¨l©3ôĐ—ñN©é‘ Íníï¦]/a& ,Åå^/+“z`[,ï;©®ˆ–̃_`Dyé²…]søôp¥'µJùú„⻌“Uf²ƯÜĂÔ‚)©Æ±¿‰ü'»oíP•ñ^&!®–Ă`#̃qÙNOMUyI‘+PNqÅÉúÇa­hNî23µAÔÙg÷cß­Û]ë£'ơ>)Á̉§:¬MúñsÍ£c`ØD%³LuŒˆ%KàÚ:ƒZ$n₫‰₫Dđ ‰N³Ø=ó¡^Ç$céUßEƒ× ^q›ºí6Æ]Ÿ̃÷½æ¥üï9k-ï!ú ›>i²V´@‹ÂÛ’ ¿˜ôUŸ9](Wơ‰„ÄRÓ(o’|@"Δ¿‘ïèùí9KË̀¼kî7×¾́LƒË8Ơ>×đa<“Pb9^{̃ÔT³s®çé^Å  VWs[í1ÍM£‹MöƯÜØ½|‡¨:́Çä`Î @n]êz”(¤Î8¯"u¡ƯɃî:˜L7HkÛĐ1WÎ^V¡¥÷™aó’X ¼BÖ¼eÙØ3ňè¿Đ’Sº(âT:U‡§O™>y“²Èçi0Bê†Ú OEg½K×ÉTÍSÑ$ù<î« .á~‘ºuséè©%UcíñƒœÀƯ…1UѵÎú½âï_ˆ® tâ J,j‹ Û]Íđä⃒µ·ópÿ»ƒ7–j]¨@ªöb©pTÖEÍFN_çtà$ß`Đ ø̃gëa‚•ưI¹´̣Ö ÷ă7r×0—oˆÜ¸eÁaÑA›5̉ÓYyP£±Aä}) ~ĂiîªÂĂw6ésÏÔÑÜ|_+Ôç3„<’||/Zư.Ïô ‰!3ÆÉÁºt‡d#̀d=Î?ÜpKTXXă-¿¶́G5ªLº7vÊp©*rPéÙ©™˜èN«¶Yñ² ┪ůªjvONF)÷̉_çpù!*&|UÓûÍïa\à¢[QV oÏ„âEú\ñØÁxAœ‘ÎGrUvƒöúB=t+bÅ­ƒ…·ÁHÜv¢ÄDưfưhc_,!B©ï¢«ÍÿƠíß=»eê>Đd«j?ó…ñ¹nW˜É»\¢–ZéưñKk¨’"ˆ¬°gÊ%±w ơf[0Ûơ^ň®|µSu_? (Â51ÿzkEƒÏôW×÷ùêa|f ´m-‹8Rè JÚ´¥„ÍÆR3Ă¡üĂà́DØö€̣Éøb¥[.êÓØÊ–£E?h‹koA€Xc\²̣fVẠ̊¢Ë^đ,ÆæîZtm^q¥MY´‘{¬ç±¨|#—̣Ü̃ $ëÇø ƒâ*ˆœß­½SR3èa¹Ư20OûÆh£ă{n7°}ØñéѨç†ÙD$Áq$‹ŸôƯ)âÔ‚£²ñ;G/̣ï9 ŒǼRÚ»^Êóè́ ½ÿ*öá„}<¿9̃ë[f¿sL«Â^`-iw§mf—Ù,'<@̃àÑ{Ô ñô+́‘»ßVùvạ̊ÔFÉ,(Å*Cd¬gƯ),¨¥V¤cWÛö¶ 8>ọ̈Sö) ïGÆp`V¶O*ç>&%Oímotí g_ra:#¶2µÏ"Æ—̣ê 9æß7ø̣c¼¸K‚µT¿“Ü£Á»qaé÷ ^à<­kè%ˆu“mߤ5ĂzëŒCvè ƠMNŸ êa€úèá¿À ny@‘çÂêØ ±í>—=³{¸đ†râĂ›Á ¡­ i¸P·½èJ«6F[ëüÂZöºƠ«b&ÛWU=ÑÔ“§BÍ}k--_»=ä .úHÖF´ÉüŒ,`ZzWM<€Y¿wöܵuØDxè†Ù=@5̀3’6S”Sèqvd S“K…°¾éOèÅ3#|íè’VH^ñ–«.­kk]PêwG“Á̀@ëjêàˆ@I Ùï«Öü:Åörg½áù /®,ßOx˜ˆÖÊ×éÓM«́øx™ó1A@Đ»ó8Ơœ§3GvcÑ‹V;:4{‹ÀfÛ×yÄHœpúQ=ÈVÅ©ºÛ\ñmÄY„ peMÑĐ2Ø48#̣¸¢d6­°c-6R̀ơ˜*₫¾Çû‘RŸ%i§sƠ‰G«<,ÏLÁ/́jƒ̣Qê ñ–&Ơ°.ẰB?vFÖ5‰¼l± ¾ö>‰WKÁä'ÛbV[¬ù„Ó÷ëIK_ic‹aĂ9 ºÚ,Jh¥~±û$Æă×ëÚ3^Ă•ë¡ÈÜßhÖ§’}ĐáÖ¦¿»À¬¼·R§Y(ª÷3qüâ]LaƠ¢Ø0:äw²“‘R]@g —Dº‰Å­37AZ‡hx*ëlƯ?¿TÊÏ ́"Q\]”|!¢hΖ·‹kAø̉ĂßM$æÍ÷ºå€C$Qä>”ùÓAâ%ö~¯bv®sñ#¿>¦„bR_ººçùÅ7T̀¿xùEǾ§6 tk@Ôˆ½1:cèm$i¤9M”ưªU}íÖ-„ëù@Ù3·§̣?ØôÔnꦨx¹{¼Đ́WÊ8M ̉ßäHŒ4›ơ,ØØë ¾CY<V('®^—uÄ}±ªgw2™±¾Ml¦TÏí¯Ä>Æ8Ñÿ–=zÏêǦô]0ˆlûFÚ’ZR)…₫Ư-̣ég”ÈB(V½6‰nó₫e›-ă1¥ÜN₫›¸LØ{c#‚°lc₫ñ^®Ëö ŸoÓg„e¼Ơ®~ÄĐ™;Ødº<Ü©₫fép/#°œy=Î܇Kr₫ɤe¾#âc¤MZ€_̉)Gb‰NrZâxÅỶr@zNMÆ_“„LØơ€̉*»o\¾/i‘Pa T+L,¯ióªN—Uuz6‘~ ‚́,×›X_·*ÛYU÷-\&,ÚøX9u{Ơ‹ä˜Œ½YtÍađ)¶­L|“‰@!ÚÖv3Ă~¿4¦Y];Ó-²=×TLÖÚ¿ È­~)×&{%Äm}Ü„4d³¢Tsµ Œ®¼„´đ*̣®Ë¶‘A·’§ç[‚B=ǯ$£Ú AOÚÉNŒ›wew\r¾m_v?ÙÂ=̀ØđyyUà?3ỏ$çÏjâHî¬ÍIö 6°#Úd°4d–]+Ö$˜„Ù?R}O°¼óе`;åÍë  ñÔ“NïĐp)},ƒ́¸…ÊÁóÓUăG—ö߃N£i£¤ßN3ơêT–—­WŒ$è]5˜Yjçc¥¶ĂiójØ|ahZ—蟅«Â9 l핯ô¿̃H&n&Hó }ó âMx“ÀơHzỵ̈Rk•Ú^i>çp?³Œ¨₫qÿu ̉Æy*~=‹£ó/íưUØåÑ»ĂÊ2_‡öRÁ•ÎÅ˘a‚üǴ́¬¶MûijßF‹6/OnK̀?}" Q ô·§|NÇeiG4í”OÙ¾ẠS¡UxtI^¶5fhÙ"ªs7’à‚“—*=«|öfJ AȸJ(́/BOrg h ³©5ñàÊ5ÉŒ®j̃„áá‰ÙÂÚîµI>Óí…ëeơÍ,¾ôå̃<¼60å)_¡¯aÚ›.ŸK/èÅv=ßPÉŒ›Xơ1,4§Â¸2zß3>o«…¥©$@‡*~°ÖKù7}2¡SxœPé8êĂ½‘´Ä5÷”Émh1Œ>mÇ«ÛÜ–›_̀g̣ºyÁ$îYÄ_ªóo(öhJ/ÂÚöȼÀ=«Ê¢€đ S ^¥»Y(×N6oY~ßqZ¤ßZñâ+"·à× ;"]PnÅ)µÜÖlÈÆP“÷Ö’I‹6ÿd‹Æjg¹¥âǼ`×̀œYß’Ä9ÈeÊñ³!¥å­1‘˜«‹¥7  ªÙ “xóơA?öPÅüU¥+øÙ‰§ùD˜v́/Gù¬¼ˆ?ß°?ƒ_¤jƒ_́œ¨µ×u++<§3¹ Ï•-'æ›2ᡟE/µÊŒªTDơ‰‘3mc* Ÿ&|T²-Hyt(uư³1½‘ ”6ö×븽Ñ~L©nY!Oí$ÁqÄ×¹ÁZñÉöû}năôgyá˜dùƠôjÓÍDLK~â«dâKô$ߘ¬œƯƯ™P×̀ +˜sX¾̀IÓ·LÉæ®|₫Øöó9¯û*Óëº_øµ‘¡t’¸tV5æ<êIç™l vÚ­‹ç „^3Ç}<5ï˲ïÂ¦Ï  m! +*Ú|i#y4̀´Ü~›RP×y'щË$đ́Ù1 ƒ€”-O÷À„‹·Ô.:5ßÛº%lMá’'Ä¥Ç9E' —ÏúBJW%ej¾ä;™Í C/‚(__‚‘xỚîŸÈtEĐo­¦«i´ơm’j¿z(‰ÊR·½°r‰}2×̣“éêùÀ&md›‚Eè/½dĂÿĂQ <ÖĂª/=ä&|ˆÂ¾kï xpímTëưX²ORcṆ̃Ơ"Ô|°è$“øÜ§kåÚë{‹´/¹:âÍuÖÖ›»n]^{¦›Â ¥=ĂTd~@Ư $1Ë™jRÅ)\u›.·8¶Qëk —kÉóÆÎÜË'¥*ESÛƯ#È\®W› Á”Ï{îôb™ê¸ ‡‡.4+ &±›ï6wójóë> stream xÚtT”ïö.‚€ C "0”„twHˆ„0  13C HKJ*¢€t§t#©tç )¥̉ñăœóÿ{׺wÍZß|{ïgïwïw?ÏÇÁ¢«Ï+g ·‚(Ăa(^> @AKKM ñ‚$P”#䯛„Ă‚@Bá0‰ÿP@@@(ŒO„Âà´à0€º«#@@ đPB@TâÿÂEÔ ÅP‡Ă H¸³'jk‡Âó¯W˜ ..úàw:@Î ‚€‚A0€eqœ9ôá`(åù\’v(”³?¿»»;È ÉGØJs?¸CQv€Ç$á±ü  r‚ü™Œ„``E₫ñëĂmPî €q8BÁ“á ³† ˜ĂújǵXóààïƯø₫]îoö¯BPØïd wrÁ<¡0[€ ÔĐQÖäCy @0ë_@#ɹ  + àwç €²œ„đïxH0êŒḄ!¡¿FäÿUsËJ0k¸“†B’üêO€€1×îÉÿg³0¸;̀ë¯a…YÛüÂÚƠ™ßuq…¨)₫…`\$ÿñÙBP ˜¨˜0â€x€íø•7đt†ü ürc&đñr†;l0C@| 6̀‰ä ®¯ÿø§E" °†‚Q+ˆ-F̣Ÿê7ÄæY>ê0b¸'₫úưûÍC/k8̀Ñó?đßûå×ƠSÓ4Påù3ñ¿c̣̣p€¯ 8€WPD1/>ÿ,£ ‚₫møŸ\5˜ “ñ§]̀=ư«e·¿ àú«nÀ?‹iĂ1´…¸₫Ăr3 ŒyüsưwÊÿ⿪ü¿X₫ß )»::₫sưÿaÔÑó/ĂZWFZpŒ`ÿ }ù£Z-ˆ5ÔƠé¿£j(F r0[ ›y„ù€ÂüP¤2Ôb­ Eí₫pæßđ—Ö¡0ˆ. ươqÁdÿĂ ́€ù€ 1Äü!1jCư^ă/‚ÑÓ?ûP‚áÖ¿„'(̣B @$˜Ơc,€—F¡ÖßÔđóÁà(L 3³À ùµf1¿3f7pë_~’Ô»"˜ĂSsđ¿́ß ‡@< `’é 8øQ}EPăI™ƒ;ïÚ$₫^̉‰± ïPö3"T—̉ˆÅrœ~zÚŒF̣t§€̣3ûmy—“Œ…Éï^èJæ*Oá#^få [f«˜‰ë#́±x¯cFÖ :¬¬' ̣L]Xºw#n¶ËXÛvésPxß«è˜wç¤ÎSUnÔnn-ËKÓ¤e7ÚYyŒª·ê5XùAw/sÅ):p5̉,,Q;…UC²ù”$νôæRO_ïeçƯ¶u·€µ}ö—(J¥G½ŒÂ„¥FsïÈ/2?¸m§PyY©Ü’Ư¶î*\äN8©Đ>´Cn›³Üwé̀¨¥ë$ÚÉÑT‰{‘’Ơ';[ö=Öl¢(¶@í!0Ô"ăåçQJ?`uú2§/X^HC  ƯƠ¢…#fư"½ú¿.o₫ ÆywU\ •–Ô@¼¼4äeÚŸvAµSe|µ[)\ç°ư™„ÛÀäÈÊ'F3wbqd¤N¨F}ơÖ ‰5,đ‹(É#¥N­Ul¤û`vk,mÂÑŒúH¶0Z¼€Ư»_0+>«Ê¬üN÷Ñù–@P¯ÖÙ'ooü­RWH̉Ͳh˜EÈ'B³ yߘĐkÈÈ’œë¶²jçéưºr±©’§¯Đñ‘ÆƠ³ù¡¥8Láo–ä6e7:ö¨=)îÖh“ÉÈrh™Ô§'§Ó0, ˜ó7’Í”øaơqúªƯ¶Q.å:¦›2*ÎíH°—º®%³Aï yÚoïE₫Vd+xÜÇEåG ¨¸ØI£vẽ ̣„lyEªØiû±s蒥Ƴ¹8D'änLv>ø9¨»«QPFF}îåB×̣ÚIĐ =­ó°®`‡̃bÑ[‚ÇÏ×UÔ|“ˆÔ(?LJ”²P=T¾êÆÜtM À)ơÓ0£y ‘y7{­°Küjéën¶¾¢ÀyzC•‰På™ĂfEÓg NC ·)úøÖvFÏ•‡Q‹Í¾Ư…ï±[¥¹å è¨=M°—¦Ưë Ô›N­ưè9ÚvyÖ®"̃V´Î`̀–ư#Ä,Z&¹§¤8E‹±èà…á}Ó冷QO› -çóV¢E\Ûǯê½È®X÷’{®•¾8ͪû7›̃Mƒ©¥S·gíơtÍÇ¡d ›ä(å±5†Ôđûë&twmáxÍ ²°ÎXß'+đJÉ£C ëdîÔßÜYç;±Æ¹m@F̣¸Í!7 w÷ÊyơÄ)Fy~£‰‚½ ïd!ø½$gdÜ–NZäÁXPéWÜØB•ªºLÆ·œSăy»:¹Dvjøü‚ûq†Ơcœ/I/}”D›÷`wÖ±c±ç’™$ôà;=¬X7ăŒâ·Ï\]›8“È%A±t|ă á—>;Ñ5m Qûçéă??-z’̉ă+}äRê*¼^pzmxÖ̀³œÓ̉Æ!ấxEÄVƯmÊ2ÓR§̉Ö5hỤ̈ăZªØÏ`Éæ—]Óêï0×îæåC8àBïXK“¿œw§­„äSP=ÑÍ£’6ÊBÍR–çOƒLV’Y°EnkD ê¨ØëízÀù>ºă¹rLIsđT–KXêë±ù i|O¾XI•z€&lC¸̣Ú·¡gêX́œOÊ‚́̀gÆ'[CíêC¦s& w›?a¯µI“ܧ üÖï WßEMå:û§₫&‹›đ4½‘ª9R#;Æ~ĂWºI8aFéæï öüJ×*Öíסsån§–cijË?UKûC¾Jn®ë¸;Ç.§½âÊÑ­û ×̃ñwă‰ga·Ë•Yº„w.¬$¨†{enj‰û+„–É£gnMÈ– ·7Æ6\*=*¸A˜Íkç•yâ_×cƒKÓŸG|öÂú#pú*GpiKÚ/pûIB6˾&ơ‡±…­gÆ7q1Ÿœ ¾•‘̀—Ç~¸z\Á”| ;âœ$.™Äµ2TÄÓX›¶él¦+Tkû6K ʉËÀظI…#üP7m\âÛô<«x.|~I "yèù` Ûϼ8…ă éè¶+G9̃,KN)ç1’‚…&DŒf }₫Â~p1†ưî.Ń缒1ˆöñÅBíÎ =e¾lÛ÷lm±»–oÏ®^N¼xnơƯ <:.‘àëˆz”/¡– ô§Ụ̂V R±âµôö)îŒY0•çüøåÓưº„Z‘*•»Ë¯”íªy%ừˆ»ëÀÂïMüư3ƒ§lW+*)F ̃ë…c=†V™f=¨[0ö¨µuo)c|qe,X5.¸ÏÏL+ÏKAú˜WÏ–öxw¶Ăm—8 Ä5ôÁ₫ s7.Ñq,àZûƠ¸È 4¬@OUl»úă„!c²©ô'aIđ±́ÇÛ‚â8POe’D*3%­A;Á¶Öù·g¾œiM̃ºGI5''x̉Œxô#Ïư£àÄÈ}Ç-ó^ç?dQ#ëâ%x,x:îÄdJ,{¡4¤ ®ÆV#Jˆû9-uÍg$h7·ËĂ›,l°Y«÷—±ˆ’<Ún$gñ@óøWd|¢æå–ùW-\³P–:; b:8Wú­~ñœycOßL̃m›‘­Aúƒ™Éߢ­=>*“Ë'![0@OSº@yê¢ñêŒL¿g“J^u˜B¿tç|P_=BơM6Æ¡è:FO{%sưQ†…1Ôäưé±Ư‹1ÙU‰3׃¯ÔC]†¢%øñyTăR~SàµË©‹|¸Ø¨j̉ÓEwßœxĐAú"©™ƯFå¡ÁN˜ÖXÜJUÂÈ,)1•s¦9 ÷ñâö¬K( c™dBí‘ʺMo[»U÷ &6,?ÛPqákhpÙnăuÆWo¦6ø®’ï2¯m0‹z°‹¸0ˆE’t—(8ÚM‰fîĂK7́¦5ós­ˆY㨠|{Ăᵑ¬„P+®ĂÚÚ´ưĂÆ‚N¥uø &Ơ—·vÑ U²¶ííi–2ăÓÇ7¯×ßqd{sˆ/¤^å”W—ă ä¾²OÜ,jgaLX~)œ2e$`yĹ‹;oÅX/*ŦnZñT,°̣ö£¡_˜"F[íª|8W&4D¤ỊƠaê3€SÚz¯±¡.4Ínr2Çc‚x'̣̀oÙ¿Ür<ô:qµÉë+ă.h$»à8*†ÄT7©Øœ|+ÑR<_ ²00¸o±Ä®Ï?*-ÎzÄvSm̉½Èƒ¥1^àtS²tw"ßV?ôHíơÎÍ_Ï”à˜s _ &?£Yđ̉S¨µL¯ô Öë9Ú‡Í;µR™P)39Ÿ JH&¥íƠùăÄl7_y_Ó=tµÈK -R̀‘,•u~k¼́p‹S×ó¡hÿêƒRWk5ĂáÉÜçê!)÷F»¬ÂḿĐç_p—Ê©ä†m’‰TưµHăX]˜—¼o¢Q(`áÅíl?éèÍ~“ H/°ÇL©Y°Ôñ— á0ö¼Í“ÒöC«<ĂƠv•ªĐëx”R©ïđä"AF´RSÉé#€Zậ`íªưœ8ÔH”¹HíŸíÀ=~¡tQûƠï§băë!9““üÜBëå]­ç₫âÖäí ï È5É'm`ơêd|Ă[&Gè”×﬽̣ôn4lăÅÊ|¤̃ ¸ ¡DG̉•ï ”æS}¥å}öÎ kI¢Æ­W ß­ê¦́~$È"!ơđ̣NWÆ…1ë[5½¯Ûă Q^Sj¥›_kdóŸÑX̣¯Ê¡5ÔƠ²_ôÊÀ}à¸dÉ Dư4ÚÉM/jÖ²v́”®”b̃́bl¿đÇsy`/ËÁ©hWTüóà~W_~°0o"Ëè¥Kèă³®qxÀ‰́3©C—h5¯_k_ƠđÓëü+¡îÉæÁèÅsjöWĐ‚×È|~^FkdÓnBËÜx\Û|mö çä½gßoåWíLH®f(Qáô!XÛ̃ƯÍ2ørÖqjZØùAß§réŸMƠß~91"XZ)"»³'́¦¶’(Ir.̣¡P9 ̣î „’©†.‰6M?%•àG"[!ÏVÉ•¡²̉’“HNæow oR_@‘7|xÅj(AÙ”yZbEă ùÏ._:tϯc/œöëñr+/ªm÷̣œä»í6’ﬕ)Ä[rS₫hwXWKôÙré˜Ù*’¡wÍrµa˜̉Æ›ư(ÏÑ©„U‘S£YÊŸ‰Rág0«ƒÆPÁƒ¯e~ê¿€J¾GŸtb×7²êªóÄ ËXÅ1áäy÷ô¦æ&pMOÔŒµ6¨txăÉ„×tô·Í¶\ư¯È¥ư$’ÂóÚi48”N‰ ój»a7gUR‹§Ơ‡̃˜¢7ûqÇÕ̃ïƒ<Ëü×Ú,ÓíÄf̃Â(̃÷’rôc¸`ï”\£¡₫›6|iÂ8­6`Û>Ơr%XœU0$r|ù º]JƠe¡Íq–;̣MÉú6%ïëåÚ“ ¯äÊe¯´$ 5ïø'à“R~%ägùxiÇØÅTæ¨4đbñ̃´?ÏaGùƒÓ\á‰Dâ€GÊpV’¸È‰@Đ÷đƯ§—Ö̃x°ÂÚÍ¥ç´ï^O"¨øH$—ég@©K3²aO}DùăØLÆÄëï=„»|OÀÇû/5ÑĂ*wv×?JT…o›Dç~2Y"¥–̣Ơ N{Ps7˜́>̀¹ÚÓñJPÖ·7Ó‰t-BĂ`3‡/NA­¥Èưvâ§9Ơ=Œ?{₫ùÀKPºe|sL…À¼3ÙÄrwz(”ú\ ïÀ>¿'äË–ïƒá®ü’O+JĂœ ̉6 ÷„.û¥'vä°*ëԪ͓KoƯ¸=¢éürevy—ÛỞßđÉ>.$|N2ˆËr!"¾b×~J¶²ªG‚Ÿ̀ñJútÈcD]0È@³z₫°´ <7¹+†SŸÿ¾OúXă¼-³Û´Ó©ùëĂbuzåé¡[ªŸM•å]ÆIá&$O.NÑGQem㸻b>ÍLé7JV¯%ḳ¯‹qƠÚËTÑ.¨p|óÈ×¹J4¹ótfIÖ́ư-‰i|®ùúĐ›ô…̀ úJØ?Ó'ƒ€’`Uœ́˜+5¸Ü¥2(ö¡ï#O’±q»e—Í¥¼9iê7ÑÈ‘äøœ…®&C̃NÓÀĂ}ŸQÈ;c•j.g"¶V»£Îjöô¼-eÿUN¹µoùk@ê] o<È›‘ÁæÀ¹Yă¼́-x’ɾ‘zBh0[¤»¤XA€Ö7®ND_§½©£üBv5> ư|¹“‚{1ËH÷Ö$Ư)¦³”·Q₫øKœ– ßÍkơZ2Øâuơơëí6ƒ0Ü̉½§¨#Â?S̀Æh-ëÎÂ`±KŸY¼‚öÂÖÑTQ̣æ@…Ưƒ–z₫Œ>/·ÁTÉe¬´ù J6JùÇæu¹U¥êëR_̉])̉®b;Ă¹C×»µ[ÜGb†²Ëă…ܔӫ3ư]nGo9 T<«xrzç.Ø=o0º?ŒëÖ‹ -q¦nߦ€.>Ÿ¤w4hÊUñ¢ÇAÅF¬ê¹;¹Ç†Âậá KŸY§j̣Yóf5o¯±®"öAÈ÷ú¹™VΟ²%°–öÀ/FU%W$\7F¾s/W{œƯsܨ˜¿/ưi<¡BFk›øƯëú†ùÉÚ)q»bà£H¼øæº,Ÿt)ûGFƠc…P¢ûRˆË¨lN6J&ĐÓ¤;4@Ă¡ë\ÈJ́sŸ;V¢(û&jµkIz“YÙÑ©*<\Qsx §ë«œ+¬₫$FăV~ ™²feDÜ=́¸a½„ î§Œ<ú̉9ÍÅĐëÆÙDæÆÆV¶{«?îœѧ29đuæñ÷¤ñµ€j©j½'̓]¹QuûéäjLơ(:=|îÍ(rjE£ øEéT){Qrøè~QTøCƯ·Vá Ư?î Ï91˜&Èîè¬ß9wŸ£v/Yliz¿WÄØ‡&‰«ªn½µÂCxå†î€º‰‰ˆz¥si5H´¸Â.ïè-|è£üü.&Z|À̀̀Ⱥ?ơ<µàêVơp>¯$î°p›̀Ë–çÑ&N~ßøĐee«âđ/»­Ö‡­5_Ϙ›(®Ñß6t¼%Óœ₫ôµï »WUzûÛM¿qê:w¬¥4q¾¯̣FơfƯ_p"9—ƒ̉±ïRV‡h¿5–/霃–´I¹‰9UMu1ë°}̀êËJOTó^ˆ“#LO¹i KiPÓĐÜeÄÖxëñá‘ äÄ'ùÂ3:Ó§føơØj¡Ë­›^L!Å'÷×kwˆØ½‚6Ûßd̃-‘óe&ß­DjÛÁ´iäU¯³¨Rù¼­đ$R}.®CÙÏâ¦*V™±&Î#»¾à´'á²Ï»<¹zÄÀđé4—-`­Q¯5™OÊ‘ú$ªm};“YíV„côöíCö©–*+rd]F%©5).Ü€jwØ{¡Ê3̉Ñ+ß´§ï°úṔ®Më̉ùḍÖÿ¬́́í4Ôq)xyóâÓ~o ïlÇûÏ}»{í‹)Ó”Û‘?-¦ñ>jîê?Nbû”ơZ2 &(3Œ¬ç‚Ÿđz€+G²)Q•²Df󺈓Ù§PM?û=âépYñ£vËGW~ăỊ̂DblñoÉe«(QâgĐÁ"CVVÉ– ́K0]¤¬k+¶íṂ”|*_i)Úf4₫l¹á¢jP³F6ä–Zñ² Od9«bB]ŸÈb[ơfx§ü23JëtI3&c†ükIq.‹é=Úo·ôÇĂ“ÈÁ‘t3z\–7«~0ø‡-£¶s¬ü§̃˜iBí†üơƯfêñp.»¿ÉLM½À·Äaß+i}4<ô½HY¿u/LaŒùud`3U×%ùpÿư!*Ÿ‚̀­g5_ù[Œf»9äx„+rßÊ™®îp+èɦ*êN:Ư2…î÷OƯ¿014ÿ¹:Á endstream endobj 1726 0 obj << /Length1 2697 /Length2 23728 /Length3 0 /Length 25242 /Filter /FlateDecode >> stream xÚŒ¹P\ ´- Á-¸[ăî.ÁƯ .Áw—à$hpww‚»4¸»;$¸¼Î̀ÜIæ₫_ơ^Q½¶®mçt$J* Â&vF@ ;[gFf^€¨ü{f33#33+<…ª…³5đ1<…:ĐÑÉÂΖ÷QG ¡3H&fè ²“·³ȸXXØ,œ¼,\¼̀̀Vffÿ1´s䈺Z˜ä2v¶@'x Q;{G 3sgPÿù 6¦°đđpÑÿå¶:ZÚä Í6 ŒÆ†Ö;c  ³ÇBPó›;;Ûó21¹¹¹1Ú81Ú9 ĐĐÜ,œÍïN@GW  àWÁCàß•1ÂSTÍ-œ₫–«Ø™:»: µ…1ĐÖ äábkt€’T¤åö@Û¿å₫6 üÓ #Ë¿á₫ñ₫ÈÂö/gCcc;{C[ [3€©…5 (!Çè́îL0´5ùehhíḍ7t5´°64üÅÜ !¬ 0øOyNÆöÎNŒNÖ¿JdúÔeq[Q; ­³ü/~b@cPÛ=˜₫¬•­›­×?ÀÔÂÖÄôW&.öLj¶.@i±L@"øß23 3€ƒ™™™‹‡ tƯÍ™~…Wơ°₫¥dù%Uàíeog0ô¶0‚₫À{9ºÎ.@o¯?ÿEđ,, cg€Đ̀Â₫wthú7 ßÑ à Ú=ó¯Ÿ?}­—‰­µÇoó¿æË$¯,,§ M÷wÅÿêDD́Ü^ ́̀Vf˯%ă}đ₫o%C‹hüá+mkjàù›-¨MÿĂØơŸ ₫ç8hÿ¥`ÚZ €ú÷’ë2s0ƒ~±ü?¯ú_.ÿ₫+ÊÿmÉÿ7! kë¿ÔÔéÿ?jC k @Këâ :y;ĐØ₫oS àßG+4±p±ùßZigCĐ!ÛYÿÛF ' w ‰’…³±ùßỤ̂·\íוY[Ø•́œ,~=V  Ñü/è´Œ­@'ĐJ₫¥‚.ç¿)ÅmíL~+'ÀĐÑÑĐ4dâx±€nÑè₫טmíœA.PỹS;Gø_åä0 ÿư8L"¿€Iô7â0‰ưF<&ñ3€Iâ7b0I₫F¬&©ßˆ À$ư±˜d~#ÙßÄEî7q‘ÿ@\~#Å7ˆ‹̉oâ¢ü¸¼ÿ@\T~#ƠßÄEí7qQÿ@\4~#ÍßÄEë_IJ4üƯ3PCçßJ£Ño"jähhl½†Lÿ°bûW₫÷)ư«e2₫q€‚ÛYƒÖè$́́¿$66¿óÿÚ/&“? (%đwPÀÿd`a…Ú˜:™ÿ®á—ƒ èN‡5Ơô7˜₫ÙA‹?b‚đoÈÁö º₫fẠ́Kđ;8Ç/s;Ç?² ̀₫€ ø¿Ù±ƒ¦fîao´ưĂ$û#?3¨LË? hBV@Pÿ, Ôc›?Jơïwd«-èHÿ°2ÙºØưz:ưÁàWḰ~sÅ´ûĂ‹åWḰ«A9́A¯dÛÿl;Ë?̉ÿî;¨{ĐCÔî©₫ê Ăï-wp±sYÿ'"ûoÅÿZ,Î4ÿµçùGú_c–_₫c<, 8ưnÈÉ hcñßÍäøetưcH  N ÷Ư¿uZëdưç̃±°€XưN z‘09›;ÿX_PßœỨ₫pÅpù‚&ëú1sûc+Ãî@Px? ¨‰¿É"yÿNơŸ‡±±‹#hDν.AOêÿÁ}ùƯÆđ‹svÆ|A–µAmwƠÂøn »ăï¦)v5’i¼Û]̃Â|¡©JXw¼₫2܃²²-NưSh‰øÙ븹&´%^¹ơñă“~́û©ƯVø…I¬‰ücáº~B8U¡½ÏƠư­ Á;e(²\¸ß*å¢ß¹ơIº×ơ—.†̀í*ïUqÊ"<•~gˆR‹Ôơ/¡È1ʘÅ!…vf „¥E»pGùy3–5ñJ,Kï}ÅVॽÁúù~Ösµ\•Ơ© —W‡â'Ú襗ÈA¢ ö¼WqÁÊÀ‚{3q}̉  ăkZ•ÅûÛÆ̃×ÑÅ–́/€ *üôø’F }GRȪVưtç6+ áA‡©ÈjÛz·©eÁÏ÷ºWÀ ’–ù±_S·×c½ĂêđÈĂmHRËƯpăÈv··F‘`¿ ™ ­¸¹NøÊ2oaT©óØ›.  4 ư’ëî'(Ă`~¯€K‘<–­|ffmn¨^đQ‚3́—Ÿ½+.:6fPç­ƯĐ>¾r*¼u&]\äă³‰¤‡P礉wÊY‹¦Ræ«6̀–2]lT`1•xËÅmq,\’°KKöîÎW‡ëxX̃óä1©W¨µÆpä)“́œD0Œ4ø‰÷ñܘlƯ”•‰èaÚ©ß_T¸…‰ ̃Tå ÊùÔñ̃/«ËI1ER8âMáíöl/œÙ©ªˆ+‰Mc4²†ê»‡í±®Â'7úRi1 ª‚Eù~ÙC₫Đ‹Ä zq«ư„°>ưlôc­mW¼£CLGYưL‘¾· A¦ß>ܨ~ù‚'‚¯¢z—Kæ¹Ö;ÿ}l›äÛÔ6¹—u…n{_€#2Â:–’d~Û/ơzưudø‹ixÓ›pưAMÚ̀pưdhR„ ¦C`üD _B•¾&W@‡ñ:Ÿi¹å™!ô@Ưô®̉I·v ă'pÙ;Ư.-p̣u1Á0µ#¸É½'Î/YßƯ%s”mËđSĂqw,ª(æ2Iæ§àåXÁ°kt2SQlø̉DkÀ FÀ‚móÏRa ƠF'^¾GWbÏ! bà­A¥BƯx™~+ƒ\ŵØW+*3&ă\ FÙëÅĂYOæ¯>Ù;Ùu<;'5‹ÁT2̣Vb̃̀T‚#!ÚíR%ŒücƠ«¿2ÿø₫x”ÏW₫ "æ’°)¯ü­‡6çơ÷ ékĂækÙAë‡~° ƠƠi‚ø‚×\‰ÇXú£ÙP:_:®¹Ư•øÙYf ¯ß9OÜI-!#ñq¦47y;ʺ°²=¦ª‰‚AY¤bƠK9WÔNM{ßxàͽøQè®;œûé¶´́±+²»’è¤éßJ·äVŸ×U=áGà1¯–]ÉËÜËgi1—F»zq®ă$̀é̃ỡ8f9 §’²á¾»…HÈPư®%˸"‹s4LÓM-9"ëe&ª-"™ÙODè±Lư6\–*¤—U‘yZ=©’SZ‰œÜúñđ¡¼‰!{C§ çx86q7ˆ‹+;:OÉJa–`Tåz+3›Bïbç#_ÎÚ‡ă¹æ—’:ĂI›ÚJ[ˆÔ߃T6ơÊÓ9^¼.Ø—'›€eLƒómâvS÷Â,˹‚R°dûóDßG[hƠc·öø½6̣l]Ѧ´üñ%Å›¹ ¡ Vwân9“ï•ÛøvÇ>;,êL‘C"ï„j~<œ’0ÇukåØỹ“Ÿ̃ÕúQôUtN cºm®m²~°+í]Tê? J›Cv9ȱ9“€Ææm`y »h[2äÁyе´ ”@*‘³åP¹r£,a8®®Ê”ô¼+æ9Ây7D·C=úÜ&ưd®đP?çµ£ˆx›̀!çjUlê}‹7FÂ/¾²íäôÑ禓4P×_bÛ‘€2-ơ‚¦¢Ñ@œ“Ơi®“Éç4Û·±Ư°0yûù¼sr™¸>£^”:"„ä–º*ˆuDÈKrñKËY¼PÆ /˜áoÚZsz€‡ÊÀEK(6\ñËÂí+å+~Æq ‰÷]ûnK¹ßp§µ;_Oµ8¦±4¹HÙ•Ë́/ xÁÅLe²€³Xüîg”‰×# Ï=Øç),U0›ÅïÁx¥“í̃¼µề"́RQh/<Á¨Ă§²Àjä–@g p.É?Sâᘈ֮"ô“¦ù́”ñÑqÙëæ»¹ă¢imIÂë­rˆW­Äc¢dé¯4'J6Ün^úQ #Z7¢O±¬p»0^»Đm/’>\ đ]Đûz×OQÀÛµV­g»C 1'; Î á¢i°H¸OœÍ$­̀^lb£ÜƠ=~6,¡Ne~ óôÁI*²w½êFÊ ‰M¹Yè/ftáùDiÛ¤%Z!ỆĐç\j"Dv[̀ 6i¥:![ =Í—×u4oí/ñ@ °©p^η±Y`̣R̃óx Ẉ´NÛÎ?P˜óe»=½©«‡¿A2ITÜ Xư0×|£}¸S9~\¢ÀN©½ok 5Đ—¼4¦t­íV‰gçD;ʉ'œÊ`»‚éÄqIăW!¡àdÈiúç`B#±´i bº¡Æj0%+»Z‰µ'Âù «Æ9z­ÛjđÀ‰"Ñk̃.©baúȘF/­Ú‡U¦B̉H帰á]å/=ø´¥+ªX—Qz €ưx`îKüJg:>èéQ́H¼©_+âY9̣ƒUĐu¦ úÍÑuÛÏùĐ^MpĂ<nÜÙ|øÄåP3·ExØ;®] 8-!•>—ÁYoR*î­íDæËăáˆ3\I˜ïĂ%W×ÎJÄ× uÂLï”ÜÙư¤‚³1?Áh<Ơó-KÍa h¡“²‰üàX¼~Ú»Û”̉%.Ó¾cIO95æP¸ă)µ`å’iy¾npb‚8 ÿjFư£ÄS™₫­³€Nå÷X¼¤S“?/ñ{rœ”a6•4 ¸á®Ă‡–=7År}ïEôß‹Zw»×égÏkeđÖrÈUA®ï-cœ‡Ă n­@nÀ÷-~d²̀̃è_̀!ñ^3H8;£Ô đ*Ư™SÖl&‡–Z/ÚGu–ίhƒóe\Ô"¸Z°Å,sLDÑÿqb»âߋԡø´í,¬Å ‡d›‘$¥¿†¥§¼l†×à“‰5Íe@T=yZ,+ºvÁ ́ûÚ½B\Û/p`Ư©l‚W–ë;MỌ́5ă¾¡à)F— Q¯ù'ï3¤L¥Đ†{Y] 85³äßx æ²²Ă›Ï%ƒ VªTÍ™(|™ü1ø¶ ;.₫ÎÖr¢,ñ}1¼$x‡Øù>‡ï₫‚;“,¢*t]yJ,½>DÀá7*¬cle2‰̣K#A_¬©/§Èa‰Z€ĂÊ»L6ö ²\àÏÀđ4½Ë k†áR‰ÚÍÓÚ.Qj̃ư}û½?¡1ÔS$ßµ¾œƯ“̀€KĂÎhíOgáÊRˆW5=¦½Y•₫€ï§Ír »nA5;ª£"g^ªÅ°à£âøâaÈW̉’,™ä#âŒ"øY2…­†,Äá·º>E—+€ÑØ8,&e‹²í„éˆྒ¿ÇØ#°49WU•3a•T¹dƯÇG™XEÆ¿¿”Z}Œ¡1Ú‘đL3hl̀Ư–6R‘¢Lä…j‹;ƒºÚ‚q£ûgHèn«×”²ơ_V“xx´mó^NÓad“ä¹_@%MÈ¿̀}Úd2ơf[OL;₫V8¸M*Y’ˆZ±Oe*ï43C¬©¡ö́ưtÓĐØ¤Ơ×¥‡à73Oa96H"Ơq¡(ơ ;<ö™Xÿ₫kßAhíø•ó–L“kÎÛZÿ+dđä‹0¥ÈËT¢æ‚₫)üA*8Ï„­§ßª»/…â+p2àR Ëëư0R„}ĂC­í4Àë婯¢¡Á‹È– æ'mµ¼,— Ø>Z¿q%¬4h¡’¶Î~öƯ¨!Ù­Êù9­Ô3râ• -^•|₫nÜ̃đ@ÁÁüXÑ Â £ñ,mÛ₫ÛÅc…Üñ*qơú‹ ¼©·±C/G·‡Éóê‡ÙŒü»®“·jôàÎÙ4{¼RWÙÁ}ËÔ•ú@EÿCB ơ‡Ih,r—ƒ>Ĩ°ÍË>ÏÀ̀à4)m]hµS×….0"¤IÏm=œo"Q~ ª[M_Ù̃áTjo¶Ù`ÈÄƯa1L³ƯZlÏK ­Äø›N>[5½g'3Û̉¾ơz[e-¨]âyñe-B iŸû”ØAnr(ïâ\Ö@`P_LÑc˜{¶Ú9́T*Øâú­u@O÷émæÜ³̣Èf±‚‘i0Ưr[ÇZP¦)\Ôb‘\›çԵّ٘áÎç—z‰́©₫^tÍƠ¦̣̉É7´mo†̀n^Ù5Y?ôİK¥å¦Í_¥êuO:ÈíjÓ“ƠN¯}o ââ&¹Nḥ¯S¤lc2ß´Ws‘z‰…¼çgbu~–ïüqï´[è÷hÅ#­ù#Î4¯$} bëuâù‘}±PSü¤(eˆñh“¤k²—”VfY…ëm×’Q,ÁÔ¹å2!å÷EáDº²½°ÎæVX´%´w?rvÉ9]kUđTµP?‘-ăTÊ%½²í ¦MPƯœÜö̃ûJ`›¨KÊÍÑÓíc9a–K¾äoè15•8Ô÷B߀›Gö#—ßßk•{‰•8 !²ƯÑRÓ²ä„,iø5̀ väÛÂ^çs‡_}6§êb2³“ZZ4‘½§DǰT‡„‡Lqß$çÅ%(yóA…“N·É̃L“Ǫf7¾•¸}ĐƯÇ{¾Ơ›‰‡ ă@àKëúxô ¦Û€$å2ĂùªÜÿ<™L•¡̀6dÄçNÖô™˜íXe”·Ổơt™¢ÉY&†I`$Gñơ,ĐQ}Í¿×ưCu3t›ÍÖyVwĂ?ëŒ{»ưœI >zÊb*t‹’pƯåné+©™±“Ä]‚ª¼§B çØû ¯0*Ư«̀5üå4­æsĐ₫í́¦ÍbæÑËŒ uªohôT ¦ˆ‚mƯ¼Ÿé´Ä1'EÁTƯ"h!D½‡6xö̀Ü\°µ}×…ÿºà|ụ́¢µÉa-ᣟæ̃¡–ù1‚J3®a04HRYm…SA—8%håFà‰wX]ÿñͰÀl!­4³7Ötƒ.©×&́9›Ú’çÀå°ËDº)Äèb~đO¥ơâñ˜0nä€'µ‚ô7Ê 3ôđo˜3¼&–dÍU+˜aæ0ƒémNvH ÍBqđ²’\ÑÛ¤•'Cß́•>́´¯<>xçơÉÍÖ« ‡đú™–ÎÚ´ơ³GÏ]¨ °ö½ĂÓ©3i\ˆ’I×]©Ă"ª ¸Â2>YÂñ{ºG₫ưÍ¹Ă’ej Mxßñ%³²kª̣wTƵ‡^–ø#8ÜU}đÄơµ˜˜tøä§4å z•5~µnM^È€¥eAcº¸S…Ö»Àî:đ¨̉L̉̃¹¾ô:³ƠöƠ=£~XèeêZZr@¤tùƯ fxdüv°†‰cE¯–gA%¶cŸ°‰´(¾S˜¿7<ƒ%œÓS÷›ợèsxº,;혿,îüªFÊ®RÄX¥p©$U`VßÊvƯä÷QñsÖ…I)%®ń*¢S­a†Z‰a4qùØù©C"Ÿ¶²ÈÑÀ>\²Rđ+7ïmù́A˜ëmmTûæ ’- z™Ú»M‚YªdlgUDÄ₫Â)Jà¸Y‡ ñ̉Ơ‰ŒÎÑÄL]—ä¹yTŒ)ĂMÖ>|5¾7à̃ƒnA‰SE(H©±h£èji´éZáÆ9…‰ổŸJ+#ƠkŸ°Ho¬&(Sá§Ø©fÖ³¢µÀMnF¨ÜHÀñ[_ßúI}åC´QáH!¥x̉µÖ ¬'.™ ơx×"R2Ÿa[úL›€QlÙ‹8»'IS~lhÿMî#¦̉hÿ§À†‹.)yµ†HÛêƠ•påÇEĂ"ùïtÜ_s™¾79Zư4)ߦ9Ơ.ûHû¨/øjªĂ§±ƒuçªG« fÍÆ«â±éæ¹Ú¹ûñS‡Û[æXe`̉í¥­øÖ$ơª́MđqH9bµ¶mÊ>33˜€5Ơë¿IBr«”T½]'*4æƠóÈ++§0sê[rGŒrmϽôâëUû™Rd%–™âG¢)B¦# \N»nŒØFPˆÜ}FƒââØ{ÉÆZ{#ƠÙ™£Uí3;,ª² ï>1ùUkëv÷C·ÂàvdWS­Y2‡Yœ4DÑËH7.Ñ™:ö˜Æ(×KÖQẾ”đ‚•pé‡è¢B›ô¸)æû&¾x¬'A³—>p Q©ˆˆ#üKzØ]v₫¯ûÍ|Nr…‚F*²$à] PßIBe™ÉÍkÎÙÁ¦nß}‚J‡©¡.÷‹C”hÍ)„¾íLT¯d/9 ̃føA,G¥äJù-{%¨ Fr †̣‰¨*ê…gQíE¸8^ĵL᳆ e1 ¡¯2^¤—úTN>Ù)ÔTÉÁœ×ûhªí¥Î-zte”æ¿6pAøơÄÎ\́2&3-}̀|Z±k{Y“~-–*ª+àÉ3ö¬cÑ’y}›ü\P ø±ưåØÓbeỌ́ÖcYW0Öû”| ơVíÏ»¡÷aÍ|_9^fNÖ_t³¦Ç›Œ³3`-hŒŒ°o~¼(®Ë …7/(¬ûâ¨dµ.èî:¶¨Xq_©ɾ^ ŒC?+Î'‹X1¨ƒ/ôØF`‡VÁyÊÔ®Ó£D4ûF ߟ)ïÛ”l{d³e¶^ă_Eđ₫Ơ¨è+rc–?úÚB§mY4₫û4Ū½Mó zïmƯø‚'l§ënÎsÏVỬk„ø/‡zU}®exø#Z'e,“:qO~ß9̃Làºg ¤³â hTµöâ?—®láÎ1Uu0,Ñæ]wú"%èJT?_¦$O4Ăÿ¼p®”` á{Ȳ¾Ófi'3[#o­2„±ëyÁÙ?AƠjLx+Î΄ExT¦Z‡J¿yª–̃¡RưÉỐÄ7Êá9®ø’ÆLºˆÉ+á]Ûøt3°iC¬?¥P‡l 6l†É~Å+Ơ(CnĘaß;é±Ăü`¾¨ûñL¹V=iº àĂʾÚU~P}©C¯çÀ8|lø£ªŸƯäô-{5“ÙÉ«ü­o/!Ô}“ ¤ÁT¦gƠû°‡àˆ‘ŸE?$rŸaTlŃFY~é„›ñ7O¼·Q‘=!NX°¨ƠZÏB/DgqÛ„ ØÜXñ¤ó.„œ"‹rï¬~[`êნÄ|̃Ơ,'£i€´ndq…¥KóÀ5‚,ˆ7Ođ=”‰5¨$ê:EJK9*ƯƯâkQ̀t‹Àˆ€Éeú†HL’_Ô rºÖÑÁLV×­ß̣x¤m”…-;‘ÔæBG“EWDÜ—Ø•ljîËƠ:2ưŸ(V4ád;{‚6»©2|1g–Ó̀¡+3)Dφ(̣8ƨàCwå)ëT!ü+aÙ“€* ÖO¥àg0ë²Q‰M›Yß`8‘¤\Úʺgƒ]/q¹a¼¾ØR\8濳V€½]Níô¹íWä^X=X³à²m vz•x²Dgјơs%‘×ßth4¢" ŸºHUøù´`@\`Xư>¬/§ë»«ëåưÜiU“† 1ßó%by± tÁ€¿¦£^3G g¼ôí̉̀t’5z/¹̃·Ö¡Cö-Q6E"4oNÆoûoêơçk÷ †^rÓ!†ÖYûó*^¬6 6Cg>åÄL¨$kÀeLªĩWíÏE¦›øi´$«í…uy°ÍŒĂ)©Ưµè'èAM.bcKÈñ…ñc2³ɾ$kå!ÇôV e.CR· ØÜ: : àŒÀäÖ…`?s»Iéøöă¼Ÿ}âj§Ä™êJ¢Ÿé‹Äñ4hG‚+k¼5[ïM¥rùºzÓ’™Èß4vL VÂư“®ÿˆCAVt“đñ[Ï[2Iû¤~ê%å6M—Ă%K§G;·ñ̀ ư5߬ô¡èê¡„¢ùK¬+̣†Sè>5Ô¬\%Hë·‰È*̉–=‘¼đµÈóM5I#´º×“|M¨bc¹̃k²ª9YZ÷0j*=Á_ ÿ́2¨åàÄ,6'ÉGtŒ@Ü@»É6Êă¶Ẓ¼#¸đq ¶ÙúcX¡’¹å®đâ’e C£ï@9ˆ̣˜e“đi­GÈWgå D}'T‡*/}ÚH¢fºÇi¤x|,ÇÈ<'ëƯYRTûN÷Ç:Ư˜h—/@=Ryèà)Í]NáÏuuƠ%é¯Ơ7-‡Ù2z‘Á̉GĐD9 ê9̣"Y¥$­‚ ƠJ<´#a₫„¶çú gºêǴiưBBôèü‚l …n«@R+®kĂah¤^:¥qùcªv©°|®f:£6x₫ ỎO?¸2Wö´¯ƒ>ˆîứHE%ß{o‘²BGù~º+]ª„]?{Ö;ơçÛ¶[̀µÆà!Ió)½?=́°„"nÚW¦`Íáº;B,‚ư¼È Ë̃‡¹=«ë„Yq±˜²Qûß5â|§Ê!ó'”,,”l‚fë .Q–†*êµÉå`¤h‹KC6¿©F@"cU¿Ë!ÄV®¡S[+Ä0dmÉÉRª[!Nè;tå¢] ÂpBôÚơcx–0­|ç]ó£̉—Ñ7\áêÛ|mp#¯í©̃$VDoÄ'²Áêë›:~I°¢ÈÛ%7¬cƯM"Eÿî+/©T1ÛP¯ñ$S¿B̀ ÿñ9 9Ưq69ors .³)çgC[4Â9üĐ³‰vü{SºÑ¬®W×đôƯ+ơ°vX.âULûf¿k- h‘[©\yrp-k/ï‡"W»TÜr$V­;̉dæ:뉻¦7i÷Dº‚ đPœ₫&Ư½Ö¥ß]¬¶È•^G’Y¯¾’́Äd'ºl~óGÿº©¢1€åq³ö¬5â×ä’–aè̉4qâÆÚṬVS.ĐÜkû¸ûĐÀ<dws« å¢9Q̉ÍʈêFød6q'x3“'ø«cGv¬Ö &Pª]r¼¯c̃à*¡]u ̣Æ_f:M jĂ©ô¬ZpƯœ=Fe4ịĐ}@ûº‡qñ^Ew®eRÈYªĂ® ¯Ê3³à^—Å0mp@@̀̉W•ë\¦rµ{·WœxÖûôçZ»ó2¡¼Û”O)G»÷¹¶ê¤’#â1NßÖ»’s×ṭưÁeƱÜD̉0«»%­—T'ïd•oè£Äăûƒî÷L t~D2wñ¸7ƠÚ—W?ĂŸC‡¬–æ¾4DéÖ$%¿¦9Ä9ønœ:às&¶<ç>ø¤P:̃‚ÚQèÍUopưB}i3 )“=›*ÇüÉÁ”¤2ÅJÈR̀ttùœ$0#üeæG¬‡– 6™¶Ÿ_³ë[₫ûâơ0₫˜¼©6Ư`”X»-¤]ë²Ï)yMGpđi…Ä4V©§5Ǘ₫ˆà|p™PO–• ‡„éû³̉oK4;ơ$éÛ’,ơ°Z¢ßÙ„uRgg¹ă:GẲăîm₫œ/4Qøâ‹bW¨€x߇úêµWæüÁÁOˆCÚºÖ@YÛHjS´®«â-Ô3«V¢îÙ²8ÎlĂ ¯jơÜ*dùk—œjÔBº T£=jÆ›Áf:’Ù©rÍyCèInœí¹œ>̃OÊ« Zûˆ‡·KÖlTBØÊ:ôª₫- ‹rRŸ¢-æ{¾xÜ¥ÿPóPzb²8¶gÏ;²ÆÏµt{̣É*C¬Î£-)̃«¤ƠƯ¹4́4&ư,„vƠ(tbëĨ£klú3Nr²üƯzïxcr±¬5óB‡Ê²¦ùvÚê®đ ‰Đ…?5zS_Üpbû’G¥­ËR  €BO+)~RbÖ°JVÍÖvøxⱕÁdáïÜ%2­êN 86̉Ó±–àÉ,̣«ˆá{é‚$ÔËm˜­f’…Ù¦‚g³\e°ZX­ßæpǴ2¯́Èßó—ä åàc~{‚ê’Sè}ßêVˆáÛl1b)̉ñAỗùj²™V낽ç“)†Ư#’ŸÂ‡«â&hZ©‹…ƠOÑ»û¸€Ê{âwd…¥“̣,´1&±“œsĂj…¼ïa>Í2êÁ-Mµ¸g´RøjÉ;Jà¡úÑæ2=„u\ÏG8/a=Ô•ô¾/7†øüV§´˜₫ˆkLs'-ÛùHnù2f?‰2;'|…áP‡¦ ×Ê‚Íç]Z61ĐœŸ^ù ]I)/ÛH_Á¹˜p¸göøa,œöư–ÜæRd;â3-æV4÷ lS mZdôÓöTµ”‡ LzG Ó£Is"CQ%Åuda͇k•Vèt;È®”‚Rq]L±ï£™đ™x7·¤˜}Đºđ4ßµ¸ù/|—ä)¶jäïʹP$¿ÓÑÁ>k´D^ây›\Á…>ÙñÄùÊ?ƠoJß}Ä×uܵ¥Ïí}¿¼©‘†’wóưÙ[ó̃WÈgÏn¦ÖxŒÛ\úä–[¾O©ºÍŒ§p°:#ü)op®ÜJ™5J:aTî³_Ä¿å4‘¡è…çq k™!8V& ̃ô\Å. ^v‡äT‘­¶x#¯%—́G…°6HfdêÄAµ)Ù™ôc§ÚxdƠÉË)~œ3~'$í‚¡™™â1&“{é·s×'ŒU·¾>)Â:uˆ ~ëZ|Ơcèœ^,€~´ü°ïct§=èh̀ï¶V̀«‡î²œw… Kw1˜P³f¿Ë÷ÖŒTêËV̉Åïá0qÓÀZ¬¿(ÂÔñᯠrĂ½ ́]«{P.1ÿضçÑIߌ@VâcxI¾U&]\Qå…»î]÷öuR‚y» ̃mUQ9l«¨!đ=Îs+ÂZLẠ,¹Æ$~¥Øi`1Ơ'NH0ŸĂ…Yé¯TäÇŸ¬)ZE°ö_,HªæÆµăŸQí7Í —+L'NåƒÉ ›¯©B)€×ơà°qa3÷¾±ă;=ŒcÈ€ƯT·Ư´ûz}æÑ²‚YPÙÓ ï9Ië3nÙ: XA·L+Ç ®ù‰XzúngŒêSæX—%øÄ2Z-ç'ÁY¹]‚3$`çĂçöË®Âñ‹+ vpq†̉ eóªK¢t²‚èC ™…*̀hR祆ǣ̀ËĐ ÜG>tä1rÀ—f$ñ#R£½µ”O½µ”RYeK‚¢8¾\µ^â\E·(Ư×ù¾°Ë́£Ø xÔˆO1Jă÷ƒ«¡,ß½¿à( QGϺ‰™Ơ!‰{¢ åWq›BDă¤BYøESCJºă>[ö~&ürb́aưa?$á«®WÙ9„ư³ư¹œơËqßÊùH›™qñÆígÊ‚êó-'Ơ+¬¯:Kơ€!mE¥ˆI¦¤V&ñ }åÎkđđ±|? Xm›ÛÑR³ÉÅØ[çÏw(ù#«Ï̉ÆÚ0RgIƯØ£§-ñ»³M'=1tD%¦¸ÈNw øM/„rw¸ĂÀÅø!ƒn–X†¢>¼©¥–Å£÷˜ëäÙüX₫¤$,T¥Mÿ³¯:[1¿&qªå³,y­5áŒÊÏ•#ÛnYú¾jø5,n‘…ÄÁ,C/½ÉƯS^pÅ0)xX#)Ê$ïÁ5’>*nô¡.ñT×ôùIƯ_̀c<Ó́Ư‡F™L6̃V§ ĐÜ›Oó º¼fY²!@pƯ®S:Äv€á[F©ûºµj‹°îyƒ,̀́Z㸕БÛfï´•K*½ A_´"ñ>Pë~a£«˜ Ç€D‡AềưƠ(i8çy@ZÑó…oó¡ƒ4dQOưºÙ:a´"'±Ö´”»gv¥Úï^3`„d#àbx…"̃\'»/`«'S£“ k[æÖ0*Zª¦—sŸ2MÁˆúF ¯à§$°OǗk›©Læc¼ºäô®Cs6³7>(*d¡‹Ư €ûÓ¬óŒ8L÷@}Ḯ¯ù́4Ú^t±HBˆi3,úè璘ÔR}Ÿöuy6ă¨¯+ ¯"́l<ØÇ¡ÁÏŸÄt4â [M æ¦ü'Sg½é8Üj‚¨¦Ơđ₫—̀nHïç°´:Æ›Êñ7®§Ơ†ĂGw›•€œ¼̣’̃¤ ¾¦™ü! ÔsÉBV’†<̣c3?O9Ö˜·̉ÚÀC3ơˆ¹kªƒ¦Y¢ååbá[ÈÆqË‘Y퇌¦Q´a¤ƒê¬ü4ơŸdMñĂ¾Ö˜öÙyë…~RÔdΘֲ$q~°î*_oÔb™Øê¦ -[lµ,ÉƯ¬Vبîx¿̣Óä~*öNƠçb©ÄËX×»e  üˆă!{|ÅFư¡’²5ưÍ̃.­ÑĐˆÀúWR!Fl€đ[åØ'î~[|wƒ!Ơơ¸}ë“hê ¾º¡ê~•–Në<“Ra“¸Ê7:́ùHĂÈ‹gd®E†́fDßih”‡ư’fô'²xŒœü™°æ1–à?WmßÓv=E>—øêUóù>œ} [•#_|æÅV¥ÓqÇ~‹3ôZÙ4v Ù¹Àh/X®·•̀…îÏÀĂ©˜JkƠ4$–ÀÔ^ç3G ơ~iFÊÈ”È3ơx9 Æè^ ¹©ß̣—çë |ç̀BfáJ³Á 8IlªT›ûˆ́³bSBh„+¿£ûMXÔ²´·t–ÔïtäÈô‚?kªqrBï¸ÖSñ3ÿ ö¶PkX/̃Ưè|pª‡ÛmD×ŇoT̉Ôç´e ®½`80ß<–9ïçÅ´9æ2±́Æ?¼76Ÿ4Ób ¹ªâ¹[–c¨b,ó.¶¬̃¤á™1â;—×0?j.¡6h§ Ÿ¼v|,<¥En£ÊÀ;JOóØ´º+4ă6vwq§Á"ÜÔ²½’ª Ơ!È₫L„œÓ=9Á ‰£Y!ÆÔŒ›×¢’Ë¡æ=Á~ÿ•áDQưˆÅÆ°Û ƒfJ*\ ˜ëÆy|„¯‡ }z}ÜÙŸñ29jϬ¯&4'Uó¥ÏßሸÑOG4\¢º¹$ǰ̀å>Æ]ʱ}ÔƠt~â,q—ç9•Ư¨W₫8¬-VE$Q¯J¡Óørº(æŒ7¥́âS‹ô%˜•eM3Igq­¦Úc˜4 ÊÙCmÖYRÁ ¶,%,>E‹²uèDQ 5‹ظÁ8.¯ËÓ đ¨g ¦Æz°ÉeXÙGÓÜqƒg’ ½çf đ:àq¿3qoÄ(ÑÇ÷ˆŸB*µ¶́ïhá㸬B“Vø‘Q8Ít”"Jººw¿äêĂp·•T²á;Íœ¥¿_oeœ1±HßƠ‚PÏ“-xܲ»èXQ(̣Ư…±OP—j¡Të̀LøI¸¤ăh‹¯«]"G¸¥~lÇ ƠQÜXp¶´±·R^”Pz2k=´Ÿ¤k™ö¹‰î†mîí{pm¿d02ÍÙ¸'ÎÉùåѦ¬²9ƒU:È¥O*oÛ†¿«¦¼ñ =‡bMÈ#SHe]I\>̽³†ôºKˆz³YúeبNù\h¾¶ç3ßé`4"Ẳ»úúÓ¤·̀I02áœñ"iHÁ£0ß>́5Àƒ'Vôª9¾Ô C¹kÑ™×\™w}—á'@|ˆYUêéLÙ²p Mƒ~èYc›®Ñû<¯—'•IO₫ÏHö”CAåmÚ”́Iûr„iX¸̉ǼöœhnoF́’øM^ë^‰–{v³·ß!-Ö‚Í÷\¹ ªœU­v6 Z˜ni¿ÙûùÜú}Ođ¥}eÜ5 ¨«»I€©Cs¸₫Œ0"E‰ˆÛ§x²YNTÅroâµcª À°‘£ÍOôucÊ\1öjM‰̣Đ$A•đ¥æJă\ùƒ́ÂâÆûÁÛ I À&Ô¨k·ä"ßkê%›ÅÀóÑ[~üO©du˺ơhåAQÆç•W¬4Ëä8€aú¯â"S³ÔÑe¾–²U¶£é¡†¦₫Ô¬Áºa<(–­e]î˼HÇ4(ßtÁX'óÙQŸå|8Eú÷‘¿¾£Îä`pƠL2ZÍ,ñ³†̃Ô~¾Óˆ¯8\ÛösX₫ØÙÄ3J€„p_®‘Ö&QrGEª¡À:V¾-¡¬êx×¥¡ó£…àkû́q% •6Ưe„Qđ®ÇÎ WʉÁ™º.û–|'›¤“SƯ6Å[(-=‡p¸Îe$ÔŸñ¼w?ª2NzÀ? °SsPœ;GM}¶÷¢(4œJÍH(KÏf×ư߇ùA®•Ü8“ǰócÑEcpóuvø±I“ ^̃ŒQ?æi%ơ£3w“.»UU€wÎ%D¦i+Vÿ®tó† "ÀpQ©CjeË©EZ8½JlˆE٠.=Æ<#ŤO/­°!>aÎë"₫ñ$[-¼ö˜¯.,Ñ₫y£ư÷•[.r'í¹i¦7¨ˆ,EZ DÉ…,Ló¢ÍÏà˜éˆ+Ê!\Ú;ö¯® 1|́0®u¦,ܘ&ˆØ€ëó¼·ƒgơØ\Oëđ²­Ưg¤Ûíx̣—Шej"ĺ¬ Å–!â¦5£Ưăî‘Fàïc¬‰È«tOó¥G-ôr·ÅĐd¿R™Sm?°U!‡odô #XZÙqR¦ï“{sl¥Ä%K«>ËüLy[­ÇÄ´Ó,£‹pŒ;bk’h€¿̉NÛ!Mz—ÑHn¯²É£½O¡„Œ&`¸»5NZ›vÁN®îÜטï̉‡:m2 ^ åJÜ{è…̀£pfÇưvÏ©z¦ă£Ip~’ºrlÖ©»—&ÖöFđ8Gbƒ°¹í7x«çS̀X·!µ̀ ¸åsl™5R`ÂL²¼¦ô„iT1V–ĂsqmPm|«hRê­GhŒ¸%B/yB¥f#³éªô!qsc£uÀ~Ôµ¤>KhigFUüơ•Àà²?4C´Züí½[_ÈYz×Zzª ́§xº”»<Ô†JØÑ©ˆ±§^"mM9âñVDtNÍíŸ7­BbyYr6Ăe”ºHí0Ôæ4₫g à̃ļ×Ëvø“èujŸ¾y¸¦o.g4ING­hSưp'C1?— [Ưæû^çfA;÷ó­̉éÅÄé: q¾I§­•ÖÏP¶ç{†°˜¡Z×ƠeĂhÚXù́Á0ó4DvÅæ¸âíD8¢¢lÎù ïgOoz3-M߬z%Of$}R¯ë¥dWñLÎ ¬>M Úî ¡1[Ü5RâiŧA^²êëŸ.…L¶>­@̣O'\úgœÇâÄ}*Ä…¥“_â)†T!·ư.îadC‰ˆ30fÚÆđQÚœJ .Bgwz%?WEA¬vuH¥Z oU*ŇÉ—.¸å<"]SynÚ1)DåP’;9øˆ̀ gǬMtI{Ù0}nÇÀ̉„T›ÿî@2 üFËô2°Ú‰Á¥§èmª¯l„%6tá·Ï£¦7 XôÓđ‘k̀ûÖwCN„¶ªââú"„Û¯̉rG:LvâẶ³À1f ”ö aØ™çhºn\Çà̀<öÛ>ØN™‹Å_Q¬iü 9œ ©"®F,²ÊKÛ̉n?§ïMzî‹Ñ¯êơ¸Ù=À0!2Ư~Đ«-LœI'>₫E®ÇSÙăff€åé=oµ²2Å₫û©.t® ĂGVÍû6ÊÀñŒM0 —¢¬˜7>܉†X…!'•Â…đox}]ˆv-0¿’†ÍßCÙ,mÍc̀£~F#đèE’ªPضûX=±–^₫Ưá¶a<ÑæC“A 1Fưå—₫±ư¶O³`~V&+$­!%{’edĂ¹½3Ư†X€[Ç) î xăƯ0S¯Œ*₫UóóL̀€¯Ÿ]4}pœZ—? †9m€»Q1ÙWæ̉"ßÜ$×ỌíIÛº6À†üB”{ư›ˆKUÏ Ñ›úb¢¶Çư†Êxs"˜ 7g[1qߤèüà«’~êÙöN’ଜĐêđ0¹\íT$dMƠiÊúÉôd‘§\Ñ×´YLj²_‹nnV%M1YđÉÊÉˬT°9—ÊE.ỖwÆŒç}hܸ ¡¥#“yƠg?Ư«̀á ©̉Öƒ,fª¡×Ïh̀IU ùf'ä7‡Á%6©öª™™­_ï4í"í\cÛ˜O2$• s<ÑŒÊ.¸—l.!|ó|2u{ïBåÄĂ'oĂ#:ïN+;2¯0§e«̉²;°µ©Ëèí¨vkªÈ®j‡Çêë]xèJ÷Á& ¦4¢»~ƒÆä2ÏKi‘ÆQÁû[]€̣a+?É‚ sX‡Đæ̉&‘¨tZcƯ$¶c "ù¿§9ÆB&E÷7₫Ú„‹á—5D-%‹€ñ‰¹osb›NÍàoYởBü LD–KoîIYßÔ$çơÂưŸ¾ Aß‘•$¥íïtë wB ]ØŒÍøæ‡.TùbƯEÖfZp-Æt>?&Oö˜¼´'dÎP¹ZtÏ̃efÛ|K×a+^\ăAyÿÇ$k¦9-{hè¨le¾lQA$²QG~Đ>n•(/…™½º‹4đÉ<áˆl5&ÇêdC…J[—>€Rß³ Ôw¹Y›kë¸ €Ûjpj­`t»Qàæ…vÆ̉;‹¬Æ¢äa!xưJƯÎÑÅ–ưlËî!pư'ÆÚE-EÏíàœó„ơ´Æ~¤4j>ø„?=Ù³X›5Zf-_“á'Ñü˜gÓN0AïäK÷v|÷óc?*’p1À•©5, †¨¥«j‰Å0¸íœJ"„œ̀4®̀h”\“jûDå£Í¹%›‚¢Ni‰h›ÑƒVæbMg'ÚtĂ+B¼e¯¿b­˜6¥Êk¨c®X)S̃”­æµ~wùkT¾­¬kK×­©]v›ŒmŒ–û—Ú-‹tx½'ˆ<ĂÔ⣨%û¶º K 2ư%^÷y 0̀ÍîQlyä’¾½lJ“NûûKä Á´đQà `·²G€rÓÙŒ|g{N%]ºơ₫Â^­‰¡×µ»đÚ Íâæ¥̉lMäa4ÓSH—!À†›}’opÂ> TÊ/[Öm:‚Gw;ù<áøS̉´êr*¥¬0ÅD¢ËÜ(›¹èöZ0!ÛY{œ× µéaˆ©—æ>ÇoSª̃dOË/!–ư÷ …¢́ ˆƒLÛ‡œ6ø°M̃âêq£¦ÖkƯĂ=—©Ú̀”5_…S}™›‚[5;\Ä("‘ë½ưd·{ ḱ±g7´Á$ <"I¢đ+FơlÏ §mÛÅ®Tª ¾%Ÿ"Éơ“}"e=`‰‚ɯ•0 8ñé—XlØ&ü&_ï&0ϧ¹=®]&“½º•!;Ϩáo› SeÆânÈתÇCöÍùÏ\°ñ%[%÷äQh÷¯º×‰µP•ZoèÆÍ¥ƠpÏ5a›=⪖NÿÉ vÔVt;I¼N”¥È}bàă§Â™Ư…î„·)µ"U¬”xJ¼êHê„ỲT%¿ ä¢|K‚.Pọ́ÿ ¯Û: $s·ïơn‘{:ÎSơå ,aÇÏn 2À&x¼ú£8†B¤0&ÈêC5 YÑëe²4ä55ƨÿNBïDÚ̃)܆ѕqXyóèÈäUê»O!~/´Å¿ëÖtF¨̉<€Ç~½–ơ·i[/5R¨”,63!ÚÀ¶r¨>=l”‹g!̉ÄŸ~¢I.wÉ8w\ʹ«³ ÂxØ€´ ̣ÈPøˆhbçƠfmC§&Oå¨!Wù…:œN”®ùHD¡Úb6Pñu»(êq“å’—à-®7Êt{Ô.³ØéVQ1ñEüôZ²Á›Å_Êô"Á¬c̣™æ;DR£b#<Á0[mAÿ\›Ù*P¾„NHü₫¼ù‰øˆ€;b-zxÆ‹h8F€&>âĂ‚‡Á x́¶Ÿ¨øº‡A¹2¸›̃ͽ]¨LÎ=ñLpw”ñk₫ƒ0α]1fG0ªDđ/ï{fƒ EÇƠNÿÖjơZ·ó2:ÍIŸ̀¡å‡ï˜¶‡ g`2o¸¥ZeĂ:Vs¶ºfëc/¤hL†×ô °ÜXÙ* á“÷§îưeŒhT ­\ J#C…́ùü‚›tL6™DmÀŒü! ¼K¿*_ÍæĐÅuư‚” aªÂ»…’H6?×'yív@ß®_¢×Î8Y™€å?̃8Ëϔ֤/¡}óFº¨ez –t¼¦¹Ü‰́¸ ç÷>–} ‹6iÇr}mÅâºQ¬—Í ÏéÑ>Í­ˆ¾ø³÷Ư~¡̉Obûª?­3Ú2@îÅ"ùË¡¶"N§j€Üxµo7ƠTë”¶¥xÅîvÅ´ú#‰spáăÄÏ?QxáÖb-çứ(¦íÑ3=cf̣.!Ï;3Ú0“έnù|ˆ°ó±æ×Èé¤Ç?eÖ&tB^ è» Y_úø¦÷¶ ß2’3ăyhÿ·–È~»Äó‰OS·Ê @01|€(Y=SàÏîÅ9éi()|IúA6.©&¼gz̉ÿđîSÿö:iàgÄ8Ñ[/­íư®á£ĐÎxS [ŒU¾b<²©v‡o,VV¡;—å%&…ÛÊ=Ø̃jfê¿[ÿ^¿T6gÿ1{Eb0»C1žk‰G 4ÄÚ7¢¡8jê²ïjwñk»Æ°èÙ kqæ‘ TT/WÅÔ=®'0h!½ª”:¶“ë)ăăüv ¼7µRˆzq™!~½̉­}$ç-œpN9UÛ„©]¶ç•è9̉©ñ G;êü €úÚâQTu–ÂM€¿qXÿX­Đÿ¹½Â÷¿˜ßÀ­ soâé¥çvƒ̉-FÇófø508á˜ÇOYÚé$7À/×üA(¢0#±™o&Œ’´iÍàÜ[ñp$è²]¤pT¤Ô Q™^Ơ9·ÿ²Ÿæ¥E'«/Ư°+1{“JÆT1â9̉)ú8Æ®/°..w²ÂçS4£8ƠY‰`>)‚p‘$ÀMƠl[ÊÈÏlZµ«µ3¬˜%=cĐܧ†°¡ÑaÂï*ÀUqóñ^¯a‡í³$́º÷?¾­Ơa =¿Ză–Bs²•w8AéÂml1ÓWsñO6Évïp?{U¶ ~sÈa­ưß ¿4)¦€̉¦ṣ­I₫zÊœơ•²j•8¬µ|«Íq×[ă1‘ÊœØßéש‹_¹î̉Î̉,ñ)kệXFÄÚGHI•ÿ¤P,e¯“zb³¨!f4‰.Î&¤c è)Ÿs!©Vÿü̉Ÿv2 •ÛÖ›×¢€‰FóµƯ–å³"ÑÚmÚE>+#ưYvY*L¨ÎnÁ•û„ÆW)q;v‡d6xŸÎ°{“å…Tʼnô›2ûQ5 ƠÖ³`¹àÿa®ñZC )o¾®.BÆÜ·ưw©©mTø¡…ˆă{JT₫ÎßTlT=î°_7y()J½sMơ퀧¯–ö7́7úM&ôètt+vΗ$F “\êz°7 ơ°%8^đͲiuñaL’¥@Ùa¿ưïZ„ÿÄv«?BŸ‰PÏ₫Tà)‚„û9oá¬0&óú̉¾8 ¿˜#/©Ë:×/hßd1€!±ư0œ , ồ‡QTḱLăÓ’ZâíÇß>˽²Y¢)êÂ$Éѽ' ơªóª†!Ö†RF¤A Zî:穆½è·Ró¹`°äƯ¾P ,'7cé[èfl•ñ1~{·ÛI?UËäjÀÄ׌Wٷً=ÜÖNªSLÄß?j—¿µo9›vE5Ö·éa ä]C˯G]4•lçD‘-9¶FBÈ™ œ*p˜§\Rzîu„~"*tJasmXdª_OMÏ }i¶²*¡‡bª7oŸîƯ©xyƠÑEá5z}µœ60£!¡¹W“l,†‡~,T™¸¶¹gp@ơumjÛÑ;¨Ûv́L¨£‰¼æ‚µ;#U:Ṭªˆ, \ÇË‘sÇï&û‚ê™R÷QrOlzI%×Ü$ȤiÉgÜĂÄ̉•@₫Ô4‘â_Z$Ñ:Zœ0Ơ‚ç»ĐFđ»©Í¼ ̉+Ï7y“J¸Ă Ă5!eÍHqrHk‘á);Âzœ̉E„ (=$È0SÈfßø:dr­y˜]ôÜs¸Ó¹£Üơ±&‡âis"Ñ̃u’+ÙRœĐ­N¤àÿƠêJí²S`VÖÆáê/K®B¥UœJ₫j 3U>·+ôû÷´Aư/kôxœr?@‰Nàv‘l~̣MÍ·çÍí~,û#XUçZ>z|_ë°·B.ED>+>N1àåàidO/È3€ªtǸ(æÆîˆ½ƒrzÔ ¦?Ûû®& ¶w]Ḻ…5ó¡@N;æäJM/;Ó×/C2†¬_÷RcXµÉ12áƒ]Î;0DºÕ¤ơ0!S¸ÄÔù¾j×­tĐúó)5.¨·Â‘‹~̃ª¼,T(—¬Ó@…́Æöe5W–±ÓOzĂyf” °‘ ´C¡©e»)…v¤ 7¨p„3Óñîr‘Œ´ĂÁË‹₫«›P`ˆÛD34lD„lḶưÑäéíˆ×œh‘ƯyùØ–_ Ç6£1+ƠËZ+·@Ä»₫½-x1…LO d‰:=Çßˉ–Ïr|.ôE¼ …Y’ç¥r ƯM-UÜ6]iYE“ól¶R¹ËæÅj˜“¡_gÁ„…×ó} Ê  ÏÈí†Öü†„‹V†<p³u.Xï½@l7PqE¦Ó:÷ÿ‰>î€1Ë8ÁâÙ(³ÑÖ̃tôÚ¦뵉ë›G—籃ª'«ÎúöJÉœmhø É:ǹûœÙX|„œcD 0PT4w;eá]ÂøƒñFêđ LJ Æ,)ô(VX–©ÔÖñ)md#đ‹ÈDm¾\[¥œ ̉Å.éê±|TJÇa–¡M‚8!£_XƠy¯0ñDu× PoÉæörén8ŒM˜Í¨nêyÁ̃¡­y† ̣Éqtà°kúcJmU¡XG₫±¨·ôơ{»´«Aƒö ÷;è›·ë(Đ9PÇ€H­éà@2‚;ư¼Æ”“ϸA#ûʰ2„‰̣(î¾±¥XÛ8W {NJ²œ7/·÷̀|É¿£Ü" +™ +Yưë*hÊ{°$ỰÖB`jÀë ÿđ~Zÿ…«ËPYª¹4 †˜„&˜d½ ú¶"i 2Oeü³W­pHí)F©fáÏÛÈ„P4sâxToâ-+=ä%³@#ÿ_~€@ÅA> ư+5r„¦èO(4=%©·†ç½ˆ¶Ơ%¡Á—)Ké°4´#ÄFÇêÚwXY ÷tA5v-É=RăVk¨–_Çx¤-—2K¿ÎÚ¨6â#è´¯&ÚcY‘=ö_g0œ™¢¬ëzßÔÈMØç2¥-Û{ê~ư›Œ[ê–ÙÁ>[Hù;¦h{iØ^t¼âÆeâ\ũ3֜Ԅªûi"}Kxpç=!l¤ !‰7ç:‹ª†©5Ú d}¤áđÆ5Zâq,•pÊÓ׬C+́Ë°Ê”à „ƒ¤]‰–_‚^3G¶ơóoh̉§FKt•@hUœđ-æœtb®Ü ù‹‡ ¹è¾"PđlîºÜ=́zwêâ+32†ú.ñצ^äàƒ£̃Ñ$Wg̃?Rb³V¿.Đïß¶¬K+“U¡¬ØLW~Œµ!epAÙ6Á£n;cбñV…ĘWI,ôµ§ ϳôvÓTœË₫ÓIáⲹܥƠ ̃åê€[dR‰éHZ9:Ă#…<˜r—‹ÁͲ£±¡ óˆ S²C“9 RV#¸Ÿ4½€‹>CÍ©PZK®¸ƠLG Á¢ê^ÀÆ8ÖçÎ`«ÜoR ÙÅ\€F?åíáàs×'†`iBÚs=̀³ZQ́¾„í(b̀­ó,SÜ—ô†Đª V®Êƒ­&94æ¼Ög̀]æJgă9,ùH›Á=ÂÚ?Úö˜Åó2W™IƠV½˜—驼Ơr^Íá˜Ú3†ÔA[h€Q²–Ä,úH¸©ÄA;ÛoĐœ…ó] ÷eäcp÷µ‰ÀF₫„=µ­…\é@±µ«ç|öÍzÚ£÷Ù§«êÚê¬×ïÄ™¿@"‡ œ)|0b49Rÿ^¡5­zTVA:ø¹¯C u |^$G|b vwZ~M·Qr™¨±3E'6Àß/g‘ˆÍ…‡­̉U ŒˆEN&íâÛÍyüvB¶|b5¤“ĐuẾĂxE± ÿƒMw·›¥ư8ÖûöŸ ÔR7%̀M̉$YQçÀpö]u2.y¯KÓ)ø«û^;ÇÏ{Ï#œ£“hˆc‘÷^øJ‹  Pó`º’6,¿êÖÓ^ÉdÚŒ°wÉmü?·I–¿:ùÖĂ ±vÛ§´S¤¡^'.ơ‘^Xé8¦₫J“ù`øØMđ–·ă|Î<Đrwe¸å•ó›>›–@đ$¼™?³‰&ÍhÑÇîwˆevwXéjg\«2ÖâHû9·Ç.V–—DˆËö¬—ÏVÚ̃ á'¾}•ÓºÁ®aßÄ=ÏM ®&§/("¢Û $×og°kD´t6É^ óÈ–3 ¡ýB¥“µRÉg·*­¯¡°L»GÀ ÿÂx>‡¾z©ù̃/ ¸ˆu[V½ÍQ;ưÅoÓ{§_â¸5Ó']ù1Ôy÷ȘKÖ•œCoQPr@sox¶9€Ü àÈt?̣~é<Đ¯dÉ(Ÿ{›¶J¾B3#œ yÖÎ=˰₫ù„Ê9Â;&ªă¤éèh Ơ2V́f€K A¸ ‰ph›…;ơçж”đih¹#äƠ×%33ê‡ơå,©UŒ ä£\&w Pƒu5I~ˆ>©Ú‡¤Xˆ®æâ„ISÀ&úS̉“ÛÊP¸À%Çîè–Üo÷:(Á¹½BK¹Nª¹;ë…xäåêă½¿´¡?}î Éw¦i°nº°˜ă¨Œga¼ơeG"âÉ» Ÿøê­§è!8R½‚Ϥ¢59·£'ơäD#'k^=AĐ«Z_Ạ̊ >^­Wăñäˆ6]D¶Ö¦]ƯÚyÓ‰ˆ„,IÑ›2ñSºç2¶Ö¥[đDµGçôD­³m>çû3 ~!U₫ëúh^H&x/°µ ¡²Qµ%E×0ưgAÓ[‹×B«M½ ¬­ q5[‡i  †’ ¯Ä'BÏkv§ "Zƒ•¬Vüi`ËlÎæ-©ƒéñ­oº!ë+dÂÎaơp¡³Âˆ›Ọ́:KL~-Ơ Îăwn&–‡·ùU–U'@ÑôE»“@^ÎPƠ׿bềí/GxY}W¤8ÁÔÂ~R/GKh[¼úÜßbXáöŸ¿¡Æ£È.™Q-xD&*9EƯ5OR°'3Uk„¾Ă>7ë}ễ‰R¢BW}né­•¦9Ÿ#@)ÿX€†¯¨¼Í09kYQ)×ơÚ >-¡i¤eL­½Ä×#€îä:€~^SƯHy1:3i½ 7€ƠœŒl­™b©2½n\¸ÓăpIÈ›=ÚtI?`éY{Đäœ&Ö*MC ¨ö˜À²ÿ#Ïù b{₫CjfBđ;uôÁ·±w¯êz²[4Ù~o™- ëiå%zôơh ?}‰ơ§màu—ưrg=(Œư` Æ@M{ICζÈë…¹# pGA Ú¨V-Ơ?4üs±l5boV:|Ôo¨›ưVe¹äÇfȧÂÛÆX?Å7À'}¨ßS›EcƠJ(›¡ŒÑÊŸèuw̉ Î9ú·9ƒ•5d̃=H ~úÉSDâ@”ë£({b́|¡u a<³4Ë…-¿ÿ†/̉àº2zZ_>àÅrMÜa&…Uñ_U(¹Vzë0—‹S óˆKœË—J_Uf$F´5BçE&yµ¶ø¡1 ¼G˜B.ÉÔ¥–åƒÓh!̉=6jû<ÄÎÄC»%a‘W·-sWÎ1î₫Ü×ƠJD¾́ÑE@qÏj§ö.mN6EĐ5‰&køN‚g’~ÄgSø!ÓF‹â7nKmÑ“o˜†₫a§1Œ¥¸€X¨GĂE%[˜ó¸SB:{Nüf̣JÅ›  oÂưB¶¯₫rßî LÀöl×$ǹ¿Â^ „è¯Kǜû±éàBƒ×BâU'öZÓ¥N¸:Aà¿qưô£¿tpúÅ,Û/`Đsµ8YzqœœÖuÜ^Ÿ¯[«8 1k>ØtF’óăU œ¦flpœµ,‡¿–Ø̣½X'«Øns•=ÿú¯¥ »¡H”•ÿŒdll{ÑÛ`hp©<ĂÉ4á'’rxƯs±z“¥à‘ëÀÉDŸ­Kó¬[ƒNB}́ï̉Ïœ•êIyÖ¬ÁéÇâJÙh`)ÜT!†±5Ë¥S̉́̉hj1²gjl ²3Ơ°@CèAzĸV–=é᛽Ek!ÙÊw*9Ú ´7ñ@RE— &*T—×~ƠVt·+̀ÍẲùlTØїΨFi1Iª4Z]Ô6bưƒP]^ƒ8âá$°ï“âÿå1q®XV^ÄvºŒrÆU‡„=_TBŸé‚À:¡`¾»>¢±H”Wb7S:Ë’]Ơ±[nÊ @•H‰³™¦mÁ¯¸̣ǵù I¶Gó† ̀½—3j]F¦»[™j‰\E´ ^€*¡wyÅÏêÆÆø±É§)ôû2‚t²6¾́¿®½Ÿ/O¤ÀƯM₫ÏüWÖ|¶£„ PZéî†ö…›z'†¾æÖA9TatÀ⦑ o2œóR,Œ“1ËH™ƒÄ}fL[́«mîP;ûB!/ÜpwYѱăª-\*ÖƒjF;/³Ÿ0 $΀oM¹¬×eîŸdÜjW†.J‰äĐ#~ÈăZ¥ù¸-T“NS-Ê3ŒQ‰+v'„+ ˆ˜N:‹‰Zè]Ö›dåăPc¼t¾”„Ïàj×Çت ¹\jh&:₫léØ+©ä;9cr^¼qñd «C% ăíÜâS”kùÆlƒXmæßZvù°=¹‹ÆÎÓ4ó>{7=Bv–ơ¨vÊo“ñn ~.!HÊOb©œF} endstream endobj 1728 0 obj << /Length1 2262 /Length2 18413 /Length3 0 /Length 19752 /Filter /FlateDecode >> stream xÚŒ»P\Û¶.Œ»»Ó¸»»»»; 4î.ÁÜƯ î<ww‡à½Ï¹'ûÜÿ¯z¯¨‚ơ ›ă2»ªWAE¦ªÁ$féd”vrtgbcfåH(©óXY9˜YYÙ¨¨4AîöÀI¨´®n 'G₫è%\fîï2I3÷w3%'G€¼‡=€ÀÆÍÏÆĂÏÊ `geåûC'W~€¤™'È Ä wrº!PI89û¸‚¬mÜßOùŸG­€‡ñow€˜ĐdaæP2s·:¼ŸhafĐp²Ư}₫+­ »»3? ‹——³™ƒ³“«µ0#À änPº]=–€¿è”Í€cF hÚ€Ü₫%Öp²r÷2s̃ö  £Û»ƒ‡£%Đđ~6@CN â tü—±â¿ ÿ. €™í?á₫íưW ăßÎfNÎf> Gk€ÈP‘Vdv÷vg˜9Z₫ehfïæôîoæi²737ø;q3€´˜À́߿ٹY¸‚œƯƯ˜Ư@ö1dù+̀{‘¥-%œ€înå' rZ¼WƯ‡åï¶Ú9:y9úưëÙ ähiơKg-G‹PṆßï"„?2k ;€‹•••‡t½-lX₫ ®éă ü[Éö—ø=ÿ?g'g€Ơ;`È ø₫ÁÏÍ̀pwơøưSñß ` ²p˜­A¢¿‹VÿÂïwy Xß Àú×ÏŒ̃gË̉ÉÑ̃çùßÍeÑ“‘Ơ“•aø›đTââÑ?&>;+€•ƒÀó₫đßQTÍ@ÿ΂ơ¯œ£•€ï_ɾWéöüw÷iÿ½t€ÿ¥́ô>±@íŸ7dåbµxÿÅöÿ<æ»üÿM÷_Q₫/₫¿ó‘ö°·ÿ[Kû—úÿ£5sÙûü[ÿ>¯îﳯäô¾ÿÛTø¯uUZ‚<₫·VÎỨ}Ä­íÿSD›4Èh© r·°ùרüK®ơׂكªNn ¿.+ëÿ̉½o•…Ưû¥áö>«€ïKóßGJ9Z8Y₫µ]́\Ü3WW3„÷¿#.€ÛûZ½ÿ` ³£“û» à^ÀÊÉá¯~rsXÄ₫ư qXÄÿ ‹ÄÄ `‘üâa°HÿAl™?ˆÀ"÷½ÇTüƒ̃c*ưA|•ÿ ̃÷˜ª;€Eưz©ñqX4ÿ wZĐûyÚĐûy:Đ;Ưÿ ¾wÙô®3ÿƒ̃3³øâ|?ïư"søcưW¯X,ÿß+ü|oË¿åÁ;«?đƯÜêđ/%è;Ç_ĐóO<¶¿öô™;y¸₫#ú»ơ?à{¾6²¯³Íû₫Çâ]ú|/…Ư?à{-́ÿß‹áđÜß©ÿ Åơîêø>«ÿĐ¿“súsú»³Ó©ß³w₫£~æü₫éăh´úS.N¶K]ÿ»Âåđç?ªÀöNÊíOb! ç?Xs½›»½ß©̃ûô'úûƯÄână üGß“s÷rú‡Ă;YÀ÷:y₫¾SơúGSß½ÿqû{xŸÀ÷2ø₫!üÉèú¯£₫kĂ-<\ßëà₫÷ ü¾₫ÿƒÿ₫0½«KNa¶a]ơb„^LSBóT:tL~«®Ư¿P`SéêrB¶]¥ö¡ḿIÑ̃‹®‘₫ö;ko†ưÔ‘¬Öù́ÿb’¨>{Љ°2ƒ34]|&Ö4H OĤ)zèÿÛÅ_;ز¼GªÀŃEơ3æ£×€ŒwÓ`åúÄÇ¥µĂ:nÄ—Ê9¦X­ĂಪBóÜE{’ÏÅu‰†,¾7.µB¡dÿh¸ŸD¤Qă‹“ %̀̉n·}hÖư}ô«j ¹íM_p̉ûN€Ævºóaâ ª "́ÅÍgLÑ=Ø‹U¬Ÿd£íÏn3èS¤ËP,¼J@R v¿Ä%oÔ"‚²üK²é@Uñ\À’wÛç<1¸XUB4n哘ḷ(ÓήdEe„"K]Ñô ùÆWo¹ơẓ´oˆ­îl”ö!#oTȃ€¸Â¥ggBq†ÏËk:Ÿ±i†KƠ5Œ JpæUÇ[2Í>IߟÔẲ~ ̀mÄk₫‰B̉₫­",l«z½'¬rEœvVˆV´=ÿporŸ4 ’i7ƒßïÀG Œ²Íÿ*$’f, t¾ ÓÖØđôm CxÏí÷0mÄzp׌q£e“%Åăº•ˆ œï‹G@R 0±EÎzÚy₫‹%qœåñȲ²Ë̀<_µ Q>ÊœéU/²‰iX¦ƒÀ§G‚™”·k YÏ&œ¢8’Ä·®r”Oèx ’§qªhNi³]O¾‚vö=±"ø9»FdÏ›™Ëë­í[{¯Ă$±+_¬ĂRæĂm…„‰Ø‚Räø~‘™>ëSj¢ckèå¨;ÑFá—{‘XeJ…¿²EøÏ™o‹'Ê–C…FiØ=ZI\uU•B—ÅüsP‹L„› ¾$¤Ü¨‰¹xPÖÔj{ơúr-‚:©¦"_(û?;b:í«‚O]H …̃NÅ¢¤{¾n “îßè]Ăio˜(æÄV>öĐ×ÿ"’‹ª¨î¬vñ£«Èæ±6˜p̀Vàà̀âÎH»Ñ2P ÿ f¾‰nÖ Ç 9Q©ô{ƠX€zÍÑĂZ{§|³èRÈ-Ÿ¾®˜Û°1èó)xh]̀­ƠóvfZWA¯Ă论¡—¼'ü´ºóÏú›ÚÀW;~ĈX-ÔSs@k}ăw₫­ÉƯ¤Âtsç©U† ,Vôp1 KƯWđܪlEL+…;…/—+¿ăä™Áícc.û|È×j¿‘™P¬•y›Ï=8s)¼̉«û¸¥§Pñ›³\4‰ô2ÅÆ~AaúY•¯nfđÔΓ>À?Áí çĐơVĐ®€O áa© ÂG~3æ&n—Ÿ₫B'g•3dùͺMh¦è,æwÓ@PuI°3¦TAøYÜ—ø4'*è5µ[“—®Ï“‘Ú{…\\ƠCXËi®Ô1;à*ï$ÿûđ^eÑ)́²Ç)ܱ-tá†Oª¬±qH^v‚Ẹ̀X^±†₫àq1_·^1lLëu6\'û6hu*NAYàmœùĐnñ&[_s«È«YNGÍ÷f7p*aö}³̣οj‡ôYÙ·<â¯ó´CË”ÛÚN{KHkVéw±yåR§'kăˆó¦è”•}îu/€æ³‚³¶~yØÚƒu[†ßT v G đ6¸&cÖ—°̃ËZ¯&¸‡¼äóœ&‘¤µ´á›f$‰vR˜åœù ̉£ 4ÆZÇ!ºú&™̣Ƥ67.œ§øV“Ṃr9z[åO{™Î.¼CHFLHCEuU¨Œ„‹²ÄC±đÙYù‡+fl÷(¢²Ÿâ*?C½pÿï’[È₫É´´û6~­¸ñŸ°tg6?ÆË6Ư×V!JlÙỘj™82S‹H74°4<˜Œđ è¯1Lư[‚hµ¿̀tn—2®y6÷ô‡‘’1,,é•̃Ñ^ë:~ơQƠ…¦”é ß* Iú´s˜*âzÀDq,·¿¬ũGƠY¬đs…Œj‚¿/^RÓö!NĐê1³à̃ë÷hûGG3đˆÍ†pVÂ~ù€đ¼}̉´SïÓƠ¹>ÇñDM·²ÇµB®¢åœå?êĐT(ßø₫™…Zĺ¥ Ÿñ4¼Q öïØ-Ü-̃Å€¹ËÓ7¨ª‡ân—â6µ¨ü¹˜UW[Åé›®&±ú­Ѱ©,—©ûúGíîAÚ³{0*^ŸmANY:-â~¹_I¼_́Çă&ƠŸïưî¦|ad³'‚J  ̣d vñ ÿFH“̀ ÂüÆà$Ö§Y&f¥ÇUÏDEF¸\Œ%‘´é ¥s¬‡EœRå'¥Êûù ³êîçe…£ï¨ÁOPÛ¥·j¢»_̃D04A9 góÇè‹ wklYgeÖỮåa«vßưˆH³;r}-Êfϧ¿â. @V­JcL‚F,ïí¾!31©øÄsäàç+‡;Iµö¢>W¨¡¯yóÜs„t‹±‡‰ÍteóĂ»Ô ¬æư¶ÿø£¿Çs˜T;âSÔ~üïæ̣]d́ä£É+.¬ùy¨J=´µ³ `™eˆP€›Æs $fI-K(…|ëFŒ̉ wĂ ơ.Q¥¥ææÂD›Ü¡8»b_¤M¯v†„©T>X/®LçÎïÂ₫!ÊíÔÚo¿ÛI$ÀÏ™KË?“dVweÑ̃,­uđ+“ eÅîåÆQ×ËA:‘¥æ³ ƒư,ü´Ê6"Ơ©Kï—Jl)e'üØ—z­'à3bí„ó´ZÖÑđÜ a‰:j3*©ÑyV«íó1éáÆW(`2Å–ơ3ơ>B‹÷¾­G0±n´6”ku¼$Ínˆ‹àr Ê=ø³^|#‚b âĐùzC…î_@»Œ¥•(ß>•½î4½‚çɉe…hât%  gQ¦xËcΜbŒD_‚*c€^é™´ôÂ2|ÇÍơ—½̀æœƠø8ѪáÉ$R²f.×qÔPœB0ªÈ—̣úî^’Ç\M_¶/÷«4:YÓtz—ض¾Hé„á P%"¢R;Ùwá±&=Đ|Cn¥ ̉₫5¥Ư©́t<¼vg?´‰g›'$à}ó:Ps—=ÖÇz@³J&së̃عb%o„N w?Æî·Are‹åeI³̀ÑÑc³ÔzZN™°9Ñz ¸Ûsmûì¤dÇ5µ f¾×äh¿èÅÅŒ̉ÓÀg†¦Ù /ºDW\ƠO‚Q@öÍÄ’†~±‘Ï Ù0ˆçBˆ_*̣÷YMĂ›đ°K»l¨‡[ír ‡@ßđEBb̉xú¡²;­c‚0*y% ̉ ê[‡)†Xz´º·ùè•̣Ư\V¶ ­|ÜfÛ]£û(¬Ljذ™…9èö Ü«Yƒoú‹Q­Ek7ôÅdơơ#ÏäúGLÉEFFđ´¶ƯêÑås]¡ơx¢1É1¤µáSˆÉœ".ÂûÑdç<Ù4êÓHüI io]e´ä ÆZl8&CËêPÙRMBWñ >-ö̀‡Ư¨Eº™{v"¸F̀öw P û\ 1}÷?ª–́!Ư¯zí˜ igaéÛß<¶uXz‚ÑÀ•~R!D“êuä™Ü:×Ú‹̉J>µZƯü¼Ü%…‚:ăư»Æ¡¤³ÿëǵ“̀Đe’ÅêfgDËÛø½Sô‹Bßë<·S·Ù'ïÜ—.»ŸOa£áº¶uưă=lƒă\Sô­~Éé7î̃­#¨æØK½söÉÔÚK%²Aµ̉“˜߯[a2ºLoƒœ¢­M.ê½o¯Ä†¢(feÖ /”\S”6°¡ÓK¤´¼+èü3ÔK­àéơ¤ÇSe11¿¹¡0…"̉‡}bL¡ä„ö=;@± 3·»&̣‰×”̣eƯÖ5±Ö ß̉Ǘ‘úº³ÛơX:u zµ^Ñ̃$2 U'Æơ‚ÄX +Æư¥)­·<ÚËêÁˆˆ««™¾5w÷@ÜOfÏí 9Mû˜ .OÍ9Wv0ơÉW’ö¨sŸp’*Ơ¦Hƒ¹h§5—Uæ»8-Æ›º‹ewUÏ#Çq~ ÜnÂèMÄ÷).{ó±Ñ"Ú†ùy«ÂƯ/_-̀énZkĐ]Èê¦=˜÷©£*Đ¡JnmôMTʵƠ(̣Nåªñ+GÁ9Đ\¸WtƒƠ¬*Æ&à_Æ•ĐÊ~e¼œ ª¶YΠآÉ$ꉀPqåGÖDơœä ?•#đVạg­ú×BÅ|¦=´AÓ·'D¼oœÔu’ü­–*ÔàߤƠØLœ?Ù 6 ¢̃‘XKT2Å|­b e=8¨‹Ç·0}ŒuhAN$øï ‹3°Æ+¡EƯÆÆ@s™KÚlé´¡uæØËxÜĐÆ«o”ï̀¤~êWz¾̀Ơ’®Ÿ¹Øn©Xéä¶p ½ư6Ṇ­ FÍá$€ÎÁ¾³ù³£ô…ÍugÜ1 ‚”.G-ï*(}¥¹ç[ÓÔ×3/–¿ÓÎÛâÄ—́9iÎ8ëƯ;7Ɔ™ĂƒH¼Ü̃̀̃ơ K57¤Ă.»âóp †PŸhđ¤ú̉đa¿ÂkRÉ,ÈA&"_L‰đ„‹ÆDs2¢ Y+=E±ÙÀß.¡GK¸¬ë̀VYq́÷NŒÑµÖ›\u®£Û~úŸ„9Ô±rmÁ̀9Éß9ÈÆÜH4·:yø!^c¿ª²à,Áƒđ¨5‘íz?“]Ûé»&ÆAQ¬OnyĂÍ\‚PV́³ÚÉ¢QÙw¯_‰Ëô²1²0C:Ư`̉ë¥bq%ëd¦5èéD•y#¹è$†Ö³ñ¼î[æ²8…º¸É•|ƯặŒÖÅä錓s`\ƒbèåÓệ%ŒÔÈäº1ÊpqÔ´“rê¯3£bô_0,¢Ø×´Đ>/ LÁ‰Ç¤÷ H›ßH/Ö¥&̣̃áB9êæ·¤Ë'A‰)ŒcîéûB²Ăœ˜Ỏ i\î₫$8X…דó8÷ÁÓu«ÁD$™`Ë#₫Ös;Ï_,]kYwä^~§L)o] ưËQÑmßOÜEòÈ?µÅêUO|Íơ,.ê"́₫è+̃ø-W£³F LU¯DSc ?B$ßû—h0Fêó~¾ Ÿ:D|T:4–˜v4)L_äé›CèËkU\'—ùÙ˜»d̀ĐÈ¥uÍ»`Ù3U¤{ĪñÎXĂtz`´f!Úo $`% úI³…±Ï¢›_Uøs÷]Œăù•JùÜ*‘^Ăóg]DĂè%“~ée˜ Í ‚É™ KÜ .ăÚEgÊŒ¨BˆKG>R(đD“æ.œ₫:Q·M̀±cË> & 5nÜ<ÆW÷²B‹¢åØ[Đ¹q3â‹—z¤m])÷đƠÄL¦/è1©‘)‰7“‰d%eL₫÷êÚJ®Üđ–”è¶±U^µ@‚üØ Z*fSæŸ?Ư¿%#˜âƯŒEäÿlwd;° :úήƠsw>P8>9́cm©ÔC¼®~ÄóêóRñ W~D±ó¶ˆÊÍ|Ó.Zèå«–ísá­g-Fç¸ù<ơăÇrĐböƯçPæ`,†\QjÔî¨DĂY£o¹æ:Û…dŸ•·JœW±Íú/Y“¬â»́ă7;ç¤$c‘a%\ùoêo‰ÑÎƠĐ „öÁ±¾Oäê´Bâđú‘$:Hh­´ ´ª¹¿îåÔFéoWb Ûe5ûëAªq’Jbë§W.qö~I‹`ºÀqjt©lB",µWkCf·©n‚ÍơL[‹#uOKxÂÁ·sú¼Eº•ȲVÅÙ[J!Đ/á6à_rh~®ƒé́c²‹ äS_áà×}ư›wXă£OÄqÈäKÑGjÑlI WNÀ¶±(q”yع” Ôăµ'ópŒ­₫Ơ<ÔX̉OF]Æ^Ô“%ïoaZX\`üơl(§jrÓ²ô*½2¢°ƒÚKĂg¾í0e£qDâ”Ù¦/ Œ˜¶†ö1)iË)›rXX\̣æG¬³Ïf³Ñ ŸéVµ}»đƠï_›ÙRgåµ.cd ¾¹(eÈk¶§©Öt.́T¸Á/Ù%ÄE‹‚UÚŸ:Ȇµü~,=j8(÷¸@)_fH¯ë÷W½¨vóqưêX8€à9$ƒR“å/èl`̃Đ_ˆÂñBbFØoÛéü3µ6fºƯM˜–2A•KS₫DC¾±đ^‹ÿº]“Œ ®%_!5~tóàwädƒN4Y^¾µKĐƒ;êư³Ê×€@£*ƒríM>ÅđQ%¢úBV…rT¦0p×̀vG¿n„•G{üüV¶̉điVp̀ü$\âLËÎóCǰÜ+q*9¾{[´/>6ZßÑ=p¥FÆ̃ÄÛé|…ê×v Éá*ë“́±yG‡ôïëê©ø̉íPvGó#FÏOFpœ³µă BÜú™ƠṆ©IN¾ăܹfÎṃ1 6hHÄQWæÄ)₫"üà°Ä˜xr\j̣ú™ˆ¡ Á̉60&ñTç9ù̉ w„”ƒ ‡È7åb!™ ŸÛépQrY„̃Ah5Ö€¶j"dˆZ¤ù̃qØC¬‘µé阛6ƒooê&8÷Day¿Täeµk+‚pÑb•‹*·»ˆ£Ă{4Éß7i‘{±Y˜t~ĂáË,é|a”a\>ˆµ < £4Đ“JéˆEaÓv€ Đ[ A#t¥ªéƠ™±ˆ¾Ôơ¿¾²Ụ̂”ưœBVñ†Sº½Ût§æ—IĂœµ&ëiÚ.€†Û]%j‚EÂèÛ¹‰+ zÙ¡`Ä…¶Q˜‚ç±Ëe>LPE.̣¡6¡X̃ă†̣ôÁú傦-­†EÍ=öèÊưÛ“Óø-˜ñZPsĂ÷Ÿ ă6ÚmṬh Æç%§\NAW³ÜµŸJVdøÛÊ)¾HÖ 2è„Züq,Êw9̃9 vEÿ]MXEØï¥+’Ü|eGĂ®-èv[M®–ăéÖ&7?æ3gâ1­3-–(=oO²¥Ωÿ™G÷§óèÚ7tµ)W^¹² %å.bäḮ(o1&¶LZä%Ç„̃½›ø/•¨Jx¸¶4€0<ÛƯq'qC£Ø+ÛƯ4!œ3èï¥Ơ“wpW±ËY[/n“7? VŸ&ÔH~ÀÖ4⯽.y)˜µî°ăÔÙΛm«|-4ßrGû́÷´îe đÇ Ï¾ß\d 9ô kçDYMI°óÀ:V'àœưG¢̃°A%5Mñ%É?‰" <2LTêGơçœá\“^h䳇°njm 6(Lfa ¬î¦4`©YæcÓÆOPªæ}åsRBẠ̀ÑÅ̉H—-»c&zå0ñHAˆơÖZáMÂ+ÏÊL‚=üy~ Ÿ|xˆÀµ|̃âŸÅÄ\¸+’¹}ÂG_rMm”Øsåû‚Æd́Ư 1¬ª±Ø¢dD^j Zá“9…ÖÇ…VY?Ù`ƯÇ?»Åm¼µZă[‹B›cFÊÏH¡@ÏK)×´Ü7Ư(ä¯0‘ȲlªÎ昮=́iµ̃wK°×â_tÂ;8Ë Ỡr¢l¦ypH]^ƠÎ ¤¨v&¤ïë4lùçH·Ä¾̀è—~$áÿª^J`yèd.Úß:ʺ[<ưKœ"ăîC—GQ´¼œnH›¨ÍâR₫×ë`ĂÚ¶@N=¬fDW€´¾Ëlظ̣Mbưå(—`ppëGœJ³6¥ÉïE‘6^<ßµP¯$́îfÉñ»¥p47ÿÓ#œ‚½‚ă$’Lđ¶$%ăß |¹7¶¡́D2túv+í°eÔCÅz¿0j)®{Ơß'`J…ï ™‡ß=;đWM}ºè-ضǥüưæëV¿øm濘$y¸Î#|¶%ÜX¢mi0ù6¥úđ.W2¥‚5xơ¢ÿđV©û—|†L0á›R¾#å®êfÇŒ]`\Ïy†ôªÊ:ÏÆØä9RKG̀‚ÜÇ|'1:ö”PÏd}{¥ÂÛgÁänRéh6-×3*ê5u†[„n’Åv‰¶h ̃k<.^EU5Ôg¥dk ÂÖ̉a¨;V‘µ!Q 9ª è÷wsäú₫R¿ÚÅP̉.E†¯;äÍåơ“óvaSoói¹:úÓ9 _–-U)®-lʲlưä›MÛÁ·²H_†LY‰4 dô¹öÁ¦₫À›ÉƯúi `˜µ8ºOXDÿTÙp÷f·O`ËíE)#ß2 3ư4â[­rE&ú >íV’}¾@;¾âHÖc¢‡̉ÜáđnÑ₫ä! ûØZ@̀HËô»^i¡>¾s÷ØÉ¤»N²˜x£ÎËCà́K”CùĐˆƒNN=cOåĨYI²îû¥”¢₫ơ–³¾ 27†:§fär8â`<ÏơFC Øơø#X]XjAäI• ²Sè­9ªỎb>úçÑcy›3‹!Ÿ ₫C˜Uî¼M¢û1$µ¤¹‰̉^É÷wư¹Ø±àÑ–­åPèî¬Ow˜drWŸ¨-¿~ÛË¥f…ˆîCOo×Eb#AT#˜Ø÷§›ßieµă*Ñ4́h̉ÙŒ…đàv @BHÊvY#Däñ0„…&yà², *ü #DØQÀƒ¶Ë‹bÔÉ‚™äÖLđÿí¶g¬2đJ‘!dû-´Uߥ×MLóYạ̊ ́1‰vÆpúˆ©ç+[¬Œ]-ŸÛ ¾ B‘94ßỄ &ÜHù2]DÅr†K¹ú ú5¿‡Ï%ưY)n;æR!OoPù;aå—'àK#9.½¡FD*;·(Ǧ4º¸äÔ(8\bÍ÷êØMÏ:óh4}\¡+üù°3Cû5†ZØ %N.ú|;”ØÔ[‰ḅ·¥ƒ.E‡IGÈ‘@ơÅ©Óabb­ÉDï²̉üLÀ–́5ºzJ QJK₫Â3%%#œ£rQÂ,oÑoÎ+,Mí¬¡KD(öj{‹Ë&kׯî‚=ä«sK&¿s§:Ñ€-á ọ́¤Úµ¤ IѯâVt ̃(§N$q.ÿÄôM<00 µƠU¦pÀ"Z;„`³]¬PnƒĂX4²iQ‰ÀđöÆ#Ÿ¼Xê^ ÿ0]ùÊ0Ór„X –±í×,ú¯£x8‚u@P¼°[̉ç’%Vwn‡ÔÇ:ƒ¯Æs?D”;ưº&ÍN&ú•Í̃ ´À9÷#ÔT~‚‹Jé»h+oÚ?ÄÅ}º¼¦M®æÜ«àú+Gơ;ztµ¨àÈÔ[ªBr,¶µS†­×ÚåU8í·†ßăµ T6æÅüöº;{pkZUƳ>^¨Ư¾3\ÿÂyñÚ….ïÀ¬èœ Ï9ẽWb́s__¸Ær­̉V5n€Ưâ₫ 5„P d˜|₫Ës3&?±ÙÂZ|’[6¡%piXz˜_pø£́Ú!³Nd"` \́z6“¦WÇ×øxtư‘˜³`À»Y0zíÀ¹Gr^ Ë”¥ )«¨€^öjc̣̉èÀ&8A $₫sß¶ÿ̃á®ư˜‰.Ü¥®»'ç53Œ_8ƠŒïÉWÈ¥MÅ̃ÛÏơ“ḅê-ËJ| Kç¾Ro·4₫;+ú’á•„¯&x¸ˆ*\eØ4ÿ|¶©w›Ă§ĐÁZđPK²Eü‚ỷDm̃s›µEb=¾»îª^¿©fR0½µÂ<Ó¢´o…£äÍçñùéújNôư’Ăî¤IYSÙ† ¨ÖpØ%- fÎ1Ö ­ÄdƽÔư™ơ¡̀I[EªR¥Ex,D¤ṽ‰[y <%§‘Gsx́ƯEÛÎy'®ó¤±o‡S.jO3±R<Ú6×]­A …ë›ß~ªZwá}Q_Rl²´á˜cGAƒ5E²@·ëÄ(ÿ K#ÀîƯËÿ=oyăCªº “Ơ¯Ó}Œ†Û½À„ÚJnÔ*¹ºæª®́­ŸcƠÙ¿<)¥ăÏ™eî(¯ÎÎE"+÷Åͺ2N'ƒëïÎYjzÆ7ÿlcCQDœ/êF²Bă“{ÅÀ́öë°ÂzÙaÓÚ›ZŸü?|ÛSƯ ê¼H Ưn—ä(G…¢á=¿ïÀ₫Ê]Z¦„Ḅe'Xmb¯àÇR-z̃èü Ù˜¶äG?»iLÉ_ç±n–đk‚¸än[ËJ½”äîU9®[ü°HÛ]Zwø”¾-wà¥ÆŒ¨è:Xé&]q2ê~ùD®¥;£N³4¦5º₫đQ´dƯuº§́ù–ªä$–»‹øÊ.£^¤Đ̃~Ĩ_†ê(cÚ́îxù寮ç̉¼Y¢g§@. ÿ3`ä–‡̣"½ó¡†ßv <ăˆ>×vØ¢ÖW©BÁ”Óú—°7vƯºÏú  ‹¢·*XĐ/²Û‡”D†#Xé̃$hÇDÂ⢖†À!!«—<³TæÈÀƠ¸OÖ_êIĐ½ÙlÄU'±xÏRDô ï{ôăû9Zœ́ùZI"¥+Œ́K|Q 23Uï¨'x¹uªăX1Øœç^«èÈŸºê¿œ§ñ$åºÔÙÈö}ùÍfÜÚÁZi¡zåP¥…ÊáÙ€3²Ô‰ÿ™ưÁF2ç)j(S¥9ă3̉̀*·×qI:O‘ÙµrÚ}sëØ§­̉è́´fƒiFI4= oÁàz£Äet̀'^ÖíúÎ2S·{sn îøØ·è±ß¦pb@9¬V‰n,JRk42́ưä:B₫ ’¦Û+ô(_ó„.WpülïsfơÅ {¼Lwôïóî »øàiÈqØÄ1yü¨/&‘Ùä¶ëÅŸăKpÊ€ª÷ß7́7ZZK> ª\ TPơ÷n-`ài¼˜¢,à|­BM©ø¡!¿ô½&'ûS¨vbkê|KHâư,O„ưyÉÊñöG…¡èÁ˜EÚ’Xv¢ßŒIL?5Ḿç'c©2ơ„°á¼¯Ö"J~ÿ́Æi^{he+_W×Wé€}߼ɦ±<̣À&>SmºoÓĐöÜçƯ ÷~?̉ø8<ŸÄ¡$ÚÖéÜwµ%µ¯lW­Ø_FŒÓ°ûü‚ªÓ½´›pé[áKÍ̀…Q4nov˜—L˜Ÿ×4MiHÏp=dI†’H%TkK¶O’@{¤ºFÅRöư¡Û|¡°¿yª3¢–†´äç—û»Y‘ÍFi‰ê/öÄgCƯÆ¥_±}9+ É"e§5LÜ%Tđ4,ß¶h́À «,x"ä,ḱ)6£/¿ÛêÙc:.|̃d§ ¢¯Ú}F;A½ëo–ù… ár¾—¦º‘ửSñ´WÑđ½¤îBđ!•æéS¦œQ'ÿ´cL^l6RçÈ—đoW¿Sª¨«b.38v̉’ÑhHÆlª́<à—"S¨÷l™……]‡m—¦Ṭ™̉&ŸIÇø|s€ä,¸ăÅó -±æ̃́ ª˜Êçµ*æX“º£À•', ĐÄy·MŸ¡ôZôÙ{ ‰W¸¼Ù&”› úOeb₫ó¼ïÓ5j’ơ¦66cÈd˜d?á ỵ~z{}°tZ¹®î®`AÛ•²—1묆Ơ1iF¿…ê?dñÖ•†Wúw›ë‘ZÈ.§Î8Èd»²Rb¿6¨dOk,¢ßmĐ¹ûĨ€½QÁ|/ÚM¨cèÖËBa ÛăÉg_h „ü¨åØjº“™´´³+µ-»F N0ªè¾P6 @¤™á B°à,¸ư¤X;œ9Ëíö_³ ¯§Ǘ̀*®E Ư”âlæû¨=Z8´×Gưø¤É®†‡Klă#_&ÜLR{2s×ÜCF*h—M¯7ŽLËùnLÊ:ªÂ±l×)‹ouƠló‡¨~²å54D¹3Û­<đ́™Dc–Ÿ²½<÷lªªºkL 8ûB·2ξûÂ@GïÀ`-µ7đ$=Ó&}–'J…Á Ö¯C)DÉüK©HGR̉ö¬I1KxL÷0ÅcĐ6OÙ& Ü ¼0ˆ5¬_ÎA²¤äi ¶„ˆ@I242ÆÚ)ĐƯaÔ sZq³)™¹„ ¬¾½ÀƠw:ן·"á yè+*°É Y›û” úÛdžúƠơy±£L=Ư.ÂÅŸyêÇ’=Ự½¸J€Zj~~üÉ2U¯#°=ö’Ǩ Ơ\mÜ”¾a{öuŸÉ¢B»r¡¨ u*Vü*¡°ÉºÄ| Ẃªlû̉lbßÛF>₫p¡âđ æ¹ö=| †ç“]f¤Ÿ"Ь́ÆÁÀ䤩 ³?çïạ́iå˹èH!©2­<=µ§pëåcNƯå—nâ¥+sà lѯ,ººÑÈH¢*Ö±Ê"\œz…¦Uy©8¾Ä@?ßid•øĐö¾:äˆÇLKƠV»Ặ‘µ®é ’†onưv|óú’Vd†³ü¦°å½æ₫K9"ƒ­¸§̉̃JS Ÿñû…®T›úđ}¶m¡[6 oÓk#|ûëæ‡Ï¸=Ô‰ÏCäwE‚NvÛêø>9jSÇ…HÔÛ]ó€©{§À†Ú#?D̃lNÀdr Q³ôÖb7‡O‹â-7oûl )÷C5{l¦}y:ï0a•n¼ôœ{)%̣ËÑ Óå;_̀q BÎô›•ógXRnÍ]̃狺®w»ƠTƒÆ½ô„Qn"4ƯăÍHå,oW“}Ÿ•û]7}]Ú .wéö]ŒQ¡ÇêV>CEL’̃lÍ»_úÖX¢W[^Ï^Ë¿ÿHø5ZàǗ~zô1̀‹ä¿•ƹư=™Œ˜nSxí6²¨:©]rÿ·{_jé²G®(̣=¬~l¼Ü>îTÛÖảá\“ÔĐ#ùâ/•›¤­ëKEb" Üà.¾búaẤVÿ椵‡ëä[${yIî¡3û§î]…#XZ;¼‹{£±n”Çœ‰¡Ă4<̃l¢åê/{º†3`9ä¹Ë‰}ÄÖB£ØèRỰâ ÏW¸¿i+ŒKaÛ›+“dncFöÁ́¥• ßâ[+×Í÷½î1=¼»cqc{Ơà.P»ƒÍ]"z-ôjt®Hg>5Ă8±đo_û¨rî¥đ§±±ŸÆ­§cÓF;( -‹îzåMa"`d»©bXà:̉…-B›É;-¢₫]­Ïæ[YY¢„ü½¥3Y\}ÆÔÚ†ñN Äk;F¦¯?¾ă>ẴQzp{=ªœG}ü!äºuŒ€̣lªÊú…²ä•¼üíƒÍ@¹’ÖÈWS/wÁ®cNlü—pú.˵ģá›ñi¯]F‡îPêÀM&Øü¤ØvRÁÖmFà=cÜđ`taÊ— MG}E¬̃Â+úI–·x‚ăÄÂ'I$º\Ê”jÔ¯‚'ăÎ.¯ ç aµĐ¬§TóĂ™™æFŸ€L3y£×£÷ý—|°.‹ƯáíåpR-Yøsx7Ơ›Èo²$uú[̉¯Üù‹f?6`dÍ‚(é„lX‚.|íd¹‘a¼8ˆ˜¶éë²ïB€à#à à÷ÿB~´`øHUE#̉fÑâêÇr6Åø5*vÖtm…Đ{ˆÀßÇ(ÅÉ8ÆSI樂Cï©}´`˜µ &öaBÀUµWÿ*Ê©±“Ơ‚fŒăi`̀üĂácFÛq̉›‘‹̣đ ,Øç£%Yༀ3ÑÆ-ø¤·Å¨ƒS" Q«i Ûơ˜p•; çĂ“åˆ}Á¬ÎÈêóP8Î`!5ñm³.ZK™ ÷¥×V­¢ÿBwH‚rWD›¢êüéÙ­ÏŸÎhÿÇIÉäv½SÀúø<„™` à¤ïÇKÜ 7töWùƒơ₫–vªiëlÇhÓs‚“tF^Ü;jÚr&*ƒüFÖµFcíÅă«Á¥—ï̃0¿\x5 ÖgI£º ô–?>_³¢æ7K%^ưŒÚÉ zYeƒ9Äö ‘7\‹JDÅ̉z+« êö­ƒ„³jñÅoỄù¿uœEî586bÿ»1ùwy*[u$½ ï¶Vÿyo[+’ÑíĐ à5½psˆ(€›û^Vº“0/H0²•OôDbûί•²;ÀIl—±Đï⌂S嬩Í0a½pâ¬Öƒö†xJøÀmæ₫Y½GÁ¾._2]åS}́¨D-%K…Ák_ükæ×N«Ô}v|3xI™8¼4ư‚ṆUê½Mduoy« y¦Qpæ A”6„ạ́Às¹èº$ñx1%Ë=8Y¹N4Í3§>¿¦ØY57wÉ@Ûë'óΡoˆöÅ9Û$U¨ó`¡6Ak¯V}×­_ÍbËă¸áË8¡nÖ|H¸Êít¨q»†órù÷ĂGM«ûÓ1+ƠHƯÓàÄb¶cĂ‹Q÷£ ưCuÔc Âñsçæ§-‡üăñP‹BçX́…*‡`#[Ḯ35ÂJY»1đN‘`r¦ë3>6n )C;¶ƒ…;ƠŸJˆåSrß,µ63™¤”[bM³¯ÔA„¼äñ%ø*ZwAQ& ølA¨9» ˜8oâIÚŒ–yHüÉ.RY¦m^Ëj»Ic¶Ÿc_¢Øm/d̉é±íŒê§<öa µûÑ™ô8n4ØÊ/̀É]k‡"R2E_8³äöM^ÿÚ&vó ˆÖă²Qư»™´C̉¶7(… ¨Đé&q¹Í±úûêÆª"÷‰ÜŒ™ưÈ@FÏÅÀ§&óyΏ¹çTÖ4k‘kÀÀk×’‡]̃ËÑ“¢6yƯ@§ Ä2W¥+o^ù:Œêô憮lØ2ÛÆÚ9›ÚÓ¶|3%¼ Z‘È7†áY<R>€ºª±a¸ë®Ơ¾ßŸ+n¶̣`«2'tÉ&?ị|hO Œv€•¸xÄHË,Ioë¼›‘ă>Cøå¡•(ƒ9X[.́̉-ײ)âNÙ´Ô¥Á~prw:Ơ¸‰¼¦a`W/ÛƒVFïÛ A ?6Œ_zXQ>kÓû‹}Êúƒơă-ÄuÊYæ5SB¡MóÈA‘0²E[,èCuyâ”Í×§Đ!_¢q”́” ¡Ơä åÅàÂ7„KhGMÄ́&ô¬‰kÉji/Á¾´åÄè¸h4SµÚSXͯ7 %wBÚ™n~.1»#ѱº+Sqîö»Á”¦É÷W';·=„̉;J^,œ‹¾?yµˆ‹Ûª¾½!yÍ [+‹ Úëwy´(Áí¢7×®'¦´Å!h®åå\4”M^À€N¬.̉ƯtG±øë¹ƒ‹Dø è¸û‘ïÖpùº° Ô1¢ó$H/^Øp%­œôöÔ4$ùªŒåîϦ́¨dÚav#”Ö°m% ˜˜Ư*Úà₫ˆZ†ç̃2矛'î ÇLcùˆ:©R„R]²©×¤é•¯ñ5P´v9œƯ Ó&‹7ZWSÊWèß.¡“½…Ô.Hv!4ÊƯs”3¤2°ơ~9™Y«´ÖEjơPjîé-]çJ÷r)›ô–fË8’Éüđ [éed/Ú¡b£Ùe/₫Ê2Ó«#ƒÇ›U#p„_aÂmPmï.¨ëÉ´«át1»7Ư}₫9¬YƒtyÑgH&„*; ëø ˆtM^+{@¶@Ô“}ơFB)5¢‘ÏpZ§çPѧá‡.̣ øŒµG^d%¬=̀?“«Y₫qZơ.D5-"7§[oÏÖ,1%¾‰FœÍö"¿ơ×ˈ/mú÷*?©çÙ åyÀÓÜ0|úVØ_js1H¢„m˜R®F2±,;Nb(|_¯ó .̀ër°Ât̉ égºdZƒç{½0ôÚ¯ ¾2D–ÔGß(ư$ÉÊ%>‰ơwô·fåî=̃(¨³ËøErƒƠÊ ×¹K%O¢±±Lü¤â$Ÿ#mÁ¥ßÿqHöx´lµ…Cƒ‘Ü€½‡u" -÷·‹©âtĐ«ZÇ#ÜĐ –Ä̉²ÜOè%rkR ¶üŸØ?ÅâSUzW¿f|$¦¶A%´gc¸¿áA Ơû—T0¼²Èr¯üơ×Ë7OU9S¤Ü!̣ç2\xUÑpV•@Û‡–üttÖæPT'ÓDéơk¸ăWÇ×Ó2d̀,Auë™V$«(ŸƯqÓD›¢–µ¸¥÷êđC~e${/I1“ÅñcD@Pç mvk‹üáŒKXbÖ²ŒÏ€M&WK4ñär²Ađ¿̣‰«†»ªim^™Í´ËÛ—~±å*»ßœ(î{Ï:;¥ĐI1ƒC₫ăÂ*̣8Mº¬ «÷ƵÂ;†Á́ÂK§­¥DĐ g 0x„NđÄq:pËû®6Y„W·#Œ`NêÓIW̉³ÍÈ?ç¼û<̉ç̉¸gË-ºoX²Z×7©iĐÄ’åÄäĂHL,tswµåN÷Q¸|N:¶ÚÏ'A}™¨áß¼6 øz»g lY†Î™2yˆd[$góÖµuÑZ¯¤n-BœfÏÚ®|œ† Û}áàOAs‘iƒ“ûVæw»Ơ¨6Su¢ü̉7Î/Q äh8kÙpÔ}®"Í¥̃{;ă4Í;‹0„Q=úSKxƠ!YWbJ=ñ₫Ñ¢5¹3ÎM£Êñ·Ñÿ=Æo³ÀĂ.^;&}†7ÖƒÚÏ|_µq­îÂÇ— "5Gơ}ơEó[>[AuË8₫3«"̃]™âà]Kª·lƠ¥ ¸_­ó §l†b€%t¯ç9ëw¸½³‘ÿ=„slë%₫è;é툉 ¼NüS‡]U¡ÂFL²÷‹LI^…MŸob)ˆK¾K)mèéRøäC’+lêÑ\®/Ô‘Åæê`xc«;“¾]+`—?̀ưê$aÇ:>‚ß¶<ư$¸ïS²É弃‹´!Bü?† yô7™­Vfcøï•;’§¹}}7®è"Ă¼Uɶ¾ÁÁ'§º©C&æ#=ZÅơ¦÷j8Œñ7́àÇâKâ®à‘e([É„µL{̀c~ÓQọ̈FưÙDĐF¾₫Q­Ï¼ïMVT.f̀ÜâÄDvÿ7Mt̀ `©•óWÁ‡ÏÀ,Á¶‹¹ø¶Y¾cÂâŸ̉é=©–S¼̃9|…NE7ó±=jöÊ4¥sNJÑ`}äÚÔăZöHƠ/ÂSû8#æä‚ Đ,¶)#ª“×$±Lk 4¹–4v-´j‚7ùíO¼5‘¥C"ăá¸u5¡ÈNäơîçü9¨ ‹cŸIfç=£óP½Aó+̀ÿă#ÙêCι°đ|Hiö₫]́ỦI]Í‚­!uÁŒǛŒđ™U$w`†h°ls˜*­®m•ûÜÍáE ̉ d8*7ùyWijÔđo+wï!­eD¦¬Í&ƒ»”¾`¿¦O5÷fUJØ•H3„ǃŸ½Ư .ÑIjVQ¦T1¡XØKîCC Øb°,i颯n 4ë7U³œ…‘Vè$Û’Œ3 @͆ƠV=î ˆ —ÆƯÍød.̀­P:׀ʨ'cK©Ú– ÿ }˜ÍÈG¶0%ÆIP>V—ưÄL;2¶êK ªà:˜đç‚!¯A(l#h¼Ül!̣QRợÖ‘f±C‚¥Ư¾úơƯ2‚^₫d’ÛÜíB4>V.O~´Œø÷@»ÍW%}rU¤5đ}àhµ;éú/¦§¼#az₫0äKp₫Ÿ[w˜¤hNª:½” ̃†·„>:î­â*ÁùóS¢L²J—B”˜ẹ̀V,ùlj±!J£p›_@qJÍ 7g¨à‘nS³₫á`,!. vă95“1Z¸ùÉs,₫>­ ă%)åÏPÉ̃‰ă™ƯßjÇỏ}UbÓ°yÊ«cÓ¦Ô;ØGà‡Øé‘»%v_ ¼Ko ­̀qÙBû^ª3µÍµ³âû–M$ʬç¦À´Ê¦úæùbÉ0Ï®á÷¼öQ̣=¶–yË* hal>Ï÷;ͦˆíEÊB©eŒá-d~Lv¯ ê1M‚S₫4 ̉ÙTWVƒ2w¹‘í±ß^·*8ÀYu*à>"«Æ —©<ÍϸP² F Uj<²„qÑƯ î{Ÿđ èµ:EÉU)¹¾ƒ~£$²À|:>́c÷à\–Œb±-AºÀαJA>K×O|gơYKÙ™T¨2|Á x^K_ºD_@a×hCưđ˜é\åư÷­²0ÿ0úmΪÑAÙ4 WÀ»åO¹’nÿà4ç+¨Ó½RÁỵ̈÷Ú//T¿í ÚH™­d©ÉÍeÔ»*Œˆ,J…ͶNï¼¾q’Ëeh”ÖÁâ Ü<¾„ÀVÓwL}¶¢ôw¨¥”„ƯÇ÷’I;^Xgö?’‚D¼qTÖèb¢óaM¤V]*!xbüÑ®ÙoNsNµGüëfă%s©đ ơ!Ÿ³gG»<&w/‡?¡Xƒ»;e7“ßW[¥<Ï8G´-¢®"/Óªe—û¶º‡røÎo˜Bp·ÿ6‹o(8¨¶¯µDcµÉvk;nª]ë…˜`û¶‚&æ‘ñBôî’ ¥Œ4! ¬1[ƯwÆŸ%Q8óÜüà/±?²₫ÿËb₫·KÜbdáu†=Ö¾Z«îx½4ˆÅ]ˆºG?̉ẮQæu ¼'^Ôé)—ä62Álˆ8OX$öw#×D3ƯV±Ö¯æÿg1™ŸY"$!‚₫ æ¹Jª_PÙ}c]|#Că®)[9ÂMbû.];s¸ع&B*N.ØCèjÚå¹axôH‹Ă±úÖØˆQ\-kñ¼jCbu6V_¼45i†Ăß—tÿÍ}-k%éÎx°ÛúÀM~úoVô²µ)k* ¤J:^÷Ơ‰Ç´Ê‚»»…ù¼ªù ´ H¥â¶;»P…ÅÊ€æĂq&ëû‡‹¸̃øÂà?§ơ#"n„¯“ËJ|±¸Tđ₫K'(x­/+áH8å@̣y Q¡˜1ưƒö'×X‘üœVè¹µHóœüơ§đ$èë. ’ƠÏ æ‹ø̉Íè¿WÅvÀñ[…p ƯX?#Un.dË"Đ@m°è˜Ë‘½‹–‡Ư[&å%¡ư¯̉ÿ#Ç$dQ-7_°­ĐʻűÄwé÷¾Ü¢?Đ<8#°$uå@qĂL4 >Å¢¿D´M%å‘v+ùWẼ”áªÑ˺d¶çt›N¥f(_5„;Jè$́Ѽ…ŸW´úü~ưïK%‰4²cc>˜`¹6ÀÂE`U=É÷;€§æơ^+ îd;*ụ°Ư \@ZÖU‚W– ˜º—WË÷¿\ê'®^Åî¾>RM²ªv~så>}ÉoM†¯çÁ­u=Oâ¦f&©å¯éQjûpÅĂ5ÅzOvYöN­=ªK&uö¶f[±ø_Ë%SLbî&ö¬µÈ?xÛ/qăa‹€Æỷ›„˜P|dth­s©$5guƯÇ6 èM 0^đ–q¢¶$³ƒº‡&A?Y‚@ ÎúñĂ›»àâæ£GÜÖ [¥PÎâưžñס̀N®×+ÓȰÆƠæØ¼0Ycü…£xq¹]GMUüm†èhN3ëA"LÁ]‘牉å]Z2»ª ¡Ç–e^zÇbw†)̀¸Ä¡â€T•!„ ¡{<̃ P(Ïs"®àº %mÿ(!Ï4·ë‹C@ásî*;aÀ" -PßyP•Ø•œ•|ưoƒ›9¡Øy4Ơ+Q¤rxeú̀ºÍP;•·‚¡Çùj“‘QC^̀4ˆúN@đTÏ5iï½Îqk…ưKơUĐO`÷ZÖ€̃ 2StÀHp)d¶ưhÔN^3̃Yµ"È®úÀü_°sŸ[ơP½]¦Vxư¼ǃĂ%j:'IwoOKn†ÖΠ´5z3Cç¬"̃¿p§‹F èÑLăÜ…À::2‚ùÑ…à$äè~Ư¡Ü"Ê5LÊ^ÀúÚ‡ bà«GúQœ‘"U1ñ>6¯®®Ö6z+7]̀Æù¾«pyûê¼cÎ"ŒÙ% ‘®´ư¨”̃á¦V'̣RÜo•äT׋ tÓxåÅrÅÚ1ú5kçä+U³ª¡s†"XéQ‚‹ïm*ǜχưú¢QÚxH<%Çk¹ÖrG‘h5)µ.ûfª¦çlÂcQp¦ù¢V\I{—™eUU¤À‰ ̉2UNè,²W|T.Ỵ̈ÊI©,#v.1Ă-'Ñ0øp&P1ƯÏ}ưns ¡Ô¨·Ô @ătÆƯô_\ 5súg[àˆµR₫Ad"¯¬Ù3ư“`e¬VD¥<¶±X¤rFç}™¬"ä¦èZtÿŒ(’pc¬ÊµPˆ™ ÛeüNÀ;Ơ§¦|NỵB1PM­₫mty×qf··‹X:Og ®óƠÏNѱ36¸…Ë.̃r‰« endstream endobj 1730 0 obj << /Length1 1971 /Length2 14497 /Length3 0 /Length 15701 /Filter /FlateDecode >> stream xÚùP\Ụ̂‡ ww‚ w·àîw× ÁƯ=@pwwww‡à‚¿¹÷œûÿ¾ª÷­©ÙÏê^«»×úơ©=”d*ôÂ&6F@q°#=3@DNE–™ ÀÄÄÊÀÄÄ‚HI©já₫g‘Rhï`aæù—‡ˆ=ĐĐñmLÔĐñÍQÎ v˜Ỳ<̀œ(ơ„ùÄ()Ẹơ Á(¬Æâư7¦4’Ad]#öª_€s nơ5ºÈôYfèÀ)âÚfRØ!®(˜½ữ-₫ú SöóñN6v Æ~á^‹j£ÊfˆÜÍKå×n´ăï;ư@ ZZ-'ïî[å3×oN¿ÏViFvF®ƠgÍNÂ9¦{hŸ»ÓsîJÚ¹äd9ĂR•ñưA¬'áJ¥F>lBÓͶ(́~œ¶&~Ñ?5R'!;·ă¼q ׯƒ—Ó”7PóĂlj£~*Ă½ûpÎO{8{€Ư^ 1FẠ́‚ä箾ØÑx~Ø!(Óü™®¡‡ñ•ê‰êê.bCå‚Ùú—Ó!p(0Ø¥Ê`A‚YœƠ÷N˜+w‡Q£Å’\ÜïG&TÈơăxà2wÛ×¶“âifr,XÊ´léY»ă™ÛÙc Sû ¶3ژ⼢™¬Kăr¬®§€NBjåïøX2U(uŸ~,HøXRăÏn‹OÁ84«zJëÖ¶Öh̀°cÆƠ¹rÖiï¸ÖÀr¿o¢ôRêĂpàq©‰Izt0Œ%xDxDº“ˆv¥¶=‡5'«Ö̀·A*—Ơûb©/̉ơJ¾Æñu¤A;€7QR•pŒ./Ÿ­™¿Ak}3Đ&½¦áÀí^ëßOO¨·?ÓSMùTǹsOZ±¥>Né;:Ø Ø„¹­¯|nƠûpo'pQ÷ñJûtMxÊ@y'aïŒÍe)Ưü²œ̃ }~ề]ăT¿ü‹.¶¢ƠÈ$IĂ*ß+”w.di$©a•H¼åxA¤_˜ËÂBÍô6ç̀¨Ë?Œª¨ŒïîăÎ\D\£5/néf.û<ø`J¦¦M¢¤¶DéÈ#₫?hó”‹1JOä¡â >Åjú@i}>Øÿ•ư¡g!üiNxÂ÷Ÿ Ưñ½x[ÛÖ₫I’<2ưê‡3™HôÖÆüŸù’àÈË¥î×?Øñóåíñ—©\^±è<è¿íà4¢[CÓ£`#6¡Y~ÖÆ—ÑFvĐ”©û²£ÀL†À~¿È׬Pk;­‰2—j´Stä°@ó²’–È Çë‰(uR`@¶îCXƠóè-%Đ¡ aµSJÏ￈HÁ·́ ̉|K&Ç-j‡ö́fr=!]E²Y+ÿ4Ö´AƯGÄŒÈû$“¥È+[Í•.3³Đ˜±÷©zI±;i®pËñJI…P¨EH•(2Ø}[̉o{>Ñvc|{સpµă₫еá³Ô ÷QÄ£Ùª ó$¼ñwͯ¡H v„|7eưĐà•0áăfx%ñĂ•^bnͽ}‚F>˜8’$X«±ÉÉ- ïù*oÏ»W^'PÇ̃"í|)!ƒuƒyé}£3ÍdŸ¨™*’²nüq̃! fœ:º₫ +µÔ³Đ’ U÷Uz¿©çñáG‹Ê·+•¬́ÔåÎñùËTă†úón¥úƯ>Xlàdf0úB“zÚÑ=us 'w|̃ÔFrå:¢}'PúH³]`˜D<Àm<=]¾GĐÔ ƠûÉàçúDGcÅïÁInä%ó™¹&Ê&"rçªÎ~QÜÓŸ·™?9h-[«ÉD‹‡ŸÇ~_zW Om}Óê÷Ù €Q̀€©G I?Vµ¶f^©ï\½œIe©ƯôT́_÷"÷⿬¦‡±Ø̉²q³ạ̈́µ?ä  ‰Ôl÷laû•è™''tăp rP­¸ç@%ß_½ư’_Á{×3-Z੘>­:Jí´Û06~ $¨/Z ÄcyŸ×áV¢ø>8Hư©FqÉgØù:Ó‹ ” ƒ«W‘GØưmS‘ßåú(¶tÄ5L©ơ Øñ»H†ëîWV§Ø’ö«ï´l_ơ‹nÓ^“´—¦đé½€û §áaKá—¸Z̉NÈ2ØÈvnøá»N­Zp?ÍWïê]Åe/h¬̀̀ª3PÇ(‰ÍY^N’bÉ"/¯Å¸é8éd% óö@Ṇ̃KDg°¹Ú{Ÿc]Ă#tu n¾dÏÛûßƯ>É…1ø£² ?Ä›@'ç] Ø#ÚƠ‡tw¡)6Lö0U1­³Å¡üZ¿Sm·6â=;;ŒV×\©mÂ"çnàe?qïĂmơè`ó´ uó¹Ù°₫ïSPgƒ lCi‡9jO\%Qi”ê@5Ÿá0äËpÇwµ‚́¬|ÿÎTMÜ?Å\OB,‡ €^44Su3Eqăcu§yÂØë¢–‰Ư0ü1ˆ¤_Œs₫QاL9*p€†:ÆPÀ_Q"ܤ^•`Q¬à8ß\¿KŸ5ƠTëƠxºzëûƠ2ÛÜUÂ׿ôéIn`üg69ư^“–̃±ÄÜ´뺕–(ÖWs–€¡˜ö9Wn5z }Ü0Ü=?bÍè`~IrįƯ¯ª½;«I hPÂđ‰4粿Qp붘lï×ƒĐ©›D̀‡A₫€ñ1d ̉fvÇ+{‚©fUmqưt5¯ F£$¡BPÆDyL5NÊƯ« î:$­‡[ ƒ‚¡5FE‡ëùd3,ÁXor«mQ“)Dáăiÿơ$ù€j÷£́FÀÅp5m·‚“kA^°%Ă®×u¹‡ƠræÖơO^çKç.t8>‚”R°^ôsÚpºcmËát¡oå:¼mũøXÁü»Û+I1öÛƯ ,r2­kÊ~Ö/ K₫ØäÑpă’Ô<;®io’¨đJv¼ë‘Á,S!÷Ù=‚åQKQ–FƠv¤VŸ§̃™²¸, 69Ö>Eæ"dž=_øÄăđ̣ûèN¿ïYµ’̉zKgVÎö́Ê$;©ƒl4 ̀={¦OĐ½‡Î“ưT½sz*EwË?}±ÊY±l‘9z0QÖ†‡Sø$² .Œ­&äá+¹rïAxµ?Y`N.bótÀ¹Œ©“‚ÛHÊY ĂøŒÓjOñæÂ”€èCmö½­_“nâYưmª̣|à’́Kq8¬Ö]_+VÚ6ƯÜä.Üpv'Fz̉oÀ́¨Rz!ÏèêIßq]±u*„—i¦MbÍ?™Ñ­XwÛb“fàlë̉ºZè¶ĐƯSÇ؇-¨×È"±nµûZÎ’ƒ́-EV¾DïĐƯOƒ9^5†ŸÚ=Úz7'óͳ@—Y Z¶ËĐüS>#팇ǓăúW¡y«¯/·¦ç:Ó÷'±åן=mđ,0çϨ!­¾¬a¾¶Wp̣}¢%ÙÉéIU¬:& "—ÊÖܧ̃îƒÎét€ .Au´œ:«̃»i.ưÖü&®Í QáJ₫Ú º™1e"x+x©]Û(gw»êù¼T˜Ă¡Å<¾p¤nœǗïê!4¥6`gê²Î–:Bè{7û ‡†G;q"¸»¨Ñº×Ëœ‘pëP2îôí¾9Ö´-äZŸ·8.ÿ°!Œ³ñP½×ˆÜ¡×9æ˜$̃S«{ 2a~Ă³cä¨7SđÖô(9D"ƪ4ú56ͧKæÛ0ưÛ́îE..»Ö;Î7÷çyƒ<&Ê´C¤|P.!†¿íqY)oÉrxSợùåäí;ƠWfÑQC8í™KD[ uÉdo å…¤¦Â®âE›+¸^î8Pc biw¥j”yXùOܶ÷y>>Í»J|ĐóƒCÆ4^œTO//O‰cR~¦ĂdŒç”@w+cJ3ŸcNÁXCMé w®eu¼çÄoŒ=Ẽv9+¬Ñׯ<{tåÛr¥ĂĂ˦“ø˜Çh(¯»å ¶8 ¢ûjZƠˆ{_“/‚Q*ÅêSl;Ư_ó™' Ø(9ª̀5X‰Élû¶‰}2·3ªbÇ2 Ï°¥W>¬Oá-'b*Lí©U-ª«ëºï¥°Æ\à+\[§”`»_ótà«^k‡›eëí‚•Y9…¢Æî÷ÜÈ00bsLA×Ä…ï2aĐíä© Ñ~=¶ăFsmnNq†k¢“\«ñ ˜8è8º̣…p.+áIœ£ÿÔÿLª;•NNÏ›̉‚ƒÑ©l¾G¾45î@^Kuxk™-ÆntÂ⛡;́ ư„ï”;¸¾÷«¯×:ư’í{¥EÓĂ˜øØFùôAÑú¬r™î÷¼ ^²IáIB¦Bëüq<ªt•ß½?Ăñ}ÊIÛo¼Üoøơ’zF¹Y&x2ÛDºöT±ƠÂù±ÿ`ùl@"0[5u„–àŒÁ*êùQWNGuê­¨çè̃1Pă!H§Ä[9®fG”ÏN‘]œv]~¼¿äKÿÊŒ¹ÉGđ±Ç 6c2T>{¶ÇY¯r} Æ‚'äùă5kG½"¢æä2n³–À¢́z+-Âåˆ^8™̉Œ C^´s}KÜ6Ö”Ẁéj1!V…”̀£CøsÄ̀₫Ơ’7ÉMÀµCV¤‡ Ưµ°+đu¯¨uʳ¤OCXCÜgÁú C"u­ÙêÓV´Y‘Ÿ-ö0TÇ!efÆë¨°˜̣p×^êy¥đƒ® sÖiègƒ%ºưú¸ùÀçr1~R*Ï¡X°u!ey¼2™úœ‡̀cMJÁu'û’¤~?à‰äôØ´l?KÅ.ˆ̀FLƈiiœ0ÜSQ¦'/UQB›Q¶²^0èí3Uêo¯FøöŒÏ†7z}ñăi,ÓP.Ló´[¬CÂm_Æẵry\¢\Ö̀Óa[ØÑ¥«Fđ÷ư>„UƠ™ˆÎê__› åxÏΩk\ÑĂÙ-óû7̉o³¯M¦̣¿ƒûPÿ Đ5/÷ÎNŸ·àè*(©Y[†· 4̉í₫* Uz´®ÉÑÍcb6f¯́œîÄ1 ¯Ë½‰gtªË¢qăÛ]¸Së {Ȉ¡Kưádvå•^J¯6§Ï•_Åt»±î‰đZ$—<ªƒw‰“ zü,ÊjÛ;ˆ›ˆDfo‘Îçé~¬ª¶&yÍ…aúEă‚gÂIÎ̉b/A2vÑøO[½Ü\a %äụ̂ă}À3+ß³̉Jänd«‚?ˆëcoH'®|¥ˆ”nc=ûGÄ©Ï!³Z­÷_è£~Gk 'mM*~ËBÈ5hQçÙôHl²…WȾKìl&‹})C§ÿËs›¦ç ˜äŒCN%É/©lŸœÏPhÆT¨œÄ·đwdQ¦Úk#1ÚÜM{M@gçǽ•ñY ë `å.˜ïÊ7ml·GO|bÀÜî6]<2Ä&ù#ù¸Z&̀ªàñ\€470ßh«¥¬VDđ£“¥G¼ÇĂă.ÏÔ°= „¾~ 0ˆ‡Zw/üS`yüÖzâÚן½¼…M̃p²nk~ûmë†G¥¨ø ¾¯±Ư—Ư–ÂhW–àâ鿇í¡ è¨Ï,SÚ[-ƯQÔpñ&Ă?HÂ÷¾1Á q¹ÇÏ"|*ë®(ë4p¼m7”“y÷* kNk¥úDfv ¹8[•œ÷”rÂ%7€«êÊ;’Kï5Tv79FŒ¢27TÁªuÚÜ`¹†—Ê6……ï,¤Ú1Í}¦@ƠßMÜåtä³wM1˜t«_¢˜¶º®èïï±ẾË̉Úo¤fØă!ÑVT,úè3ÑGb@-Ñ}Idá̉tAX̀…[½k™3[ç¤ hÑà[dFα­9(Ä­(¡Æâ,”[Fœư.ÍxäAßơ •°Í~GR«̣VwÀl§ú¸A¡°NêÅ5¦Ó††€ürÖH[”uÁĐêå¾®üm€´5ÄѯŸơu1‰¡«0–¿?62´.ëơ­à%ŒxwŸ>¶¥¢2èR(ÁŸNªqz9 ;û~av-¶¬b†ï˜×Ë-LAC]ùy9B³€YÍZ†&û.ü²$kÖå XÑêú‡ t̃^MmƠóµ 3HG!ØŸQ¯:!SÉú´rđµƯÙJPGÁ0ñ‡¬rg:Örk̉ 4‰ Äêº̣ÜĐàË%:á%^fÛ+X .´¦¦û„1 q†)@vNmSKYùªJç6ư»Bo®¢¦m¾¦Ù—¸y SOïi¹î܇±µû,f₫HËç…•¢E“è DøŸÛ…¨¼¡Û¡Cie«0‰}Æè$ú¸KxÚ\ơc' *ñ²öTÁưUƒF@‘TŒ÷ïçïMD0e¯e_äR´ÚqFE¬~\iS"pú́äh¬MT4:Éi¶M]`w₫f¾6­Œ±ï´óü±~׿̀ è.”tÂbä탡RªŸP±6p»Wد]uAg‘Í}ÛbMí«Öå”&Ÿ v+N¢!Lư¤9&¯ưƒ8TGÿ¦(Ftö=ųèSμiï&gåLum‘ ¡à";‰J#8đ(…L!E kư+¼âÔ.Ư±+b¾¦s‰?™Y§…đ¦¢†ØÏ^£×í¢>UXGÅs*,HöXHå¦ă—f÷¢\á&äÏPÉF””„ù ˆM9b'»±3[^xWvế ơ†F3Ó¤f<ÄÂâö¥5Æ5”ßáhĂŒ¢¨ñˆDÈYOˆ’™ ³ñ‘€~k@fzxƒïH.ç]û:ê’Öç÷.‚̀3Nê— áÀçỲ+Ÿí…Ú‰}Z£ßH+áVEÖD/¾đ´UX PŸyN² yÙ›qé=$‰›\l¥,>ă:¢¯¨0­A~H,’·̣Q”Táè!ˆY-ˆ;r$@® q”v©×¸Çɇèᆄ­ÿ`°ƒ¼)¥/På?wÅH¦6@ß\À9^]cîù́Ï~‘ÁÉp™½D3eº&˜¤y–9q•E§¿ñ <"l” ¸̃pGª 輜q#^H§¼=V0 ́kT–%k›d 2̣ǥ =%ˆnê!íă@âÆ<Æ};—zÎIJl˜©Ụ́øí¤«åt¶âà¸lHÁ§ß£·¡ áöu¢íûmCKʵFnưªÑpC A¾ cwÖ»MI«ËQ››UÉơÀàÄñ:ù¢±™Œ®Á±=Jº«‘PÚb|ä‘¥~2»đ~­µt|ÿQ53t œÛo}‰Ñ‹B%²0f3q)Æ„1ó"îß@ ÂÇÍ“̃û™äR!~¿_<ăàL?Ñwÿ®œ~=&ÚeĂYçP\™F.+‘¢Â•!ưZơÍTÖôÜF“M±ÊG×s¡*ëM,»}îKÉ?¾•üDt¿4ƒ´́l£=ZÅæM«,¡UkevsXP9e7R`Ú#9$RÑ6ƒ9lrë ÙmqÎ+Á̀æƯwjđ ªMïàî§«%ÙL Á‰c°·Í}C|Ǿ=j­somrÜ÷ÁĐ„ à`ͽ¿¿hé)ßÜ£p«¸.Ê”´÷¸<ÖJ́²ö«®¶´ØL}(Î>ñ¶áè̉ơ(9˜ôl"u÷p çẶÁ¬?Ú¹!?̀ưª&•—x{ä¡‚OÓOËeóûÛD´—j 4]$;;:&mS£ñÛÿâ$,Ø ½öæ`‡[Ø Ÿ jáíúrs!D~m!!-Ö3›7…è̀öô:azà°v(9Àeîíơ76eŒ–Á„#¥;Ç},ÑK¾Øƒ7W­»{Ç "ƒXu*!k“ÄXöôüDU9Urq&@/bÙQ¸(̀9á®R™¥ă™ K4’ZhF³p^ĂAmzÛ¯ÈS»KWv®£\+ªăóø̉́åđ‘X?\¯ ‚ï ¹ xÑ”EÄ8V@ØḥÏfhÙ¨U;©”˜hJƯj{ )ÈbưNp„é§pu.‡´ô_}pïHîz‘Êâ-µ©ƠëöSh…$Ÿ€ƒNË·íûU¯jdaºM`j¦„ öL‚ÛShoʳÜed4c‹—Ùu²Á†R4óW>́ˆư ”„ĐTS"ô(Í:ˆ(̉RæS¥̣1V6Ăªưï¢qç]3,yKKơNJ°¹¥Dí]‡½W\e͉Èwå×íaĐ*îÚ³S­ÀÅ:èÏ )®́¨ÖáØđ¢,oÙ¢“YÇ̀ñ Y5 Et [Ab±ï,H¹>!瘥"Èư£‡½%n¾#Ûï®qɹô²"+¶Ơy)ÇŸÆqX.±ë­«>¨@^£5ÓŸĐÜ- nÄ·î‚ü͹S{…Ö‘Œö²û>—̣–§y)u‚”†¨ØÁ˜—Ú8̀P§â …¯Fờ’>RÉÈ ̉́7¥@MIfÄP¢6¹SSNuÏÚ+¿çÀ̉æùøÄƠ~±È6S‹ư…Ç"çơâRï”’#¬6X…i¥µßD«!ưö«†€ÆhYµ¸Pm­/F¼₫¬Á£ƯqªdÉhØƯQÅg ư´-ÎÈś±îØnÓdj§¯l VÁ]®! ­$³S*¸˜è|ï³/ö>Àh6³rmzt TªrøXÄ;PÔºí+Đq81tÅyY:â!Nç\KUÁ¶b\¼¡´*RC}ç̃£q|„’fôÅ%b /"_C«ÏăLÏYûçÁ;U\/ Yë­$%bœx²‹/vG‹Úœ̉˜¿Ùº~nsô—:œ¥2»2Vä 1!÷Uû£×äŒï=»¨?6áȪ+‹ïegçNœ(_ê¦eÙôÁÍS[vƒÅà¹Ñj”¸Ùm†½~×à Tî‰/!aÛí¤Ü«Ñjº\T+Úß´nh ½₫ƯhF‡÷â.Q Ø`úe‹‡¶uÂö—J˜_]ÔYA’P̣h~û{•ë n6x‘¢V²ư«fHébî'4®:"öK"¥́ Óư f̀/%CĂ¢!öƠhYư]–yÎ ¶3̃”B¢‚Û `Tn²{̉.å‹Vå &gĂhf¿T̀yº• B„Ê;o¨*R¾’q•_ÖIâ*_e´ẻ `7U÷ØÚ Ûûµ Y^Û÷8ß4·åÖJ3®Cë”g"M³§ômïQbv´"ÁpŒÏö Œ’…€ch¬JƠäB*C”Q"ẵr­Sæ½Ø”BÁzMkđ²¨Ákdb×VV́̉¡c»r:¦[AJẪ‘ áµ'!ÛçÑụ̀íŒÚÍb‹XÆ zÛ…x̀«̣ơÊÚ. Ûˆ7le¬ô—X'jÚÇ­W›ƠÑ/“<Wùø(ô´’¹I?. ¥YwÚD]…î‰~ụ̂Ñ/swø).—Nî»Çd)¨œ›F÷á§½:„á¡&èïèK¼3+ØPjà¨a,ÏÇø('2"áWđ‰Ó€¡₫Ö“m”Oœ27H±LÚ¢5Èʳ^PlÇS½z®<æ—båù[K‚!ạÄèË$ؼEm Û“+¦ưPß''âµ Rßï̀Vó‰Ÿ3¡f¡+|:yPŸ‡â&m\AM̉ĐUøè.†s@ʼnZú›J$d¯§CIC7=6B³"yï‡2Ÿ A"MîÅŸÔÜ%½̉ d¤ £ô˜(’́CåP û4JĂè .÷ó•´³IÔ¬ f§Ç(íÄq,É!O˜…ßÂrŒ’‹G ¸`oC¦çó́|‘b¿ V0n˜Ë¶e„;Q‘€¯́;±êrgç±]¦·»¯ưM¼‹:¸O3A*»Q·'¨oÅÏ[2sŸ©>x±[ÏẲŸ$£BWRiSÛmf´@÷>€è̉K°d{ç¹>&NNaI¬‡Uk¸¶8"¸zÂ…"îØ»Dœ@1‡Ơ ×@0ÉŒ ¶‹ÔßD×Üđ>&rúîƒ%U¸ü¼e[đ¶}o©ă+±^R ³Ô}½TNB1̉Ñ~¦­/ï|49Ïû€Ù‚ïJ¶ÔÓv() 53C·‘¹ÅÖ¡ÁX瀡y'¼Nê!@bĐBä½eaA]¹±ZÑC-“`xätƒĂ6̀ï.î£ç£Ô×8[o8âø“†ÑdIJ>W—ê;ôPag‡º̀bAÜ{O[̀Ä-DüñhÁÑŸ(œR Kn ƠL0Eû\Äí́µŸømçumˆñ'X[n›|-ƒâp\›¨–£Ưbá¹"²‚ÑQ㑬ư¿ÿĐÅ`ÆTâºù°r0p¬_>ün8÷r“TkÑMç‚WÍ…qfx>Vø₫"&‹ĐSªŒpÜ—¡xÇ8I &Lé èfàü₫{V[ÏAC¿"LTå䥧6%øè¬ö€Pî6$xA:ÍÙ2'·™W k«B7C₫û‚kc®S WR¸ ›K3,¾ó̀Ü5EÓ§'Lyœ·‡ª„p4Ơ/HsĐûÚxñù¢ü ‡¦°đºsº<ƒùxw¤£êk²ÿzđ¼À¾, 1'¥Ox{BöÇËm༆¸ÀËÂÊÍŒ£́aÏ´pö™—ÍB½%÷«(uù₫(u†æÑu«­¦¦±9“ÄVÚ¦RÀ́xÇ«ÂEѹ;åLR­¹Đ™l-üwͽÅOä̃Ê<Ú|qÏ/Ă¡‹»è© ơ9Óü¶¨çÚÔ•¶ª.TÓđC³Ÿ_ó;Ô—¨\û¢D¼0bÚrç%«çTŒ¶»Y5¢$¸g¤øDè7 @‰1©ó¾[Ï—Åï¾U*í̉ªüÊÿ¾/±ñƯ9JÅá\e-"t<Ài`˜Ùđë Ç…ª…œ>QˆQÏ5Öt,<7~ÚÀSÁämkÔºÎ`“ ‹î¤(P¾‘éøó{‡úîTáÈÓܰù ¹2mJ»̀{*¨v…£4„â fÚ`ưŒ…âŸ{ „åŸqßÂe*­ hƒ;>êZB£§c¥wOw鯦₫\Ëơ™f±Ä‰́^ |Óÿ :×_₫kxî̃7„‘Ôk2†ÂD)§”<£†™đ:>CöóØ»üẬư ‚‹È}M&Éñệ*ÓXp>ă…mc „eüyæĐ8n®è6^u 3ꌟcÅ©zBÓ(X°eûf;À%¬mĐ­¸Êæ!¨w/j5>Äô¯HïøṔ 4}[Lï̉‡Ùb2ia7ë#c¤O´Ń¡ ư¨®=¼rđrÎ*²ç¤øåµ’ ç̃)BXY׈íëºÿjUyVôQä¨gÅmå+ïªL¨L7Z§+#kßTöæmF,ÊẮ̃Y÷«Q~1”M±ḱËÍsê^±Á̃Y+J?„U8tHkiÀÀ-0;~´é¸¹O¡]tÆ|QµưMÖ°Q…»g̀ʯuI©ÉSKï`ç}%ú²JíeyÂ‡ÖØ™»{©7½|a¬Âiê1¨—Y@}ç€̃@Á’^S›¶î_ܶF`ÁͱÓöûCĐÁ3×ÀÙ/æ÷é•Ñß­¥ˆ)Ö>6³@q§3́€q‡CQÓ€¨í"ƒÇ#( Ú:ư~OJêôv—æe««ơ;Rµ˜±$Ÿh¡œÏ \ĂJ¹³©ú£­«!‚®¯ơ™BÍc¿m"€ÔZơN^XN)²+ ¿" €£n²_¤vfiRG¿AÏ CÀYu’’»ÄđħØFû—zna®¸u è̉1V 渙ơÊo(vđEÄ› ³J÷nûïºBT›p†îœdçĐ›̀4T’Æ=Xµ4j—E³Ø„öpÀËXûÜGÓ „ÜiXï¾ú}Cêă0Wx…úÙY“Ö{ˆ÷gZâáÍV?²SæÑR‹\s²osëÄ—xIư©*0ÊU½sfU¹æw4̣6rđ­2µ8l]º?´rƒ ê&̃e åµÈ_Ñđ¥Îñzd\xáưF<¾xôê]Đfïi©÷pJE[!RXÙ&®˜ºHê9ûÛ₫«“ ÖÜ₫0ơSG|;& ¢’¹†å…6_Đ¢Û˜´I¢¹æ">Í`‘À6ó$ùC „́ö(¬åœ—qƠ‡I Míèđµ!ï‡}€;ϲ””5`üºåê…M‘W¼~+¥Í’/ĐĂ·½Ê·ñS—,·2û=‚Q;±=ŘÄàQ̉ˆP£¯Co4¸ûµ)cY‘'™îesV6#.> ôẼ ‹ }ăd¡EÆ—WhçŒv˜ǵ[®"ưiN}+‡Ü’û˜Ÿ‘ÛÁÙëµ7®UŒTßY˜¨Đœª…'ạ̀A½µ\<½âc&¹Î‹•e₫³UΗ+îcÄBuÍU¢^OÜ;ØB‹Ü!qe²_÷8sóƯf·’ưƒà–6GʧÂmöc†˜¾Êñ.¦³Ođ¶êxMbˆêV Í¥;dMÄ„Á™4G ́B|éäư¨Ă Ûmˆ’í[~7q;PÉ*¿º̀º6>‘œlÅW“–s:³ÈieèµN÷ƒÉ¹!­¾ÀI’…®xƒY¹ºÙ:™Ơ,BiµábÇB[mÛcÇ2qÙI᫺îÑ%ÅÏä$i«C<¯2>“%p&x̃'±âáSëû—ÏNÛkƠ2&\_ˆŒ(¸•Đg;5ÆÇ8èm¥ơt)^ ƒ®q**Ù†J¼í)F9Ïû:™÷3̃¾Ô_ôS•ñ®!Mû–M?úÁ£µç)§̉M2éiE8~O>QM–ï,sv/§!‰]2Æ@T!y¤8£ ˜Q­½ÂVé¦Ozú+ê_¶{~¯ y*Yï'r,‚%áÜßÏrñï¯GĐø)A×÷eºàÓxR÷-% /–yÂ(¨—‘¨ØÛmW¦èÁºäb=c,Sçíѹªß_>J^÷¨ñ¬ a7$”©Înj]óÉæ,§#`WŒvhúca¼₫¦!ÍïçrlœK~mÛ;׆Y?wêƯ [^ `Œ`°E°Ob̉w¦ƯeEªS)% l8µ¹Săë¯á0ĐKƠûaSè»ĂLæÑăr>7ç–í× #(ÖL…Sp‰ï‚ÉX®¼K´ü‡Ur'Öà6™¸–+í÷¿5 »¹|Ư–JM. ä!‚ZH^iZ¼Ñyoèu <”q=Ä-£k€¯«Ơâ·ê¶‰iútNä…Ă—¾ZoyU)êç¯isd©CTΙ;œ^²-5IrÔ÷ÜA´ÀÊW 騝™̉ÈUô4@ ²ª’Á­ âçoy¦¥ä(<ó»¨<äU{—¼º…|ÔÚtĐF?Ó«e¯D›–>́–Å5܆U,Ñ]‹¿®ßeEu›ÑW×#Ó™̣jÚóí´ôöÁ ^!÷—Ư‚ªÊ2÷j¶à©ùí3FÉ÷o₫¢ơơ¦̉W’³’Ù¢A›W…Yo^í&t‰‰üôpç$‡0tR"ơ¡ËÈ_‡JGĐÖg:ư†¼Ê }ƒCˆ”£wO锺©ƯAO©Øßô|ˆ_̣›Œ$d(A‰…̀̉MÂ^l ^;ú[ù"ѲƯÔ|q¾r©)&ÑÑi]øă±èN¬¸«̃å·F†{Ó΂ǡ6å¦ûƠN_ÊXå¾7xƒ£0‚¥´K†hÆÆ„ÏPʳQM‡– 2P”—ưü… _±ÈÁ˜m¸bÛoÎsç´Sv~ư•å,|¹0‹{ê[¿qø¹ƯÏâ(³I]÷́[É–‡wnÑăJaçE‰V¡uæŸÀ»7ç"K'²Ẽ£ѶBíơß¼Ck#mÜ)Ä*ÆëwǻÁ{ÓUB“Øh\rQ؇ÛüªÆàŒ®â‡M¤¯—ö×$å•ÄI-ó#!£Ÿ¹ÙÈÀ–iüCw H´ ÄlYư§_³ Q¡QÀÜĂiË_L¬ÄbƠZnèœÓÊÀ=`ơú½\Ÿ'Ra–$*eÜé0ö˦墘Œ¾îAF¹„äyWDE±3aà·8Ú°B8fùWI‰ü•Á™ ,¶a3Ÿ̉‹p$Äé~íÅBŒà‡ˆWTÛúeË^ZhíF~˜IÆ‹„f́Og¼<*RK"uđ^ª­7Ö”Ïo-ë N°¶>f‚S»[ ƒåÛC§Ö+xA)ΤM̃èƒ\{¡ ­ Q…ŵ›Èö]‡Đ²qO^ ¨rm³~jn³©#]Hy»LiîÄ©^‹.œ _R‰•Z“6N½C›²º¹YM¡‰q¢ÛÙ(tÎ̉;£đÅÔ…ÆNæèÜ₫Åu®qạ̀…ÅÓ#wA© •äX*\èÎÚÁºß”ß?Ư¯pù¾Đ½«*áÅ̀«¶‰̃Ñg•‹) XdSиé¹ßn&yïôEFd§÷×ƠJx±¥»S|̃²9°ƠÂÅn¬€, ›yå$¹| –ëNư$|,5ÿ¾­¾é.÷$Œ×`ö©MC›pØœ£{Üơ©%^z₫9çhNh1 7+²éĂJbVp:aZàmÈdô— åå ´Ç•ä2r•V9!/êG>DCÔ*¿Æyé°́×m§ÂSfG'o;¤c±ùú‚l¿›ü•µ$âEK3¶±wÚ®¦]yiö†y†Ö§jƠ[ˆÎâöCôñF—ô×! Q¢Ư‰Ó‰úYÜßĂ~@?.‰.£> 2ÑéJnMRm v(á•cđbÀèµ»¶AfI硉rụ́¶Ă%a‚X,âx.w Z¨I 0(‹.ä~êÏ£Ö{CD2 ­4ï!T’«¾ÂM¬:-Ó“̀€VvܽĐËbƯe0>,F@Ñơ›̣¯˜“̣̃“qg°tP°å‹ @ƠÑD"i´×­b+P§u§Ce¹÷–x̉1*tkk~_<Ô0÷öîªû¨RS1k·ú r¥pÜx¨L¨½´¯cövƒáÉ›âÂyZÑ” ‡†|ZŸi|QBˆÉQSăÔV«3±í{MQÍzÛ¥ªöûêƠ¤v{{˜Œ#c₫j¡a]K ư™™!ăç ˜+º®~Ÿ̀R×”6ß…\́ ÿ¤°.ûrvzï×RÈØqÇ”sHVyŸÔL⸢s†k:.°%L<‰d™€ó=5³8AŒ Cs"ü„ª~&Ăzv÷Å#j´8‹(“̃ú~Rp§èj@ZŸU*µGâ!±r×é¼xÈ’9i†°"¯¾:—¬úª̉8\ydŒ!ă3«,Øù• ûñ=@MÉ?ä²­=[n¼YFTÙÛÄln„&¨¡º§)bzv¤0:t€æIY's±Đ³b”K缨®WF¨bYµhµ̣ô!-7^Úá̉rMüÿ8ŸÂ endstream endobj 1732 0 obj << /Length1 1958 /Length2 11575 /Length3 0 /Length 12768 /Filter /FlateDecode >> stream xÚzUT\[-îîNáîî®Aƒ[Đ…»»—àÜ5AÁ .Á-¸ äUnwß›î÷>̃¨1ªÎ\¶×Üg®}ÎGÑQih±IY-€̣`G76.vNa€Œª–¶6'€““‡““…NäfüǃB§ tq…ÿˆ‘q»Al²ænPU°#@ÙƯÀÅàâææäpsr ư'́" 5÷YTÙÊ`G + ØÉÛdcëYé?—FK&—ë_é)  È̉Ü jîf t€¬hinĐ[‚€ñÿU‚QÔÖÍÍI˜ƒĂÓÓ“ƯÜÁ•́b#ÎÄ đ¹Ù^].@+ÀoÚ5sàßäØQèÚ¶ ×¹´ÀÖnæ.@Ä`²:ºB’Ü­€.Èú-%€ºĐñ_Á*ÿ `ü{{\́\—ûwöïB Ç¿’Í--ÁNæ̃ G€5ÈP—Wawórc˜;Zư4·wC̣Í=̀Aö怿7ÈKì!ÿÍĐỞääæÊî ²ÿÍ’ăwÈFË9ZÉ€€n®(¿û“¹-!;ïÍñ÷-~ëötôư[ƒ­¬S±rwâĐq9»•dÿ1¡üc³ºø899!7è zYÚrü^DÛÛ ø—“ë·ÂĂß× ́°†Púƒ¬_Ws ÀÍÅèïû§ă¿ À dé°Ú€Q₫©1­ÿ…!*pyŒ8!"äp₫₫ü}eÑ™ØÑ̃ûŸđ¿n4‡”’º&ËߤÿvKKƒ½¾lÜœ6n?—€_ˆàÿß…4̀AÿnäT%Gk0@è_ưB6ê?={ü[Œÿ&À×RC 0₫£wcN>NKÈ×ÿ·êÿJù‰ưw•ÿ½ÿoỌîööE0₫'äÿ0wÙ{ÿ;"aw7È8¨‚!Cáø¿¡zÀM±*Đ äîđ¿^%7sÈXH9Ú@¤Í&ÄÎËÿ/3ÈUä´̉¹YÚ₫%“™u~=Ȩvư>jl\œœÿăƒ̀å[Èqâ Qç_. d”₫{U9GK°Ơï™ăæă˜»¸˜{£pBDÅÍÇđå‚ §Đë/=8ØÁn„¡?À́‚̣ûỌ̈óA$ôÛô/Äà₫ 8d₫F<¥ €Cío$È àĐøAªè₫„ ÙÿA<‹€Ặoô›?‡Ơ Àür8¬ÿ€~l₫€¼Û? „èiÉîééí̉”ử•Ă?2T@HWà¿!/$ràÿá†téô²®Dîà?hA"ÎÿÀßÈ́tư¥œ „\₫€B®@Ha·¿!Dnà?Ü‚îÿl3$÷¯c̃Ợ́ç̃@Ï ääàđúBx{ÿ!<}₫‚ÿ¥GKwÈư×Ñëđ_ Đ h‰²´¶ ³k 뼫—"ơdÛàù¯sóâNÉ‹oư¦Oèm)oáµ`Z®¬Æ˜­x­¬*,tD"©\¼€ç[!é.vDÜpÅh’ö&Q5a´s$Æ© Î/$IqDù‡2̃ƒgTU7tâ2ă8Z`ü@̣;ĂưguRªâdơƒ&!‚‡êöÂs#Ư²œv!‘¨Ê=­Ó÷ ʆ¨­'·¸5]8fó ửè|s (nç¤ÂƯă=ܶ]¯$»¡?³–Æ0́_±–Ü.©À&ĐĐ¹h|¸÷¥–ÉÊ/œs¼VW7q̣Ÿœc^@Ë´C¶ö >.µUü‘à“'Pq<Ä?«Èx–3ÓùjF³ —¯+JQ¨D)³¨3is¨.ƠÑvB|óbŸ´+ÏŸôÆ´™Ùàq>uÈme8H[Y·jûÈ ï«.Û;köÊܨ˜́ÔeñưØÁ«­¼9ym#ÁN®s¯Ôï KÅó–ư3&†ç½Ơ{µ̃M“ªÓ\,Iú>'ÓÍ“<&!R5ÄÏŸhÅ’±¤L¦¡÷‰ç(.f•™€5=TXø ƒ¨–í/Ú\ǧgh³Đ₫†½P/•R_½;áÄkQ-3ªQX$öîgà¬Vè-đŒI¬Ö¢±ôC3Í&&9ơI+–9ç±oâ³–<7Ùiü’NW Kåë`Ï ' ª‘Đ1Z؉à÷fpѽ´ư¨ê«½Œ3›)»BÙ˜K©ZÈV¢üw±„°z10F4„QH¦ú£=Çcqüx¸?¥•eÈ=QÆ,ơf*e¼“§ˆ-$ÔÉ‚ø6´—pξï)6.ÏJ{ú Å¢lÅà©;4 µu¯NÁë₫̀ÑÀ¸¯U29‹¥aY~Ö¹æ0™f'¦#̉b·³wR¡Í́î~Ï‹Áù|&@EQ5Æu]Á†³»écƒëÎĂwÖImĂKâ$’¬“Lệ%Ẹ̀¦ñ*p7£áƒ/,rmÛÉ#‡Â@°¡!ƒöƒ¦‰Œ*7F/BNF)œzv€¨0±̉u ‰ñ#ÂÛv) &Uv “»̃¦×oféí6¼jqnM̉Í©ÉÜâ{|ïü"e$íú¡?äÛ—6ö÷7îÈIEk/,(nø™ÚÇAiü_B@´ưi~v©Đù$År«èøh=¢.Fr⠌鉥:P·ê¦°¸4»tq ́_ơ…UÜ ü,oƠ¯KàóXäZ)ƒ—‘k̉êNe½û€¥|¶×jwú¡âåJ­«£“,G¢ơ¹²—©,*Ε&ÓEŒ£ÚغËá«m,†‹Ñø¬ƠÚ7ÇG̀¯Q¸WMÍÚœñaB¬̀§á”¤ÊæNgAbËEHD0®tú¬Ö‡)AÇ7a—Ó7Đe$à¶ö‹ư·[¯Ị}̃ơrgqœJüÜiŒiVÓÄLå Â®~L¸:°RâÂL8ˆ³ñ4„5]̉̉́0A•Ê×å±î:̀ªJ¡¹“ˆÿ°a®D+¡#ă-‰ÙÛ wi˜!d© Â¥÷“úMÑbÄ.#cL ,Â8 c·Óz÷Éå²₫±ĐóÆƯ`óV¦úꧬ^ÄY9´lÅ˼LHcÓ·Ḉ>R̀$óx0…0‰ƒ‹–úïî5ptu&Ù)<´>ïUÆo*i]l0ÇkØPJ,?•o¯Ù*Ëó46ëÂ9û£gh^cçªI· gûåE1Mñü«eׇáéVHUºÈù ¸èÂæø˜LúÓ‹É /_®— Ăi]_ƠúMà/¸NW´«¾~öNƯdQÉD̃j!+é½ï}°Óº«W!¼¾xC&´zŒÛÖ9Ï4\xIåúQ¡Àψsă‘%#ÂU¬!zéHn«³K»€Î°maZ€×SÊø)ö™xÆ7ïWđ©诳‚s²§è¼‰BB<Z4bq:²Hß«|ô™iFE~vKZq{4ÍêơêRÚEML* JBƠ"¼ ờ‚ètßi8’ . Wú¾º£´Qà{B7˲byr˜ +˜ü,/ïÆô4â ƒ Î)„7–Wrù2Ê–÷ßqmóqz)¦| 9G?2{‡M¨´}(³đ]$<ôNøÄX²øÜû¦ç2EÅöN_¿ >ÏÇ÷+pç×qñ‡-¸́¯ă§qº6/âÈëĐáÄ ;QƯ±P¯y†K#ợtæO ¯9"hÓä©0cû•‘µ_8­OơßIÙÛRÊ€¹*ïö¶jií Å Ú+°‰l'/XÑÄ •¼¼%—ˆ äoZ^LQüÖ¿¿¬5B;›FM·G™®q‘ZM9₫dx º(éSlaƠƯa=V”qQÁ=¬ÛµéÿCƯ{1^K8Đeײbóƒ„âË^$îiT4Ï/a»ïæOpvI§»Å%i3]÷`ùEë…Úth,«ñÀц-Ö›^›n™`A™ÏD™ø ₫”º+óơá·­k;€¨c’x̣'— œñµ«¶âä+ú6đÇ;wĐ̣äA]OöFWƠ<ŒÁVèƯd |WEU2Ù¦­Qé8>̣n₫µöơÔ •… Ëû8öŸUlÆÜV[³Û<37™xQÜ“–CÙ‰^›>· à{-ä]5î}Lºú•· Dà_X!R ô™eK̃PK`×;6 *î́ˆå Ăm»Í|CdfSJP3(GIÎz Wd·K³fz9ô¥ă¥™ˆl₫[h&›́âôƬºÂW±,¸Å ¸¨S+¡ö¦w¢_̀$Ư ·̣ĐcÚz â‰÷̉ï‹ †³ÛxºNç9(¥cràq4vzƯD‚¦¾h8¹̣åMQ‘q³¤‹½ hyư¡!<¦héäÅÆ¯̃8½É{áƒGíÚ¢vä>hù˜Æ—ơ.R ®‡Jhi ¡:÷PÜÓW¿m‰ǿ=|ù±ó¸•ûïihZËb>Û$l½ÊLK$!Ö.•E¿‹éº>¹u£Ááâ"›­¦ÿ2aü“4‹kCÿa ˆ¢ä$ÎƠoËz₫ư|NMâi˜ëñ½³ÔeZ5µA]?QưHö_¯:}[nF0¯lw¸à$Q#¦†A@Ù.í4—‘{åđ^á}t·|¿!`Ü+âaØ‚‡à±Hƒ×[¬,ßøĂäMÛ)¦†’̉0lơ"̀•ĆÍeûüm9“±¨‚«́åÛ¼OÏ‚™ó³ä½ư},ëÊm-àÈƠpá“Ü·KlVjùl]¾¶RJbucE"ªçtFBlâöÊä³-ùơ¥RÄP{pCzóFœˆ~yæ8O­ơ‚Üî° 1m¥B¹Iz…KVjâ|½\ï×…^,¢Q—́¢ÜRÉĂ9ÉÖcƒó]ËÆé_ y·Yk;ºùZOƠ: •áf©Ú+S6Hë§gÎåvî ñ¥ºIåé²ï.ÚÓSÖW]“‘V‘êÍ».Ơ fö€aCÍ`BùđˆG”¡á§q¾t•„”é̀ÈŸỮơFN̉nêíØ ®œ|ªo¿wï/8EÉ@‡wu]/<ÙÏ¿®v!1²ä<­pÔT~Z6d0÷§CÚÚfŒ›±åg óÓlêúôRàø4ˆÍ êÍ{ưÂ@p,USë\":ÁÖ{ ›7mk÷Uaf3F–Ä'ª[Z ›²M^ª¦¡h̀ư'̀m)Ơ£ç¦>çÓg¼ #›•æ 7kïEVœÂDoe%á*íw‰wÑ´“†çê‘¶fØaûX¯úL>=¦l??°XÓ$¸²îÅ/ă5MíØOŒ‹Ñµz%âö/"ßË3‹ívÍ2xä¿RJ®C:®¨(’aÅrƠç|÷­w†2éT@ 1½dI`߯ ¢zBA¼´F*ÁăăCF’̣)ưŒüˆ)>¿†~¥µƒ"˜ sÆÂÓ¤™̀;NlcÑà ó®Jká‚U ÅupêAíW…̀mợå,¬Úứđ°¹ÎĐ­ü*™Úrí£Ó‘mjö¸ÎĂ™ÉèáöºÎ¸́D̃cïÔea‡)Ú„wèÎP´đTăÄq7HùkIP§‡{ÿ‰M_Ø”’f„"èÙ̉¬’̃ÇƯ¿æ“ñs¨̉€©÷«4 Öû ¬±àê5d[>sܰđB¶¼R₫9S+0[²Gl©†-{ÂĂ‹Áe¿  •¥Ăƒz``±iOZP/Œ#0‘‹uŒt_Î)V»₫#j½0&‘2v í3"FĂ/½1~Ybí+ʃO']ïB¯¼‰8­3% ¯¹)ˆ_·{;²ßƯÍ_)œ®L2‘{°²ùí̃àO&|Ù—`efÄ¡ÇÙ”m÷&̃”WƒjzlÅy[+@*`´·‘Øá¹rWo:ßê·¼T€µ{ß9vWÊ©êR`¿ó núĂ2b}¹ÍöđZnƵ)K¹óçùú3hig­Uz©Œß£) *ơî±`̣å.(öƒQ• s«‰'t·äøIA?–ä‚!£œ°(¹'̉p@'}k/nù«*æƯƯVÊ×î¢É¤äc{H{äßÈ15pjSÏ’üs?Ö¤̣íÆFlå8ICaˆ¤ /‰̉›Â3ÓÑăÍ4Kh¬'úgÆ¢&z¯ŸN÷0ñ¹đ  ́ ÜñÛ›áxÎ$›Ê’Éù‡ơL•ÚáwêÿÚ‰|¶¿LƠQo‰u y±@PđnƠ(–ăGê*¦E…j;(ï3=w7¸ÓÊP=@¿ÆºŸ7[bGs™ùU"o<bZN̉ŒPÖ—ñƯ Œx[oŸÍH̉G+Lö¬Ư…@´ ní2b0ŸçÏzJ:œQI|U#`Ù&ô‚ÍBt¬b [{K”Åg₫zOóˆü±çiE¹èÚP˜Ä¤½Øi"=¼Kâ{e’óŒú̉­v ̀Vˆă…Úy} OŸ1)Ö̉y~æ„]‚^)‘Kfo!Æ»R0ođp0³%–:”œLÁfQĂ˜Z—¹»}T%‘‡ă7•0đÀ¨Ø¢…§bîtXUíØ†«.¸Ă4̃  Oiøă—-Ó×ơíS¿ ûijE_/Jâ[†jqø´ Ù¡¾‰ÎgSñ÷ ] \ª0ư>2Ơ‹¤WÀq̉‡‚‘€p‘¢ÀGÉ¡ P?¥²¬%ơÔlHöĐ>¨a¦|{n%ê„63,Đ¹,E&p6RE₫l’€̉ù‚è̃sg5‰gëÄ1wû~TÀ^Jf¶yI;÷† ôî³'xă ü©¡æMÁ’Ó¶Óẹ̈öÔØ¾ÓïÛ#%7r¤Í¶²^DEß`̃¹À‘”Ü¢0ưêƯbAÉqܲ-2÷i3ê‰ ±z̀@ca¥ñw¥ÀœD̉4¦‡cÄR̃åøAh³s/̉,XăHŃi m°Ïû¼I 8:û‰†Â/!î¦a §Ơ±{¯b±Đm/Û5đ]#Ô1”ˆ±ẹ̀︛£@̉<ñ CbxnÙØiR¶l|ô;¬WĐ4É JÇqỷAE"QơN,27(ª³Î$¶Ïr”ó¥k–‰M … ³çÉæî«dÓ¾Åj‚Gfx~ª“j̀)^ă6ͱ hé„«©c^B|œ,´È]"^—Œ³7̀¥÷-ÔD'‡µ#,DÓÙ2"ˆÚ7˜sÓÅk»v…“Â(imGöhîµ”P₫ä >&!ô+öÁ_ü•ocÙ— Ưđ¬́n '£ôkZ®‹»Ûvw’ [©DơÓh^É\²§f°„ ơ”öDŸ¾|3¯†ŸAĂl­¨÷(ˆ× OV₫`¶/»Ï %=¾'{ôŒ„QuĐĐº¶Ø~í– æĐ+Æ÷dJ₫*ÍÔåª*:@₫̣Ff…¡É¦Ü“da}Ê}ª•hkbtnciIăẠ̀Ư´—¶Ä;\7fœHË!ùrËF́¬áĂ½+/"¿ZUÁ2́xÜ+ÔU¾đ.œ³]QMVX¼¦ûB'%9ƒM£Ê,C̀r[yNíE´è‘æR<链W±×}Y₫“£nŒkE>¯¿˜sf#ó{f’ ihw\oéÓ+ ¶¡Œ7¶‘@9ÇÜY;Jo0fÂâwŒsOÇ}̉ƧT#ùœtx¾Û'q¶X2qéRÿđà§₫°«₫&<Ö̃‡œŸ̉SÓbOñÀäwôâ RFyqƒ¢´ÏqÙ©ĂJ Á胇eÊaüW¹j[zègSM²ŒFnœ}+£záênø µ ­Ç: [%ª.Ú$Q+`MîÈ1äÁO QùÅÉëẸ́JÖoF}Ä–…¢̣EA´́7Ỵ̈g8ín‰ÄéW„F^c"¯?ææíZ¼±`ƒ»iÖĂE$Ư›–¸Ỉ#A—4WàI>ؽ¦¶ơï˜Ä*JË‹åÁáWyĂ_HÈ¥qF₫–su±ÂÉèÙoV÷Irq̉KÉœY à¹A÷₫”[_¶=áQQ È>¡u¬Úô,_`lt+¢rÜYÊ W§Lô-c̀¤ÏÀVø;íÊ&æsÙ«̃Q{3 DóeD!ñÜàÊ9ØÄaeÆZBSR¡Mc>Ä{Êï !¯óĂ©wÄ´ˆB̉)çP=0i2‘]Ư E5—₫BÙx…ÑŸưS¹QZB˜;Üv…Đî ®“°jPs>.íÆyøß̣„ø[½>›:*?ÚgY.Ôúè$ƒ6Ô§;]}’FaÙ“ŒÉ;Ú§sd4‡ ưÅ1Đ–>.g²$%̣h_XØÙ±ÙuRs›pĐÂî̀nơĂ¡­jÁ[rĐ^Ö̀¶àcÂCÊƯ’ưÁ¢} #ÙXd^œY?³„X@#Ï WÑr6XđÙ9ÖünôW‰ ³ä„H+ú̀ ?XrZ¨Ô¡’lBÀ÷ƠùƠÁ;-aî†óeÚƠÛôDś́‹±™t­ºƠiI¬s ¾¬Äj-%&ĐĐ1­¾̉±üÊ·ö—„Ü’碕÷L¼0^/́o¦Q:û©ÍÅ.R 2a*Ø|Ơkîh–v5è…rÁ× Ë]Îû–oYúØĂTRB³ñH[H!ÛƒÏר÷™´/qɑƢhæĂqD̉û ¦:ofPt g̣G‰å¯0ˆ7|TơwXQåÂE‡î£»¤*¯hù¸0[ƒ2uÂn*?Ư¤ƒº`̣Ï\Ù$bk¬4ªÛ…‡áé̉Ú¤ơŸ€Ë¥b0ÔÉpÈm´+ëi°]grP3Æ“ø«ü¤à̃È»ë¶yäƒI¦ŸëÇ“&˜"ˆu4M³£áx-ˆ«„£ƠÜLoÊĂ ;,ípŸ …‡nñsI‘aèâû f~â‚^_<å9äEpqiÅwg^É̉6|‚¡1‡[ÀûJßfŒÀˆ<Ú́‚ œ]’Dz×̣rư4Ï£¨ü²1ë^¦L­x3<ǻÂôƠt%¦‰G»Æœx×E>“ƠÅæç̃₫we₫¾üñ|¦<)\A"o±4Ơs{d–Źâ…ªcí%ËÍû¿±&¬Xdư`-ÉQ-ÓZ K?>˜đ¨„ woß\ƯI•­_˜Ù}* -qäa´¥ƒ® rˆ|í˾Ù&’ă0LfQ:húđăƯàƯ+d.QÖZhb­mo©ªO¥́Ö,‰MÚiáUîí®±ßFư¹|ºzFPM`IîÚzP#‹zGÆ=̉fi«[.aj¥YQµ¶·Ówï³y |–ém>£Üáç ´·Î‚Ô&’q%Kƒ1YÂ+ éG0­ iE112$hULÔ‘%_xĂ.‡Âv~¤ÀU9ÊÜz³ó!W× ”ÇèD+À*Ÿ\Øë(¿µI!Aƒe¶¥̉"ñDmB¢YŒ̃=̉¸Ç„Å0«tAHG26fËơ'61M½¥6¸>ÇÇZ,uDZ9*^•đ2!F×âUŸˆ´¾««Û8M@É){™s’}7üUúÂă ₫ÓéẠ̈1•G¡ù©,ạ̊‚®C)öêú¹sn?Ç–ỚjÄMo&æB˜s†-̃ơœÙ,'ͽ~0Źé~¨à₫̣ÛÏ̉)R»§Ë$yŸ¢BS&\y¾néÛ–/#ç(#Ê|ÚÍ'µ˜îÜcÂ?)U¸ǜ½zßUz)ê7¿gûc…#~ëŒgwüm1J+́OƠÆú¾&‡jb:Mtè±C•!ÂDzD̃Ÿ“₫© *Ăảö%³›¦,¨o§©?ƯÚ•û´4¢ÅL9ôDÛgmZ ÚïÔ›dÑíè>Ö÷zæÄ́”g³Äxˆ·)–:́8ÔxíÈíƯî‹8£t%ÎƠæQÔ?PªbK°¹øÛ´î­×kUáùoºØéY®¾BED$Í’Ñ–ÿ̉ww•₫Ø„ñăMGRƹèĐÄ·́Tç}Ê¥DØ£-M#́¦ô6ȾÚ1³¦¡˜R÷ô%‚ÑÎTẠ́"‘¦+F ¼{—AE¿j§vxÍnßơÙg–¥•°˜yÍ\oil³âP¨á=9°j6áuµ÷ƯElœù†]ÙE¹¯—È—¿6±̀ÛK6̣–ˆ—Â"}Ơƒ²ô>Zh´£äC)ÚÖ\SÙÉ6¢ ­07—é²N}ØưNmÔˆ̣?ñÈËßx¡Vǯ̣ E£è´§¶:Ï3¼k²]²357;: „| ]¥NÄTK£ÍÀÛQE\Ôî½X‰~¦¤¿̃½˜홟0uÁJIåưÙØ´8’'Ä1Yf‡Z ÎQÄBÖ~±l\ƒ¯«,’3…Ø̉]ƺ ØƯŸ—•+¤D©TFâA]‘Ïm,>%„±>…Ÿ\Ë”¥ Bg 5wñˆÔ’èw4²è w;=hQ¬¬"ư·eÿ”J´Û…ï¯DíVI“Zơi†¼ñÓîË>%}PwvçDÔ¿b–Åw°Ñqº —ïcvB*¸hÀÁ!yƒ˜¯á7MN|ÓƯ(΀ñ±̃Yåéd́c©@á/×â_Ưz–Tä§Úö2 1/P*&üR{™K&¿è‹[í ÀJŒ‹₫qZù™Z(p}¤{j x8%mË7ơ5=·4 ë–äz=­ïPúíû̃̃+Àó·ø‡ïî ¨ù·& / Ùk8»pâ&÷áƠ×î₫Cª‡V3ñ†¾Œ%ª>œ,uI¡«Ö‡Æ} óï5#¦½ 8CûtRà5Ư­Mn"?ză]Â’ö…^mCƠộ30ß;t́\‘qø¾`‡´Â=y®#¼~́LEFø!¦jƒÖ—áêY‹3 ¯ßr¤D~N°₫£¿̣₫MÙ‰§^BU}ଵ–©STăQCjæø^ætL{ͨ¥0Œ:^QÔ ̃»/æ7g |ñk3 ̣Äû XmŸ1ŸiÚ'lÛîm’I/-pIîà3L±»–aúÊ‹gdf&É‚ë_÷ï•q½Zr›¬èEµoX"¯Œi`|»‹Bµ¡vªÄ›øp„a{w7F,À¸ ƠØ£NÍå0"̃ïu!ú˺Œ ¯ªod#Oáaêúxü¸*]%{îƒÊ‚.›Û“{†„@›ÊzM£îåơÄ%“e-à^¶p¾§ÍÙ1‘¦ÏëU€–’³Nûc‡ưŵg#«ÊÚ±?gü1S¦Ö!×ií•#_Ÿ¥¯)s·Ó{VÍ;™öót]á‘0Ơ·<5]âÎú₫©̃*ƯVºp1¢ÆKW3áØyC/v=Ø—Fy«±x\₫ $|Î#ŸÆ»‹\̣”â¸t‹™H«u…Ø”)øú©d3§) §̃,©[\§vôËă÷«zF£I¸ ¯ûè`²PQ¸ÀÚ¤#fy ºé$?½f»̉ĐIV¶íkj87é¾uÂΆ¹=Œö`>rûăÈ „‰ }*¥¤¡̃7 _YÚÈnbàAv ºpM:–­Üz AÜ X¡°Ư|—j ṃ y·5¥?TVx¡3[zE&¿ĂYwÚúúx-Å8w+’×J5;xE/Dæâ½u«k‚Ơá®̣EQ(Ô‘HBeùËáêv%èSe?Ơ¸nOÇtÁ)Üë/d©†a$dá)Ú_Ê~å°!Q†ht‹ló¤½x[~»†½@»m…;eFGâ(àk—ĐÀeA3ĂKäKđ–IÁWĂñj‰f+çÓƠÜ¿WS}ˆb;”äE¼G1ưœO?ƠêÍs߯g̣ܤ"l(c;Ó!½`4~ơ¬2F_ÆÎp“ƠL•Ÿ"/VHî¿iËR̀ÆèŒư%SàHOÁM¢ßèà̃…ÜÀxI8n…i©¸±: —éåñ®°J×ÎMU(¦¥]Já>E@PL=ª’*W÷«ó…¸k}›Í\E÷&_Q‘ơ—'yäB$¹F¶zDæ ³|\}₫ ß¶WËp¦b[¯é)°)fù‘/!¹ơUÏTîûb;̃ @̣äS£¯̉̉*™÷·8få²åGé®Ä:Zá&:*}̀Ö„q»n#C̀̉gÛ°'&ÏZY»–æ½Kñ Mb…¶̣n!;|.‡»°vzLøØ`µ•F¸®Cyh-mEïÍĂg‹É#ÅØàJJËĐ$öñ.Ôu1ÎÛñFAï‡æ#ûV́ÎÀ@>ÎiØåi7ÖÈö(ŸÚ‚¨°®øå½ÆESL_[îâ0‘SÙÇè«p ίZû!¨/ïz„mxḥ{·¿›¿œÚ6® ÍÚ=¸”åч8ñ́f7-§]¥úyÔ[dJ€ù—‡|0›uj0̣¦È̀èDÛ²yïåW9îæàîI£!ơJˆ? d\Ư§ơN—tǘ ‰çƒ̣¢oô²Ñ¹':3†KTkœ®k­E¢9 •Å‚¢ü•µ ­’° ÛẸ̀ri¯=‹Z*“üQIÚж{đ“̣_diYç$.sªä®.tûÓ}₫¤|iLJ–O]ïl•̣Í‚®uVÊ€·©åeơEoä™iNbcü¬ ÉH™s²k‚™³Ù6X¼Ö~0±½àÛˆV(¦ÅÔó•´¸‚¯A5;±qQ’8̀;¯U%sIêJ2Ü胾”³eĂÊƠuWµ̣2HRMpàƯmÂ<̉Óæ at¸‚zÁ3QŸÏ[ÍN­¹›Â/Åʺ̣¹Û÷ ¡3’×D†Ơ9Äiüômb1¯¼›´ö¿Ô?×*pwce¿$¾•săïÁŒY”ơ\„ \R™W&3k—8÷o9¸dc r=W[½9pnßÊÎ×?ÇVXÔGR@µßxØP¨ø ÆOdIá(°£[^gù¡ åÈ?oÑÊjWFÓÚ3Ô!pÛ° ̣KCáÖỲΠïs]Ü[jZvÙŸú¥Ăü1ËÖ)b9}™/1¶YÖr´jg,çq¯|́–œJØÉÛx kÆ»©6âîqÚ18NÔ1WÙÔ=•¥?GpÏ·•%tHm=˜ïUlÉürCÑ´ endstream endobj 1734 0 obj << /Length1 1401 /Length2 6058 /Length3 0 /Length 7007 /Filter /FlateDecode >> stream xÚwT”[Û6R"ÀC7 ‚¤tw0À3À ]̉ ¡̉©H(%]̉ " %!̉Ư)~cœs̃ó₫ÿZß·f­g}ß×]{_×^ëaaĐÖ㑵ƒÛ@”à0$?/H×ĐÓă /$€Ç¢Eº@₫²ă±B<P8Lâ?̣0eS#Q@ 8 Pơtø~ ~Q ÄÿÂ=$°ÔĐàTá0EîæëupD¢êüơ °Ûrüââ¢Ü¿ÂYWˆÔ 4ÀHGˆ+ª¢-ØĐƒÛB!Hߥ`—rD"Ư$øø¼½½yÁ®^¸‡ƒ47à E:ºÄĂ büĐ»B₫ŒÆ‹Çè;B¿zp{¤7Ø  .P[ ñ„ÙA<Tu@OEĐrƒÀ~ƒƠ¸?›đọ́ÿîOôÏDPد`°­-ÜƠ ó…Â{¨ ĐRRçEú ¹0̀î'́‚€£âÁ^`¨ ØøƠ:P’ƠÀ¨ ÿ̀‡°ơ€º!¼¨ËÏù~¦Am³"̀Nîê !x?ûS€z@lQûîË÷çpapo˜ÿ_+{(̀Î₫çvn|0¨»'DEáeÂûÇæA H $@܈­#ßÏú¾n_N₫ŸfÔ ₫np7À5$jAưáù#À^éá ôÿOÇ¿Wxüü€Ô Ø@ 0¼²£̀ûßkÔù{@}3~üèçïï7 Ắà0ß࿘OIÉDÍXëÏÈ;åäà>€??À# ÄÅÅQaq đßi´ÁĐ?müG¨ ̀ˆÿîµMúơ‡́ôÁü;—&E\À₫ÏÍA [Ôƒÿÿ̀ö_!ÿ?’ỵ̈̀¿̣ü¿;Ṛtqùågÿ øü`W¨‹ï¸H”4à()À₫jù­\ ˆÔÓơ¿½*H0J ²0—¿7P‚ú@́´¡H[Çß|ùm7ø©4( ¢ G@̃-?ô_>”¼lQ÷EÊ_.J=ÿ.©³…Ûư”™€°öđûâP\üùQz´ƒøü¢1ÀÇ ƒ#Q!j¼@Àî÷óL…@Ÿê€¹@́‘?]¿­ü¬¿Ïï§ù_Um==PNä/f ZúkưKéˆÄojn+îT̃rV)Kăͳü{~±5æ‰IO´0’ơs¿£úÍŒ£îrÖve”©Ú“%‘#4œ;gC>æY!s)ʹH4Å%¹=ü₫óĂœÚá£hj̀̉íƯDZ"k3L3¶$£‰«ÑNÁỢ•‚ï­ˆUSñMÀ(:e1wˆbå¾5bsc¶E·|–1Xx n î9½0cäjkçX/®¬b9YX£ÅïàFÍi±}xñªˆp2ú ZíHTE-Ç͵8ó×̀où1ơ!Ï G¹0g¯§ûº¶<-NxåÏç}:„lIÖ EcºíÈ&s°Xs…ôA$ù½‰ŒqV]6í“ß6ÛΪ3ô‹«okb.„YÑăØnCZƯS÷hÍåƠßơ9iMưèæXùàè{Ó#”+»Å=ÿ O£"”p¥RªñMêÀú„ÓG¥Ù4®s·AĂIÎƯêë·z̉ ¶[&ä›^Đ-ñpµz^ó¬&ë±3c\ÑíŸ'%m=ño‘D+¬Ek{Uí¤Z\³æ¼ưó¥]ˆ„³K-b4'0X·°ư—zÿ#”ÆëưŒëºá¬‰­S:Q¯Ÿ·̀qË‹ Pàngđ́ ’"eS?)<ä%C2ƠM@GÖH-Ü]ôD„´Æ)×jZF!ë&g¥ˆßăNHƯ‘kÆN¸4dRydÚ2Mº“Êæ‰…}YçíkËâ ¢1tÖmbé#M½p ôGƠ£æ9L Ó¸^ä‰Ă˜iº€fñÔ‡G¾¿đÇÈz%æ`læ¼G³L{?Ñïu·ÊŒ~ëdúÙ·–Ü›Z*£ C½ù}¯C˜åe0±#¡Áü–Ò\é¶²–LGùnKRÛMáz~9ei#åæ¶¡hÏŸ|sa£ë>Æ9Ư¡ƒưƠ¦°ºFÇ–«Ö´ûêËơ` ×r6el:&có³Đ’ùeÇS …Ơ×öóˆù‡@Ù%µư…†Ó±ÉĐiGÉæH­C b̉Àø†Ø/×V½¹ÇD»~"‘ÆJ]“ƒVMªÁ¡ë¥$Q& ¤Xs»Wc ?J#íO¹ơYj1Û¯ÅûÁM©:¾¨éƠ'½Œ©u+¼EÆw"&¦¥ơLB¦°–sÓÜ 0Ư°>$–Ï+jÀôDkÖ¡·)Ù)O*É®đ©øZ¯‡b19Èä+C‘ôôº¬¢îƠëoDXïÜîF̀½GsVíß°¥  Ú}¦G¶ôüùĐù«jÙd«"̉L^÷äWÎÚW¸í/.ZiØđ¬!M£9̃ÛÎ…îŸäMd[Ö®@©»Ë&sb}AäpP9ÛßM,IῈSs§KJ;wØù!\#-Óư)%tiépüFTÀ'Ưƒ@f & %̀^¿nơ×›Wµ.ï›rŸ̉Îv>K]7µ›$e%: :”…fàÓSnÚô“̀T§¥¿¬ƒQ}´˜i—Ö L˱k«¥z]#7 êœñ™û{AÓ"º¬ éÙlû‚ố8û1`î÷Ú—Ûä†̃Ó >&đØ~ôæÊ„Û¡ÔÛei*Pƒ’ƒZ̀qƠ *E€y” úF(ÖÖÔA>ï+¡„ufÈjƯ\µôi¡{[—¼ï ,—ÑŒk¿œêÍ;GS'»AGçÁ‘)] ¾ê'̉¶W2Ôª́'(lºă- {w“f4Ë Ç$1_N ÷aèŒå*å®`ÂÆßXwíMaÔ4!†d8d“GZỊ̂ 'Åmu&ÈâG‘% 9N‹pµ6~jơR§Ñ•\Îå‰Â˜J›h^å£S›ˆpäÓ̃é&Sˆ•*ă>_#ñ¼̉%Ó¼ă‚¿¼ĐJM¼­é[ñ₫@(“̉ÈL¤3îÎMhæÖ̃ÆcăÓ;?’#&¾$óèO3üyäjí!ựXŒÆPođᡘ¿èƯ×C†[<ƒy¸–§g^!ùiŸlå3‹%́Pù>Fèiß7Ǘ ~®bæÊ©»³°–>ogNwăëv§Œq<Öîj|ô©‚É+‚O²•ë̀=Uï v&c'ÚçêÅ€{œ]Kg<‘¯9’¬4×̃ơ-h±9)>i³'̉̀ÚÀN/4₫5)Pp°üeßXQ—~Gb¹wØ”µỨ1•g•?Z©G…Qê'K~.YNöab>#|XñˆÍ¤ºôá²o7ñ9W……ª©bq× ØGĂV¸Év$uW?¶s‡qY₫ö›|uR™È‘ŸOơqø!‰›ïˆ̉»kÑ܈x‡~Ç?<ÖÙO+ê¯^„3íß¾́¾ÁÉ-¢FÜăæđDæ“æ DB6I}±dNé«ỏ‰§ñáfm[62Êơ—D°˜¡¹fÿ2K—T‡zBLe/<Ɔc{̣å Ù)!EaèÖaÿ:ƠÛ7Í[xVÏaXƒ{™ Ơ[U,¯'Đ ư"´Ÿ’M̉*¼hI^v7e2uPgÛd!́¾Uî•#«y×)ó¼ƒQz¹U6Ú7÷¤’â9¥‹/ñ¼^̃Ç(K88ưÔç-¨sûƠAÉYav‚¾̃^5ơ`QnW†ƒ-eA·Úh»?ñG%.È]¡—SÈƠ _â‹À9s½nß' À?=s(˜o¼@Ó⡲ôG¯e›¬iˆcK4“ª8H«!eg3‰ Æ»n.‹¨¾ÄÓiês»°ñÉ5Á2¹¸×{Ö±ơó¾]æ­Á—µS_•6«³ûSờâƠ¹ צ—\ÊøEùÏåÍ̀«X„g#|_s¬-ïÜ2¥1g Qºf^äë&O•¡»—>Oí¬6ÍBß2ß×µüîê÷úȺ̀í¢¦ŸXpÖÆ<Æ»Q»jØ$]’ÚøY$k'?âßÉtWtymшÀPî4=±=v|8́Zgq1~¿Îy¢.5ñËƯm/ p´”îUơÛxl³á: Y•¸E²êè»d ›´äª†¶1ă÷ÉΑkr0Føđ ÀmưUÏ¢J̃đÙ»ä>Å•8œ0AC¨Ía,ˆ*›à}lÿU0ư¾€SX&\•”ĂTss#œ̣-=µ{ûª,^cR2̉ËÁ‚â©àÇè2í…yø;} 7t¿¬o¤Q¥„%æÙ€]Ú¶0†TÅœ‹ U†™­ûx1)êvCF ÆMǘNñ2H'È»d«¥È™·K2‹N™NºS‚ŒªóM¥ÊI-gˆqˆ ®·óù"8hwàÁTgeù ¥”äO–¯Zí 7 ̉!•ªy¨·ÑB¨C´&‡¬æ™̀¸,l°Ç—†¥ÛwW"ă•mJ7éáuY*_„2 ×V#ïḤ›%–#Ô- ’®¿µu~¥Ù1Ó_érb*s roûFæ@cËU\Ê?‘ ÷„§*ÇËÅ0<¥N#à­»#¾zŸ+úË„ƒ&Å1ê‚?PI‰ñó‰×̀”Do³;ïMƒ7z°ña₫OƯ(Ă= Ÿ¼×iërwÙ°Ÿ²wz ̉À1Ax÷‹Ï·øÛ ÷̃¾˜Q™äN½¼=h{ÆkSx‘ă·ííFÚŒ̃¸ÜÀŸC;ßơØ“J±H_¹µ§¸†§µ“‡a 4 äôŒå&ï»qºöÄùđ*̃éÊ;µĐº̀öÖ‘åü†£j³Ơt“#ùcέĐYYsg©Íâ£2I/¨ˆZưeDñY„ˆ3/—̃¼¼­¿QôíAók‰§d4ØäuK’|{•údp¤:4­º&–ç¸h.[²§”×áM̃²@FâîQ´4Ùø=®3PK¿–ß0z/̉$‡ús’̣8&¯E 5ưbAC—J³gZÈÉ9Óáœt«h³Á¤~‹ó³Ïµ¡¡…¤G¦.V₫́”F•ûaĐ|£Á[2‹ wMM–Óú¥åÆ-dú7Å3CæÔªS­Hî,ºD²÷‹QÆoKÓǪçÇ»Ế˜Ji¯u®¾K÷'Ff…nỉ̃Sđï‚ƠJÊß1%OI×<‘-/âkzbåk{ư¾û®2œë g›ï=¬«·ÅéPLAÊ–ÁNA ¢ÀÑc!ß7Üà;Hsê3t^9-'!±ªÀë Ø9)¨èX÷:³;×;,ƯúI}\̣Ơ¦ù¤ÓÔ¶Et‰öáÔiß v*µÍ•ô>7¦N̉¶C,fß[Å•„Ç ½!Ü+E]”Ä׿èŦ³@mX¡Fu¤­±vOG˜>ć§bÄÛ«á\æ[Ä-aê#ÉƯ¶G.¹g̀æx;Ç›¥7SK³²U¸ŸÅ)Ơóq†|†\ÓK:™¢Í/Ëcñ‘:Q‘˜$ơºÆÑHI®Ú{œËîwêÙ?„d«zjµÚl™toîc~=pt>p)UDç,ç~óăÅQg4&H'÷xPnkù1ï~₫ơƒäµDÂ!t:j8ç²tśΪ¹‰J;Ăt徯Aœ¦cP Æ´=}<‡6ÏO ³¿ßÜŒ~wÊÇÍ%Ëd1¦wª{„òÆ®ÿÆM÷f̀¤´¥F¸îyÊÄ̉ûUXÈ+ƒZyánüÜ|³È2ù¨Î·Ä±̃4ç<«¹V9"®ĂV^ÙéYÏ Ơ^©ë½­'‰räz>©ÔδÔö¢Aº%¬–̃‘óÓ1óÓÍ‚!Q_ÊDH½^äKë$]—ÀÙ’œ]̃÷> ZWöÀWÍ Å¼è^ Óú,!°”c–å(<ê₫`‰¼÷“ 5 ©¼“¦¢ûÀGñnEÎŒ:×ö˜S7CíS™éR%<¥äܵÓü«••ÉK.{˲0÷ z¾Í̀x̃» "ià"h{˜ë¾ưf̃£-h©TŒ Áí£ ¥I>–o²ƒÈ̃9jͤ€úÓSÇŧ—dcX~­Uk²?of¬-½Ávˆ»Â£Ă1~9³0?YÂ.yÖ$­àQ̀Ÿ¸B⪥ÁtˆzÇ~1¢ĐĂ³Æ?Lj£ÛÚ¬Ö;Y¿ụ̀Ư¸2›ºª¤ y†@6ăg‘Ûă`»¡6¹BóoĂß `geØbÓl¾ÊơÑơ₫K Ơ·jvL [̀¤8Årܼ˜eáÙ œO V¥‰3‘꺣‹˜bóÁs5Jwú²ñdóùvc2B7*đ6ψ HjÍ{ă—Ă€)¬ÜÆÜ;zÈƯByt…̃^_ôƒ^N°A9H¤ˆ~ÙơøCỵ̄QXe.¡øKΕº!÷¾oÓñgíaAf+¬ï^œû²³‡»¯*hÑ(>Ñ;í º˜ú›XÊ2 i?»ă9ÂRϺc;`¬v™0Aç¹|{§{¨PŒà ±̣Ỡ£×‘‰–}ß@,Té_‡Œ« R¥ơZÅ ÍZ•±[ó—fŒrr®*RG {¦˜‹5ª; ”‚&_Đô&È;Û?.`³âÆà‚OĐ^„jêă »Yàâ3|0ÂVø‚]Md[¥SŒ>‘]ÛƯk$ÖàiíQ4/.́[Ôµ[Ÿrkù¢¶bßW¾¢eÔ=©·¨¶%̉Ùî-‘YƠf×PŒ…0ơ”Ôó`?ê¼ÇÚỀœ̃©c—å~YƠÊDH]5™·ó ̃TYœÈ‘¤Êª3ÉB©o#ô¡ŸN—QyÂä–ÙH]ô„^‰È÷iËøçûỌ̈[[\ñdÙ”>q…]̣PÈ>¤¼ûăÍ÷>U—tDñ‹0%₫FM™4€¢KÍ' Ça幃̃`ø¡t«´û|ÁóưIÍ3_wåó^ăx:|»,°=¨s°ô²Çêîæ^³̃µE…è]ӱɵ ËVÂ3¢Ù'âơhgç¡ĂG‹̀6LtÈvbơigo¢Uăn¤ œ*ỗ¤;†ĂȾF¯zâGùç=h­"I×c2±©’…QØ–ÍÂôÈœÇ ŒÙđ÷úă5îÇàÍçă6£NÛ[L–Å—:‰—̃ÛÇGoö çkarj.Ÿt"·Ô´M̃œc·qéTZ7†u»|ç³bï2KëêĐ—;mËC^’ñúI|Ç>HăU•xÆ̉Œ}ĂQÏ%̣󈔗ӾÇʨ-zc%•ß₫æËÛ\+”KÍÛKa5í†Å2ư&É·¸Nå#̀Ÿ­E<U®B}·­1T÷*/û©—5 >6#†pv›wªĂ5ĂLŸËsúo˜}‹PŸ˜Æêp¶±;Wà5T?ox|ÿưÇâ8…‡» _ºâ#`£³#‡ăï§,ơŒÄÂC¶'«GlGüa®Ô]%ô£Đ·²aûñä^ƯøÍ…̣ä—:Là#& f₫é—ûúRcR[– c¾ƯƯÜGLÏ\üu+¬'êÅaø§¦₫N„z¦oEk#̀øz-ên„Ö;ØX ¢€H‰¸µDmú@¾ƒKºÍ¿cŒđÙó3‘¹ú‰(‘Rưç˜"̉γqööÅKéƠXW$E˯öˈqœ̀‚¡>vÉqr¿ŸöçTX5zṢ†FZ}²®ưÚƠ™ø endstream endobj 1736 0 obj << /Length1 1406 /Length2 6162 /Length3 0 /Length 7128 /Filter /FlateDecode >> stream xÚx4\íÚ¶è½F¢×Aôè½÷AÆ c3:ÑkDÑ{DoQDI$z'B|“ä}Ï9ïùÿµ¾oÍZ{ösß×Ưçºö̀Ú́,úFü v[ˆ*âJ”tŒ,„€ PD&`g7†¢`¿í́¦w$—ú„’;„BÛ”A(4PhzÀB"!1)!q)  J₫ D¸K”AP;€@‡ Ø•®>îPGºÎß·.07@HRRœïw8@ÁâƒàÊâ‚®ÁF0‚̣ùG ®(”«”  ———È)€pwåæxAQCâî ±ü  rü5;ÀØüă0BØ£¼@îÚƒ‚!p$:Änq «Œ4´z®ø°öà¯Í ư+Ư_Ñ¿AῃA`0ÂÅ÷ÂöP §ª-€̣Fñ@p»_@ ‰@ǃ$ØêB ¡°_3 ₫Jƒ̃f¸ÂÅG! ~ơ§ u‡€Ñûî#ø×á:Ă^p¿¿WöP¸ư¯1́<\MàP7ˆ†̣_´‰àß6 ”@Üo°£à¯Æ>®ßÎßfô ~®W€=z HÔ‚₫"đC‚₫#VnH₫i½O·́ù¸₫7àŸ¹thæB\ÿ&ú# (Œ¾ưŸé₫;äÿÇ̣_Y₫W¢ÿwGª0Øo?×Àÿă¹@a>!Đ̀ơ@¡U ƒ@k₫ßP3Èéê@́ .ÿíƠ@ĐjP€; Í/t_xÿT…zĆô¡(°ăÖü±›ü̉ ‡è#Đ_Otø_>´ÈÀÎè§MÍß.ZCÿ¬«#́~‰MXT rwù Ï½ø ¡Uiñ₫Mf€ B‡Đ3́î¿VH h‹̃#4ÁÑö?&€ ê†AÀ¿ñăEÁîîh₫fº£¿×¿åxCÀ ³°t˜Óë°ö‹z/₫Ï£¸+«Ñ }Q¢(¹~ÚxYjSníªî§ëÏ—ELÎúÓó́]Œy?êÎ ^NSÏCa¨ô­+đç~?îv€0Ù!èÆÅÓ£×Éö I[b[r&›Í^…‹÷ˆl¾úRxƯ‰Ü|(¹ pŸ‘²¤Ñ£)ävnc>µ`a[E Y<"#w·̀đ0Ö0¿Æ| ;Wl¥ưî³n—9´´ô.§¿/]ä¨@«·Z¬*‚‚–̉W“%w8i€–*1G³ ‰Á¡(z¦T–ÀJ[äÁ±ŒơX|ùÇtA[ Gƒƒ®Rđ½'#uÑY™Üå#›lăï‚Dw›“¢ùj̉ÙÙ«í0Ά2ö«E`y½ØÔLܺÎ7:Óˆ’̉s m̀ÅÆX¼'¡"Ö_&î^<~–•($l•*“øôRQLÆä:lo¶xơ @AÇN¡¯¥Ëâ´ê1|Oàôe´Âœ9~̣µù]ûPOä‚m‘j*8Á¼#kûíVb“†èÙ{2S1T­Ö¢Ë†;>7~:Đ0/[¿­SMú¡¼äük¼©I¾1Ùœ±ö&F†îm ©p… iRb ç½2ÆW‹•b#/dBeR%‚€O>LÜR6؉'­]¿cĐóÇ:ÁÖư@PßZ+¯ó¡ăă]NMÔưhăvÂƠWE‹©àñÙå<ÅŸ&6¥OåÙ?ûwºỷ°Ÿg®Pở5¸nór„±ăaCÆ›‰̃ÎÔMoơ†Ë3́ Û!5©Ö°"XEc¼h«̉R?U´‰e?H»ư¤ß½gľñä;¡å¹ôư`Wë¯ ºû®?ÊƯ•ä$œóá’"ëU:A’~Ø„Q¦ÊD§äD ‰†áY¸†£}#ÁLNk‘º`Û’íis YƯ¥ëÁY/ĂEk-ƒ æ€/ø«(DU⇧¾ÈÇO‚æzbï|]µ{O¶7­̀Üè•CtZp£,G4“XÄÏŒ˜ë«h_ ¯Û·Ü©j)C¨§úÑxOÑRnqvµ{Đú·!ˆ.Î.Ít™ ³TRw3[â§1O~p¤¬gÀ˜Uo¨j“a: ½bR͵=,®à„)]X‹>ôpá‡1xÚÏ ByíÇïæèlï2לĂäÀ<ËQ¬{UÖ†•_¬Ê]"6HßCK´Êơ§âX4îľ~ưcóî©!ÙOÔ´™tf×ÈaÆ€‡<×½rÏH Åô“9~₫ë§§ ‘Ϫ¥0¬ÔÎc óJz¼Â)T’º™BiOƠtË¢ẹ́ÄO"¥Ö!ÊPSD]úÏÖÜ$¹ºf锜Z™á²|aưë%X+¾7¦fÑLîâx*¥Îaç(;ĐOËÛđåPçt8“S?³µ‡m*h\è[c–×ez-dQÛi ªû:sÏEB½$0Å ï ™èkÔÙûi•"é ÷F-ªÛóww<»ăÇ-ó[~̀35k³ëåËogª‡F$“?XÖçŒÓ|9ü!Đ3q†¯Ÿ­ƠѤDGî¤n[n5Ù•g6LÜ“xF惾2`]$Y¾P7IÔú@$5Úøs„}k€ÎÇ 82´E;¬¨(>ưe8üv˜aáe’¡ïKăcûo~‘ÖdÊOløef®)¦oÍ\¾é_ÈE Ûs*û,¯ƠØ ¼~%of’H®…Ó‰»q†̉~¹¥uußYO†f÷g…ü¬ ©ô#ŒoI¡̣t™æ‹3æûLbq|7,ËEÜó˦±ù¯Óm!ÖslM±Ÿ¬È$`©ñMȰ°nÁ„µ5kî,ăÏoƒ@Dǘ«•{ u«ÔÁF¬ù̉ñ_S¯<¬1Œ¢ D2ÅeÈ>xÂ?d¯ăWeÆ×·³†O—QX ậøEMöÊçM§ñ>eÈ‚ߺ.ƒÆ\áƒÖë§?Íø•é–…`́;²#¿—;È`´̀­êR‡l|®4]Üí•eY|•›á#ÄÜ=²EåĂ’3IÅoô¢<{lJp ¿ÔI&¬±ôwY \Ïow'ĐŸ·¸‹·wKƠ=LûÚƠ¿á9Ï$éLèCGƯ äă*M§<8·Hv¢ƯÊ™:0 ³ª\ʶơUS’ceñ‡,y±|­M{6\d¨ÿ•íKS‹ÔMÇ{îÁ8•{ó_‹́8+{?wÑó·4¾Æ¤ï°ÆD.tÑÇΤ!t¯~xE÷¶@›XbüÍÉÂ3đđqĂ8‚r³2&[[½è}«ÖÇ“ăÆ\îŒS<·\̃¹` ŸÔ¾Ñ¶¢¼́[6:#±×ùåëđ€ä¦¸×ôœ'9ăµge(£̉ÁB;¹¥Zs*l ®P‹Đđ·çκf ovUç|U ¨Kûæ\÷¡oÅp—kqfÜZxˆ©pu½ăÖ†;F̣ æï˜~·SvŸÖàs+UUX¾Ïs ÿäøEOf̣}̃' …yLoSTÀqï_/`%éôoÏ V1Ro£æĂ±®Ô!Y úJơßG)- ¾E=iḾˈÀ)A0̣́¦KÆö»Ïh<ÍG8U›́jQx;å· ÜæĂ½àµª™}}HØ«‘ SÖ̃7xˆ%|̃¨ÏGœ´up>˜°èXÁ…đï ^Çæ‰Ç̣¨ˆ̃K·‹<,DÄ¥ùY)•˲ưÄR½íëÀ2ÅóÑ1ăó_÷GđîhÑhâH"¾OËËÀaé™k5qˆÀlLÔó±íZBmÓè''ïn®.\ˆ(a 1"+vÊÖâÇ me6¯   t®oÎú☆đđI˜¢>æ¡ñX S£¯¸¿0çïbŸÙ iå8WTŒÄ8-VàÓĂ¾4åj¯W™Ư¢›â·Aefߨ}æïj¾n™7/¤+èAiøßv¾À¾Ưg™|¯1TùÊû$W×jỦÓÚå Ï}w½i»1¸8üN!Ù–½d(O5ư¹Ôiç¦́@{–Ïè²6£=æè3ª^É$P’“4/£U0̣6÷Ä¢B’CoÏV°¹VæÓFNß…‡Ç# Œ‹Ü·á{găwêfŒÛSÈz3>h­knï}³V†–^[H!<ÿØ,ÜĂrH¹ly韑v÷»¨iضư¤Ì–›~pÀùƠ”¿̀MlúÿL¨¿~/îWd–äa S\ÀÆçdF^W… ¾¾n§ aQ2¥Áñ́Ó¤ư´ê†ôỷ@o‚ª¥ôôƒ-ĂÀ‚4”aÎjk ¦+ƒ„Đ‘¶‹X?èdcÖÅơhO3Q/_S»–|cs°¥0(R²f@ơ­K‘Éôä Û¤JA+u‚“ ÁS+9@Å×ç~^8Ơ6$¢"çEª{Ó]u÷Ÿ+f~ƯÈ̃Q(­ _íp{=~0L¼̣fỵ~^ SdaÂÄĐ+}û»ïoWóÍơ剬·ă0¼p/,±L\êö|ü‰°½¡öÇ3“®@ïs5¶›<ú°¢­q€ü–±;#)M¥4Ç;UG3SÀ5µY‰!2w«ºíYhn1ó w” à nzá¾6”hå’_XxåKnîïƠåĐpIÏ]z)kỊ̂Î%r8$?£&6»a2URÿzñ\â½3ÍL"Ο‹]"P ̃VQiGŸ@qÿ>&J·¾èmLø5i³³‚†U$7ÎI`£QÁ—‹´x]È3\ǛøRë8ÆDÎ+°<ÉÚƯ+¦Aÿ+c}…éçL“t»5ä7[ å¼)`⪠ÆùO|8]v2M¾Kº²Øtb–´/npëf«Ơï¯âdÈcö•¾q²ª'‡‹˜ËjæûÊ-(ïÉè^„ßê°…1>ós£±µà’e]àùú´spÔ¹ÔGä±sñt­¾̃C¯́µÖraUDØAŸ@µm÷ÂO%‰j¨¨÷©Wđíj&™•éê¦#*ç̀×™ÍÙ™Íê₫v5öؾ9ÿ²´M Û,M₫høø‡Èó³tWf˜Aơ‹dƒ/™Ñض«¥T‚®Ç·_0'»uªNJ`ÛüœQ Kê‚oS¼Ç»)pÑóăđ•~0Ó•‹́r´n §®ßÎyyÈÉC}ífd| ~„z@?ë|$ˆ/W&́BË;‹èb4j?DÖyë{ø%R#Û[Çk.ôsỴ̣̈?¯*Ë7y^«zjr¡ÏÚ¦5Á[Ñ>eÑ §Vp¥áCíè鳴륜ñ$»É¹,4øba_îI?¡Úü¢0¯.UÿêŪ…:£­PrĂZ›ú€_³W耡µÅd-1Á 6Ở÷iêÊ G¦tr®Gx>“é-”úË́ª2m!=ư‘¸g gùjZóúuOtë-›±5†l¶¢‚”đŒ©}—§́oõ~0–{|ëñ}ô¯²Đ¬&gûơêÛăĂÛ¸$!x‹JƒÈÖt…í @ÇMq‘ç¤[ơG«[]'Z̀ürt¦—EäæâŸ•éY}—2£•¦$ódN'ÍÀ1_“Æ SdNº]bN/ ¿ª!-—Çb\¸Ó„¤̃Á:3±Úx$3ióóÎu’hư›˜ ÷ ”¬LuÏz°­Vçk¢T½‚{m>Œ³ñ¢¯8ơêøÖ£“óù¼Aí`̀íĐ|ưdqó̀CÍWZËá₫âñä3&é&nÖoủ—RÓz<;†®N•ÔÉui†¶ &©²™Ôe7q1Ox?jL‡iY‡¦+&e¶ƒ‘ß–wC½V«så,#^WbzKOsƒPÛĂ¢d¦kĂeu¼•dEM•Uo®ÅcêL!Y¯fËú}6?½MÆ3΋U½RswX3Á}K*:™Ëá_ßĐƒÿ$uI­|c^"7}‹(¿WÇóó — ª$t}@t8^?ÜͶ³ê3À1»®7ŸHåB,û2®êà¶¡e'ÍDB÷Ó½/ø?9C6ß¶ UQ̀¿‘`&9¤ø<Ë%5‰¯•; X§x˜yŸI+Ê!»¬ïkaOÙ& …|lqe `†tÆỄ¯åÿØ@+àSÁ»ơ#刜ähâ€c ë·’׳%m›¶t`̃@•.^9ÂAÑâ(˜ä‰y‹¾́Üá䶆ꦔ\*e>×ÈDo ÜÓ$¬äbYô©BO\6ØÙ́̉¹¨ ¬sؼ3ôơc1u UÏ“’×sº$´vNsÄ"¤‘²„™÷èéÓ&Qœæ©vT’¼*⵺¸ø™v±~}VG±.-Ï#iïô’æ¶ÍÅQÙÑỷ>µÀŒÀµH;ûÉ́…p¥8ù–É’©̣Vÿ¹¸ªâîø['}ɵ£*Ö́n‡dŘç±c} ú{q'̉ÖñzeÉ"ß»xïˆÔ…zÀÛ°ØV4ú‰·ṇlôp!?¿'`Î`{³̣8$€_’Ê@đmÑg:HP®Ü|÷ÀàÖTMĂ-&̉Ç ,«˜bÛƒ®Û×ßÚ¶*l¶„L^Œ¦ơób“î zÊk,Çsj£h5ó–éɲë$j„,#B7̀{â†F̀<¢k´]Ÿ́=̉1U¥̃Œñ:k|6“”µO (kN\¼m<AE6VÜ´æ;•G÷ú³–Ô9ÙK˜%È´¤Öq̀ĂŒ³ §ªăGˆ;S­üL¾Çˆ§ôƒ¯̉{̀ÿYỗ-RÏ} ªE¶¾93ºëXr§å¡ØÄƯp ¾åIG#~³‡äñÄXcw9›j·dJ7>zé~~^‚•KE³]艮èo„yơÚLD«cX´–E¢'†Y­?O~wpû) ¬µWéç’ve•ù9dÈvVCîÎ( o¯ÇÜÖû~¸ư˜|¿Ä5)Ă¯y¥TCŒF)MëZ KĐ«æ¹ %^ÅÇ!£÷l¯ ~0M*iŸ'6S{gxƯ₫ÔỲ®Ú¼œĂAô„5lC%Yv4¿Qú16I¡çö æÅjcË]đ,®Ơ~3†U-Ư„ÎéÙJn˜ÒÊÓ{FÊĂÎ ‘Úă¡ åkc;Öạ̈—¶¼›ƯzVó°jïOœb^Gëb毕H»”µ˜ôđh»#í³¹佬́‹M3‡{,·ŸlÇ ©~ÿÆdM¢ âYy{`M/Ûsª¡Qø–'!ïågăæåËaàÂ¥í½³́[–Ù¾>ăI3lØ¡ÊÎ3¢év† ;¹úÂåưdp|̀d»¢6d/«7}ä¿ôƯ´˜¬^âÿ~¥Đ«.=öK;xà£h+^cáđo=À‘/‹|¿ŸÏo—ư¡ĂccëFÏ(æÖŒÀsN½!*Ù"?€ơÏhzÛ_ZϼJ¹Ë=“ÉïפßR£7{)LjXÚSOâưîë6>s”A₫‰—¢ĂDâZûµÑu[n6ë\9,Ûöà̀Wº¥6CĂgæ‘ÊN÷đV´«{©³a“<®|„ăÍ ‘Ô XïP4ÊèüË[vÆà]®†Ë oÊYï 7xd¨@’D/xß.Ô Kq̉áSÖ¶”œf|Ú´2xMwrPc#Ïsê;$Đ̉ùâỷb.­=a Đ̣}¤K™¶yµ~N­²…Ç·1"“Ñ¡APpṢk‚L?JMÑ™,O6Ë EͽKf%é20k}ªw}:™xŸGÏ÷G«¸ùØ œRaÁqµ̣q~~œ"~gKf[œ<ÅânfưÙÅ»ƒ->QøÆjLª`ÜƠHLæ*‘)P¯+xC–“ê/>ŸÓ½¬tØö_WƠ—`J[P{b Äo¿Íq똱³ƯË =Ị̂NΤËaÍ4ö÷/ed=ɼ†ˆÅFéKæ{yל¾sÔ*ûă~́÷£ñîØ¨]åÈ"?~y₫PÛS¶'ßCüîô›×ÓO‰±´ˆ_‚æI{i©0b}ÈC°;D«IÇá 7nAk^nmï4x)Å{ĂVùóă3ÖÍ„á/¢9r—ENÖä(ñÁ3«Ú’E?|³™s‡…Acg3¾₫ơ+U­ÓˆGKB!MS´`™9~_¯@‘‰gKKVXƒƠ$đD‡®Ư8ÓXÑ0ûHîG1%R¦¯G ̀ º)Yç€û3̀/)ÈbL#ºmÅ(¿ÇÇ]Kl±tïVå‡áx†WŸ»Ó‡‰…„J†ï9fZ¬"/!8 —äk¼™DöK₫ẻC×.UñÖ ừ…i‹év˜ q†ÎĐ‹æm ‡Â”Ùï¯æ̉¦c\½¼¤^éYˆ¸í+4ĤÆéỴ̈Ö>ÔtRYx9i" '6‰ơ)K¹üvø¢³Ík3»­gVÓ¥&+ơiI®Fi+^˜¥¥Ă›ởe‘…È'Óz[ Ù€¹W7Ô't(ÍÎmHXX₫óØ‘Á¢Ï?£´âJ‹^4Un8j:̉/Ư¥UçJóç)Îû±L˜%g7ȧƒỵŸH¿b8œ»ơÎØØ$Ü:J“)Èr¬̣ÊéûÏÚO=g. ?ÆyîƠ ̉gfæÄJ‹ÆÄ-ÿhùÓ̀ endstream endobj 1738 0 obj << /Length1 2571 /Length2 17734 /Length3 0 /Length 19224 /Filter /FlateDecode >> stream xÚŒúPœY× ă.Á!Xăîîîî¤Æ]‚»kp N€àîÜƯ-XpO n¼“™ïÿ«î-ª ×–µǻ}®n¨ÈT5˜Ä̀MẢnLl̀¬ü %MM6V++3++;•¦µ›èr$*m‹«µ£ÿ¿,$\@@7°Lè6TrtÈ»ÛØ8lÜül<ü¬¬vVV¾ÿ:ºđ$ï­ÍJ̀yG+•„£“—‹µ¥•8Îÿ^hÍèl||<ŒºÄ́A.Öf@€ĐÍ dh´h8YƒÜ¼₫CA+håææÄÏÂâááÁ ´wevt±¦cxX»YÔA® —÷ sÀ%”ö ¿KcF¢hZY»₫¥Đp´póº€`µÈÁ́âî`r€£4ä*N ‡¿Œÿ2`üƯ3Û?t{ÿAdíđ§3Đ̀̀Ñ̃ èàeí` °°¶T¤™Ư<Ư@ó? v®`à{ µĐlđgê@€´˜®đïú\Í\¬Ü\™]­í₫¨‘åp›¥̀%ííAn®Hä'ií2÷Ư‹åïõupôpđù²°v0·ø£ sw'-kgwœäß6`̉o™%È ÀÅÊÊÊËÁ9@fV,Đôrư©dûC ®ÁÏÇÉÑ `.ägmÿẠq¾Ü\ÜA~>ÿVü!±±̀­Íܦ Kk¤ß́`1Èâ/ >kO€+xüجüüóÊäÿÇÜG³8#3G;đñÿOÂÉù‡Ä̃₫wÖ̀‹ù¿ 8$è7¸zĐ"pÿ¡wv/Óop©¿]À¹YX¿ÿÇjGw—9€M,3‚ơ–<Ø@ÿ6'ú»mœàöXy9Y₫e–Yÿ ‚ÏÂö_\úï¹Á5Úư1é¿ơàFÙÿ†à+å77˜Ë¼!ÿ8À±ÜíMÿ¸›,ÿ•ø²eqü%˜Óñ_^llàÊœ~«Á1œÀOD‡ÿ%'Ûß̉ÿ$ø"eq¹€Ÿ|ÿ2å₫Sfíøû¸8Àmrvwt™›₫®–ƒïoá)Áï'₫»Zÿy…üNḶ¯Ö³‹ưƯ).0™+È̃ú¿sÄơ‡ èư¿Îƒ Lâ ~ªü“,¸€ÿ3ûlàü§¾¯Yܬ\@ÿpƒÜ<ÿåæpÿ=Ûà˜¾p5stùwúà£~ÿ/NØă_›&ơüGơúŸ÷ïœÁL̃ —¿2øÏMhæî>"·?VàḳøÏ÷ 'È iuÉÑL Ô¦>´ó®VŒĐƒiJhj_'ƒÉgƠå‹û|*]Mvđ–Ë/±ÔѾ7ë»R´7¢k¤Ï>§mđíÉj¾OƉê³ûH+3¸CÓE§b ƒÄˆDL¢¾ÏξÚA¶ĐmỰTùÎî¼hª…Xw2 ƒå_'—öƠj¸ŸÊç˜â´bß}^ *0ÍYÄ'‡sc"F Çüቾpók3oú•T>‘Éï,£ØG›=₫~Ñ{£R“Ưµ‡€’@Ÿúsb–ÚGü(MoÙ§´$vKh9—•bkbÔw¼›́œß@QƠÎe•Of‚̉¯£%H·1{_Ăĉ¾̃émŸÁÂĂCZ¦P¥µdÀè`$ñ6̉…Á\éưxe/Ÿƒo«07z§7 §çơÓ̃c;ˆH;8ë-â’ÏÎ~ØJpD×¼=¾E6Ye”u>ư6ÓgNó_†*¤.ÜÑà‹R3Ñß`}læ¡M¼©Ăâ|‡XĂ×a ø®—Î`”`MZë+³óåÁ çyÁ„~¯Â£·‡Q“—]Êt‰—)f ©Yâ¹>N%Zf4c2O^Ñ̉h¹Bÿ…¨üWójÑÙé3ÈI¥ˆĂÛ^ặ‚Gs K†ú‡S¡–#áÓh˜ưœ`@kKºQ´̣ v´,—ËÚ® ~ưPÑQQAÄ`2$.¡Ôd±Áøu~œrçÑâí/ÔØ=¸4t|+'[‹–Heƒªl*\ñ§Ñ±«é>KơL…²èÉAyƠàÖWô•ÅB7å;DưÉ«†µ₫úó½ú+^c#5±ơuĂA:Ô’‰óÇYÔ˜Mûí‹ä|Daª~÷~]‰[Ưư³À›%fă穸üµqỶ¦ ‡ƒ8£“»!£óJ-óôö­‹¸zƠéØÂgë῭.ûX• N>¬’=¾Ü¢‡yÇ9†',5]V¾Ó3̀wŸƠÅ`6Gk í³í~­Së¬âÅl û´₫x¶—x»ñ½‚8§1½›pm1s”#AZÁ_7¼˜GW“Gl]éQE-Y ~#!VvŒÁ:\·.WÀ¯>é.ûÀfPO÷FjÙ½‚´ó×p‡Ó×q¹Î’oÑܧ²|'µ/qœ¬f²™ ‹œ?Ü ÎP=ô¾ô§}̀ƯÏaï4p›™K[ûÛ˜-buƯjưí…~•2É|¨Ø$ †–Åô†<8ÿ²Œ.¾̀WköûPÙi¬Ü}–dS‘ÛƯ›óô¾ÏùB•YÙ\“?;›‹.lxz©N­E_Óqw°F0è g#Ç5Y fœ#ßj­ÏH×Ư&´±¥¸IMϵl¢Îâ±ôª—6RIcÊI͹ê+qÆ …7Ê&{Œ…¢g³ô¸=dï)àd)ÉÏkåè­ØyWËăưè}2ËFtLƠ¼ùăgPŒ”g°MûHùí W¤´Y€ƒMûΗE¸%3́£6”¸§»‰#@Ó<9Ăˆ́è^¯Öz₫ø‰=T‹¥‚²ơ“˜äư“Ë’ÇR Ë3ªn§‚GAëKRZŸ²‹ơăh/ ,^É×ËñYÂöé©?’[éª@ñÅRÇù¸öÄs,#˜̃ô ư’<8äÓƠWÔ„ªp4HŸY錨~à·,‘ Ç»i®́"U{±…†|íå1ï±OIYf¸¤ø&FhHyªï‘¨ßÖÖîöT&̃ª«g•KKÀƠp=óQ\‹c?¥<\¦;MªçÿL«CsÀñ">(SBÀä’4¡Yºˆ«gƒ*Îh›]zHư&`ªB<Ëư²cUoû¡̀ä»0Ƭ‘ D#mjƠ< œ}æ1² ºÂÎ<*pF¶Ô¶ª2#¿̉‘O´‡ »:(÷»¼m¦‹F¸ºq4_n¤q™­2úaoơó®í‚奫ÊƠZN“ŸMªª®w>*ñƠÁícË[Ιzí¤£LtºiÎ¥@TIö@›̣ë8“Xxt$›¼•ÁÀÇ̉́÷™l[Áơ¡hj~«pÙí5b|™Lº¿íÏ7ÁÜøµ´”øky@SJâ¹…F+S¡ÇÖvđ«"*_«{¶²”åLåV‰Ê„úŒÈ'”_aŸYầzR¯°ÛSv ëưÔÓ§§1Iä₫‡üƠö§èŒ×¹ŸÍẃ¸hLÇM7œÓd1T’kx¿!*+;ÜêÈ\ÁÂ;»O’´ ×-)¥@u]÷Z>/˜³@C1Ă;ûÓ|IĂüÖ̃…>Ö ÂvºoBb»¨÷sDT€8£Mûî#övÆUi—ØD€’Û4îGđÆó*³Ôhní3íă[÷û<%HƯ§1›2m˜Ÿ!¶\B'CÔYzgÖ$«?ĂÇ}ñJñsÂßKÔĨ‚¼w¥aê6ăM¤CväáUÈz*^¼‡ †û?I1Óñ~Ëv3aHŸrehÔ*Dæ̉To\Ñvü‡!ư7‘ñE‚<[>5N›ư·ÚtTX˜ßlÇÖ9BBÏ25‹$ü8…[ô_]Fj}:\đzµô_ù¤Êó–dª¿¹'ṛ­ o›88wM²}ó?FóÜIû æ›mÁGº\)̉£{É́>"îi!c*ơÄ́¡#đ–éÈØƒˆW,®hk«ĐäÏg`iùÄiẃ[AƯI8‡¦4¤ÿ´@ù+¸û=Åz³đÖ™ÙqÀd3|M v„C«2úLæ[́ÇĂÍ¡ø̉ƠWíu”² ew8¾×5tNŒ/tÚÙ¾—­-Ổ Ô¾ḥ*ï±4G•>ăßJ3ư"oñ¢ƒÑư@1̉®ûmQà'gÚ>¡©H¡0ùN*äë(¼^OØ÷‹́%¼¨cÍKñF;¬Ơ8>­géùrL'Ă>ä5Ø1§)«Ø•̃ü©¤̉Ëp-(̃ÀéÅdï‚ĂÍ.Åp‘†À¨d¼'~…ꛇWª Ư”ĐÊ•~<ÓQ>§ƯFi#óâS$Ḳê´ÜLôçœdÙq³^z&4JMÏ´ĐÈU5çcJXªbC‰äD±ä0" ÛôƯÏÔIê]RĂ§È†¥́'áÜ0(—"Vt¼Ô8,âÀ7!¿̉’ÉđÚY#›~¸½iQŒÖe…ô₫¶EÉM‰Óâ÷¤#¸Åf³o½ĂĂ}øLÙÅY‚¬ml–)î3¾Ÿ*ĐtW;rlă߸ºô#n’j/¥ƯƠŸdeNgÛ¤C6Ä ¡ø9&7)Шjˆ‡ùe´é² W²û%ơé(µ]1…|D$+'9è×®©x̃ôÔÈÓ2¯ïúW™éÜÍïïÚeQ†¾Á™±GnƠx’êNÁa糑‰đoă|ĂhKÛƒëFẢ¿+BƠ6{›j­Ñ 2đ₫˜„óŒmYÑ¥?H¡@Û0=„!„œ©„r¿¿ñv/J5 AŒD´öl4Ú0qùIí̉sH„&wv‡ùàĂZ›±0B*›Æ‰†9́5₫¾åE˜ ]Q_ƠÍ́₫2?l4îEw*†!̣:¦áŒ´\µ¦­ç,KÓ\ÙdsfZ~¤̃ïÙD̀±3PéTENÎƯå׸•ÂFÇ̃Œk>FI“f†.Y;ÜƠ-áMm7#›•n²ÉëÏÓË€Tç C̃{Jl¯ÖñHGEÔ@!‹æJJ€ôƯ ưMƠ=} æCùƒ›¹k!n–¤²·YsÇÇÏÁ\2₫“+}­¹ À { ñ‚y&dô®¡©«7M÷ÿ₫4PG¬±J½,kJºÁëù‹âÆƯÆ:ÔµÍ{É 2ܾ00Ó¥“s9yQ”à̃¼«<½7åđ} vÔI{6g@̉B¡ÅLHƠêƠµâ«n"/ñËÇ…{û˜À_¤ªjO ³e}«4’ûjë"Z7#ƯđƯŸÜ7~̃?¬íéB/·;D»©'¼Ï܌ܖ^…jp£á̃Gü]ôv“q@"ˆëiZ¾É€[ƒ«óĂƠ,ĐfLEGæULCYàd-Xæ•t,¼üĐ-1fpKa+`§[BóÙ*½û¾k²\›ŸXQê­J¯6^–®±¬¾oNOzh§|·̣ÁËf4¢ Êă‹»ñàgh|"Ö-|bănû~!h–£­µËëw‹ëB¤K9De˜Â‘Q,g›̣ËL:¤±øÓóơ ¹Íb˜Ă³Ä3.…;eÜÔ²3)|Kö.°¾ư<.ơ˜?eî©ø#®ä]^7i+,eŒúüknùa´%éï9Er$ ³?öđ˜ù…åe¾-VÔ]Pá>|dyCeÂO:½pùª±»1±”¤ç’×2V’̣F†1ơuBÉÄËOæ¤$oL„Î,ivógÚÇWo Èd¼âc_âí G™×Q oH¦q›Ư#ß#)´„jˆL²ê –w^)å:JA}[ú‚*¨i) ùo·2 ’¡um ÚË´½ó²då₫ÜHNÂv\r₫® 4U)׌¢á1*.§Ù»¸đ₫ stÔT@¨̃aû̃̉·ÊúöŒƠÙéÇ$5OˆYÇ]ٵȆ̀÷̃—‡Yƒ!?@‘«—œLJ‡'@e¦·í"Ú45@Ï8$(}ôß&q‡ ;üc”ö%$® £ªSnXçÈ]>ºfMiHT@ ơÍy¡<,<. ’1•°QÖr)¦l*a`È1 ¿à.¦È]@°E˜SdcÊó]PgÊ}€£¨LZÆo5›Ñwˆc@2”Vá¬Kë8˜‡+ùM«ë¹gªB·W½ÿxh&bl©dË¥ï8฽GT×2g‘í·u.Ó'¼đ´̉t:ɘ÷&¿2c×̉vÔJ«E:#oÅ©̀bâ÷ưpjç˜ƯºôÁm‘–Å`@t×W@¢d Âè½»¨{ƒªÓÊƠ) ¡‚û+Jí,JϤôĐD̃X¼f›Äêó‚óå1/ ™À(óƠô0a7ư@·¢̉måđ÷Ă,Óî”%‚t ©£B–ÜìV¨c+¡Ç¢%ñGRïbœo¢z—3±Æ ‡2ôH‡%G¹%íwđ_ ­—4-Gbâ Œ·ô›ŒÏl‰ª?½¤pƠ”̉(óz +ERÁ3Hñ¿E#…n/ÿ^đ-Xâ‰+0­‡ỏ`r[75»ú₫½ŒÜÔuÛÚY˜qà­¾ĂqiÇA_,hf‚¶¸ÎrhÅñ±§ Dy¦~ß̣×ô²^ù[“G½#ÏofSÎQlÁ¤œÔÄÏ!!‘  ̣f́=¹`îHƒ˜ŸP÷B0iÄûáAi¼#ºùµŸâƒ{NI~1ç×{‚‚YïÏn×[·p'¼—®#'!.ÓFf>m@đM¸Àmâ7‘g›»5gePzÏ”/hŸ ủđû–æ„?ḿ²Bçbܪ‰'µèĐëKŒeE«äh"²6.?àµO-ơ´Ăík„ÖqM¥̃2ùñD#, á®2ơfÑăµÊITđai ‹ÎØ̉l؃¯&pQI¤•A@~ëɽKƯù¡Ïz—kËC̣Yù¶”„ÆC±rŸ³̃†<ơBç}ƒ—̉”©Åû¬¶¢{"jÆÅpYøêđ7³Í2Áaç8ÔÉeª=­Ôr˜ø3_O‹>X Ñ¢§çyóø>R</Á̀6ÊÙ½¯öR½^}27 vĂh÷ơؘµ‚0+æK«9ÖEÑà=ĂôÉID[̀Ñ«”ç´ÅqmûACéÂåöñ9 .”nË:FQgBmuW‘'™®ªẠ́W`KPø̣ÏÄÉÄfræÈÎW @䩬gú$ôZ<¥±_Áüư|RɃ-سDP¼³â»n‚k:§ :®_9’üú̃øN+‹=Ïz’• œ[¤ü z™Ë¾«ơè[%B <‹<ío`\éV[ÚmÔ鯌)‡œè(®¨ăhÜÑoamœ·&›ü₫è– À–'Âî uè¼¶w7ĂM̉ÀC⿌fÀÈÚ¿̀eJ÷pαÇf`É:Ç!̣üUÈi–á¢`Û|"éD©£n!„ÿ‰K³ˆ§ÊîtƠ“Ư@kƠÅ7¿™åHj®§ÿ¨ĐlrÁ 6ó‹đW˜¸6½ƒ:faáe­Ä*L(Uå¯D>áoJY‰B %"¡X/~G–Ù-°éøË¢ÓD­-„!å“AỦöö›ö=)̀z+*>\:Í]¢Z¼!’€”:ˆ'e··B«H ?Ëç„ÂM¶TF‚êê È3÷xf˜†F„DÛä¢ ;ó&¶*_n}±̀Û,T­\—ô)+÷>Ó&ö”Ë%)+̉!“jÙ“`¾¥üNÏ®& ñÁ₫Éw¯Ø®Ú;NùÛàW§k~ªEwyùÈ `Æi³SÖƠHûûtë™ïUb́ăÎSM«]Wow{ñEÆXیԙ~¨î:R½Đ VÅă Á&”¡)÷ +Ëû‡Ư·5'å&Á1GƠÁ’·‚èœ ÁW¼IZµro´Ÿ–p¦*ƒ ¢ƒ Đsíc¢m‹3́ÚåS „FàÓáyµ,…ç·’́$µ^ÆmÙv:6çwæ̃¥6kG"ÿúI üéÑE’N%l¶yÄÁ–¥oºwă’œ7F:Bá²ĐÚœqĂ3½¹6(èÓ3‚ŸB›ñkpzb¨yY·¸êøÙû¸óöÈ9@~îX+Lfơ@^™7`ÛÊOïYù-̣í9CG[UVt¢ªÊÛ—aâ ÚÔ`¤F?äSCƒ.ÇOk s£ñ!{¼«!ßA1w4J *D:Û-÷ăGëI~n/üÁ Oªü®É=²ïƯơŸ‚uɶéN™ú©×Q«öµ©đ½0>V±ë¹¦EPÔqÅë,åóÁäŒÜu}µÍ`î)œ[y“[Ñ́Ă(¿ï­>¾)+îaW¤³7 ©$A  0å4†˜ïr§̣ ј¸P2̣G’ÛcÔ{ Í»—F¹!z£ ³^-5åt–´!Ë¿3¾å$^€ PÛnÉI/I«1¯^uç| ²Q mjü!̉sÜÏEx¹ö´èn¹:J5áKû<}—œØ:”ÙDCy`±*‘–e§ñ¡Äåû="ÏĐ£7J¥ÉF₫Hb&¯đ8AÉüiE( GºÏbÈØêÅ6ZȰë˯ư± ©× ëỤ́æ""uƯÈü©ä"“O·È‘ F¯ŒM®­}Lô«y'm\¤„LNÓv¾¦!gKÛ‚ÄS|’Ƀ`6·M«QüI«úg›a¦‹ ƯÛ[(°É1*9jV~´Ï<Ÿ¤ËÓǛ¹I¨P[}ûº ÷8nc‹å‰“ÓNTÙÜy±G´’z<¡B©đ-₫̣<…>×p\œ™½ˆÛ¿¬'Bª¬u¥̣fÉ­­ëø×m—Ë€äˆc-w´p­VEd¹ …tË2ÁЉq­2k†¶GªC† ×ͬôJ‰XØ$³.Hå‹̃×íJf4NÍo‚"²á˜¾á ’̣(n¨”ï¢4n––˜r·³°3<æ³/ë>¿L³TRÚB mZ½®?_߉a-"Ô»É@™yÜK`«rúûAØNV‚ß,ÓÉœ‹‰G·½ËIv< j̃A2‰)WÚ̉búǻ§ôg–²Äp2 !Z¼ù.¥¡éŸï±¤p!ÜèLÜ€̃~÷×>o¦4ó#m{‘Ï Ö=È7ÍÀ澓̀çwp§XÓyû»S̀Ÿ˜{Ÿ/IFZå<Ç&Ú v”¥RªŒ1É™”ÚJfj¬AüÀB>2Øv©ĐO˜3ëD \mˆAK÷;–6₫÷0µóÍU·*3<ø–w›–®æ‹ªa‰Ṇ„-´G±G SÏÑ¿"…¤…Âø–· `É(øÊ½̉ơç4Ø>Xbö¨; =ñj/¸ƒióØ#ŒS̉Ɉ°fX>t lÎ#= ¼ªyt\‘²9$Èú®ơ’¡F1ƠÆ,oÜ̉øï¤2̃|Ÿ£#œ.ïë >ûQV¿¼RÇhJ)¹áÔºˆî€æ;́}ö‰!S3o¶2ïDXè¡¡E˜ă»°„—3‚aTêăÎÇ:(fDRÎXîç ̉đjë3½N®˜3+gÏă ư¼ïÅ™ÅÁµ)Ưbz>2ü)æ¥Đă8ö(Ùmíô6₫äËRMư–w&Ûœ#åóÔó±>ăê„#Aÿêûs|ë…ÜÛ3†g[ÛrĂ™A[3v<‡÷ª""»J÷#[eÇ+ ¨‰Á.́^óútP.¦Oè{+]knÉ"²¤v¸ S+hơœ¶×6ơèw÷¿‡ª§ )w ü`e'e'¾0 :è‰̀N9ÑäFÍQÙ`bÈ'›~zs±°3ưvW1₫̀­yµĂÏÚ.B ÿ́Q´?§8¦t¢ÁÓàr“̉̉c$3ñpYnd!-¢¼Ap½«uƯ†ßPøº]5>?û³ÙÚôóNÎ6HécÆT%6_»Mægîx D[›“CƠ îEăTú;Ö̉ØÈ2Ñ‘ xŒ&Ÿw «=*³|ÖÛ‚Eă¾86¾ÎHÎ)±@lÅZ÷̣"¥̃z3ùOc¼ƒí§É̀BZó2—ºO©sjRY™ Y©’P`o‘@p®¿è6ê;/?oGùH/ ²È :~KIƠÅă®ơ;o¸O¶¬^Á¤ f Hÿ åR½¹È¾³<ÍéÆ̀ÓbË øx"ì!<›jk©&ç •{ø®Åul}$™XƯ»ç­æ´µ¥R²±\|ï̉&³:®Áüs(V‹¼E£ixC+…ü´LƯ˜S@.7—œÔ“>a¦ kŸĐƠ¬9ÄV=‹ÂƠƯ×OK±i£mçCÇ̀¥JRvºHAR‘î1¶°»èẩ²|p?ĂÏ>½(ç_ütmë:·aRE«<Ú—dÿi“÷Ü¿ÁG,™´4“,Y ¨5ˆiq$Ôbc†’8_6«¢»MƯF@²–w^¿etF’ÁªÔ••̀˜ßá]Øà(^-q ‚"c¸aê~̣ËÚ±"Y„×äóZ41MûCi Esa¶.QÏ¿‹Á¢₫Áïô>¡Đú³·Iˆ{$!bƯ1¢‚MÈ:̀ơè+o¨'n×lñ› ÷TQ·svĂgN1æ—„~I‡̀ gPơ à„t0 u’ÚZÂÙ”»l₫xˆ̀ßûº¡8}Cå˜?çñ¹ö‰]¢̉ëƠÉl=¦y…·Âåá\pÅÙ_@°Gf˜€ÍïÑ3¨¼vYc4È"„U%E¶úË[Å-tEˆg̉5_¸׸O²‚Rưû€ûêÛđƒç2ËÍX₫Nœ;dÅ ×ụ̀ƒ®°“X}Ü”ú½ñÅ!f?4”ÅJP¼7›ßÜ@a#ڦ³”¿•¶x!¦ÂE(<í&ẹ́¢₫I₫y²cFXD~(“%D)-4{^ÏûîŸR #ô0È¥C‰Üæbs?j©Ë·“]‘é±́sa^G‘°v}̀”K–#UZ$»´mh›Rv‚}˜ßÔ‘6A0Ñ*CÚ¡”o· ¤qP¢n¨ 3‚P5qéL\Hq‰sơ.1NăÎ(„¤Ó[Èß¼Ơ¦haÓ):ÎßËØuç‘’ N‡åöfZ×Öa˹ư¶ílyØS±+ƠÅc³èó2’Jbü©t6ù]̀đ|‡.½¹¼Ïx¯Ê’MJ›?”‘¯ÚWA¨ÍÈîϯu,ŒñŸ@EF-ñ³ éÊ?÷ñd÷»E|ưÜ #MÚƯó7¼3ü¡ÉÇÍ’  §²ˆs7Ô¦E˜ËùSM*=ÜÁ"·¼ÙfŒÊ-̃_…ÙYü@<¢IB„H ]U?gưÏûèâ}§cV̉0™(tL”%́:°fM¥đgư_I'r<ûÎ!‡ñ»°Œ%¿_:Ö3kfSªµñKn¸ºR₫mr’à|á̉ JÚ[Ór—Ă/F^̃lpzÿ ÙËL2\T©̀>§æwog¤Æ–8Is¡øæ™®½ùƯq†âÚ‹¦#vJ‚$ƠÂâ ¼đ¥ç£^‰m ™×± =~$㨤Aä÷C–Ơ²dËa†_m₫ ¹'ï¢}MÑ]@~ßÑÄŸ\o¡úx.œÊ‡ï!f"«'‚®,̀!–L…ÆôQ ûƒ)o!æËÍ^öÂÑ\Dr iÿ$s}x¹‰ ä"̣̀¼Ỹ½m}©Ï§ ộF¼~9j6Zµ̃Ÿ #‚ñ»…w…ˆË×̉î¾%™PüHônÙŒi4¿¨0ÿpVÁ"¹‹Z̉ë~l<\˜Va7F ơ¥mù`é7€N™/àM¸C uj"NåăíÑ#CÀ³ăYP·ßV©Ç/Í•̉ªÆÆ)\Ûø«ƒaK^4\L߯Ú@SâmĐp>‡4-HRi¬KF²³{mƒ•ü„ØÚßR ô¤`ª%•‚1ôơáû®#‰/¹ç¦ÑŒ~ÎËÇ‹ư£+Ằjv̀Ụ̈ɾÉ_¾·'×SX6égDQ“nË^¤ç‰‰A9̃ç"GvµbD1Đç?é=S M40ưÀ+u÷~è¡‘A\| ¤ô™R1½D ”åÉdFy™·÷Î[L朻¶!Ê4& [Œ¨…ÓUÓĐ»7ßĂ²n˜³L.eÅđmùËD¢Œ»JVW®B*ÆÈ¢¯ßØ•Î)ø£ĐâÜƯÊaRijkº¸£Ç*²Œ¹ „fá́w˜LÏ̉{öă¬\øxĆL9¤ñÇiDµ±jl:­ˆË WPrt}V³Q^ªmDѤ3•‚謃f¥|Ă %mÜ„ÇV¾LHŒ̀ôêçÁlg™¸hvó–ÂͽƯYưÄóndÛ—:‘OÔ~ ߬k₫!™@ƠY¶'µ“Ôí́m…àfoÿ7M+Âm­H”đº¸†/c¤XK$c<#²®It[×3káÇ_2̃dµLéh]ưx‰(º‘fH<1#̉(Pg±̣‡ˆßgpüâÂg•>.7>?]se±ai 2Á$‡èªWq¤Ëx6ÜË}ûkQ=0Iœ•K1ÙüU5 Ó „­áFÎYñÚà3),âùN»éKÚDH½ '›+6@çèôÛôECæbÜw˜ÆD3½¨a#†Ù3©U¼Jeb@ÜúY9ÏQç¯Èç'ë2ñÄN! DodhÈÖ¹̉íAÇ›̉™Æ–­9Â;§›;4­e™&_û{0#Ÿî—Ö¼~¥QÄKdc3‚ÂU¹†êºÑ‘|† ÔZ¿Sxbñû1̃xhơ× o5#ùt,›2)ëvh)Eq¹ºà"§?æ’Ê —-–æ;WІ{é[¼±:&ĂÊëçĂ…~₫¢ 9¨¸••Äp?§]¾3a§Ú–X¿]ốîúơàó¹ßº́BL¾ ÁŒ ¾:ä'%L7|ê6íÄÊ=ÓsêUXR0¶P-Ûˆÿ éñ̀”Æ0iÛMAØ`ˆíçq€ç‰Wr­DS2pá®JÂ₫¹áØÖ#3cxMM> ˜Îç³ä¶×s’]ˆöhéˆ)"<æåè ŸY“M+.Ϥ̉@ªbøpY‘dÆïưn`£{&£Ü¼Jă ë ci®ÀÛH}(-W¯ˆµä½Öö«åÙ2–‘B|…·åë0•øûë+3ÅÖ.)ÍD|³ư#J «µ‚[}ÚÆíMËiFï4›î­~±ZíMbWù5jÜàr¡)•²]êÉ£”à*„W̉oÉÇfĂâ$ÓzÜà mQ Gé‰ƠÇ›RNáE§(P¦atU Ä'”Hêé4 h;ªD‡97™{°ï‡ŸX5˸2ó(iÚ}‹÷‚RG+ëBuv’BÀEaF̉¸`’R7:¶#æßHµ•‰dØ+B´|gª@ë̉&?{͸–¥}:¼Ơ ÛƯƠ¶qÇ;ĂÎ?d₫F ªŒ}TZêâÇŸEt¨o¦^[5":ß—0ÿûúäà&Zm̃ª¦Q›ơơ¶¨ØAÊZ“mG,H¿51V=ï µfEĐbđ Í/ 5½>óØL¾©:‡âÉN"$[ÄÍdˆ–t“b/Ñ•Bcßm$Qv(2œ¼ŒOp²É@í.`0•¾j©M“­Îø̉ú R_sđÊF æLƒiWđơ@äơ₫}yk½ñeôµs¾@m®#¨*Ø£Ÿ™ưÎSŒ¯Ù̉§„Ö[‚̉ô9åkΖ‘NĂ•3¢k.”÷gt=³ȹ^Ư®›ĂÇÈI=SöÙ»A–,Ë;æ_ư2ƒB––ùDÁ~ œÏf ×t ú}}ʤ^s uú^ój‰Ñ]‹̀A)úJeàh*⇉°¼» tÂo`6+2ô|Ÿ́>^Rœ¤y ,ÍÚĂ}θ¼éSṆ̃›·ÍÖ>¢¶¡jË«ó(ͧ/ŒW|8Êj>…›eÚ́ư¾ TG´X|Ǽжôă£&²!©ô“©AơGO2I¨siTM–Nă²µ»J£ñ2’¨â±³L’ëÖŒ–%¯™NÓ|’ñÍ3Í¥V±O‹\Jeđ‰@4‰rVn¢l>øŸ`ZóÖç dv?–MkVur »Ơ2Ͳ´ÊÁiå}¼1FY—¯P1̀Vzư[Hæ+ÿ‚¿²ƒ÷iôux]º6̃Âç̀›ÿë†aƠŒ…ẠcØk$”«ç1~{±™íeă«ĐÜ^Z„!¶m®É8ûOư."ê àß±5WàÓô@ñ5™‹Œgºct@ƒfÚĂ[ó¤¥L̉]Æ@?₫ñ9<Ú¨ˆ¹xçƯ‰‡­ë™)Z¦Íf‹‚Æn·;ḥΙ ÓV‹MIh:Ve]ÅÜÛÛí¤D_“½y^ù$Đ­Ë>Z4‹¾Sơnsü%2¤ÄLÜØt8‘‹"ÇúI[G­¦ÚbèÖ‘f{øđĐ1ÄđР]DZ®º… Ảèf›6FÍavjµ€¤Ú®¡B?2½¦é úơ³ gTMç ‰ëRbA /·Ă0Ư©G<Ô8Œ³†aúëE]SƯ*³à<̉ËÍŒ_—ă:9;å%'¨­-·ĐÍÑ̀?5ÉÅ/kÓ?ÔÆ8·†ăb˜BN¢;î¤Wp­³d7¤!œÈH“NÚ<ªÓ Ú„Ó\Λc]lª¯‰ ̀ú¦̣#Ÿg¿"«pg·Áá„ú¥à¡Ïy¶,˜½.g½¹̃ÚéV.À_àæCÀÍ}Zƒ·3&‚ÿœ׿=ª€>ˆµ̉Ås¼¥?=Àù(`!RŸúÖ@sÖâ°Ÿư­I+»ƯÚ•kdÇB|®±[ ´oXaÑ[kbá.o{VÄ|­3Ójơ†8¤Ư¡l|–Tï ¹ưc <6Ÿ|c¥¦ûNñÉ;€høQ$+åẽ;®Séù†([D &„M‰y•€më§gÎ;dj„§ˆ…<¼̣GƯ/…j¢G¾Ú̀›‚’˜’¦€GVîƯoœ½ ›¹feˆNCj!¼vyk÷é́.r¿ĐÑ^è[ÛµÑ~Ü3wV—qQ‹B•ëLE5Ỡ½‹‹ù\÷EänÔ±:̣=ˆĐ¤ÚÈ̀¬M{>¥uÏjÿZÁTi5hƯæ–,ƒ<~Y:ª)ïûơOµ!Á? <\4Ưü! —Á£&ó¤orbJG’#:­£2 ï¸29D±.°ÇU@=G·¸Ó#ej•ØAǘC_4u‘¶Q#‰dJi-mH7.Û̉äö§·1\^ƒ'{=ÅG¤sĂƒëœ”lgl‹`Ăeấ  7.̉!Y dîZmT(´g—#ms™V•Éçªgd·?}ơ<êâă± ’( ^Z]sÊsejÊ€·;BÀÓVŒ¬G·IepØÆ!‚‰"’,ÿq·É¥t;S!·ªóÖ­₫†º†©i²?7 9̉¹%B)7ÇÈ_‡ÉeFzË₫̃æAEÏö¢.ŒŒxÔ‰ô”ÊN@%DÈ/IuÀÔJÔ”4̀»ù_UCC¢ b4zÄ#—UÈ0¶DVˆœđÆ’ÖRXN5ÊaNÅ¢BL-jÛ #Ä1"ÔØyX¢̉©¦Ü…£™Óô4²¬k⣠V(ảPÓÅ';óíƯ$4_ÁW¿i{º:ö×uç¾ÍÄø‡~]èû4_››%÷YY|D²czÛ«UU´`JŸÜ5yÊê…¹s›+Í&àĂåV “-¨´ÖZ|K¾‘Üͯ­÷¦ˆ†‹2dDH9“Á:@DjJơ.™Åçab›zß®ËI¢Xä]Eyæ¨ rȾE”á³ÄâïöĐˆü8“ª€ó‘́‡()»ºđyœ^’ô¾gWóÂÜyÁÎ́ç(e‚nÜpko¡¯ÛƯa× ©ăß`ßơoÓOwÜ^¶Úµ5˜+pBtbK•>øµ u»8\2ƒÜ…hâJ_eÚ+ªhaá“n=ÏÇ?:ôQ›n<àH̀ÊÛá‡DGÙÉÄ‘£9 Æ¼}¯W ˜ä®£́wZ´P*³8•&¶OÖTópóṾ!¤¢Œ,í-•{‹ºHøD̉QFîSè₫ó4̉k‘çWªĐK°:ƠÙw~oĂÅ{ĐO¥t¼>¹î̀¼=ï_;­*_ƒDWµ̣‰M¹M£ÉE*75X̃àNƠ?Đ˜q’Úrr>¤+R‘¯Ss±¿¨€¬ß?›ŒÎ‡̣‰}Ñ©¢ưbĂ$¼~Ë©çúi6~D;¯*§³Ë'½Xx³É¡iƯKÿƯØäŸ#¤-ø‹ñîà— ̉+$Ú×ÎFÁ2B9µ©ñªmˬt„ºÑ½oçŒRT²©ö"äî$kéüZC+¨Ÿ·³¿!(©ä'=&ïyƠ"=û»`Vê~Vàơ*I+ỵFT,¥£¨ÇŹm0Yá®´V$•îưÔ‹ª€EQzŸÈpÎ×eë›M¶Å¨ÅêKc¥`sPFB$ x̃?,½×|Ï‘û€‘[z IU*¼ơ\˜àÜ[~-ư¡́²²Ttnf8ÑË Çî£Û××ñÀŒúU«Ï°ZÑ×7M7c̀ÜXÏ­>w”„'ÿo¿"ƠÉöz~ÉV<;đŸ@UËD0–Ú©ûƠxPÛJe >¤høëû€„‹Ó$¤Ê¶/0&º®/¤qư8¹Å?XO¥±ªñŸß )öÙÙƯs¢˜v\lj†k6.¾o½L3«¥ ¯«í~ódÖ††Â¡˜Ó¿)ÆÓȉ\rÇ뜖¸>=đBí6đF\’?¦¼ÀtđYĂÚ„^ڹל?—t îhMî{Ë=ÂÚ ¯xw|—",…)₫DG÷戡~?…©ƒùàqÚ†‡€ÙoL®Ç"›äÜ'¢Ú‘%›+̣:†¹IĂƠÓë°™*t”F‘²¹¡$tƒ-ƒXi•±?Î+Ë*ÆâÛwŒMî„íÛ.¹ÉV¶¦P¹Ñ=wh¬>{º?Â\*Ă.}A-{SÍæŸöƒrC:÷ùÓ1£ưºw̃´KBÅ¢³3_ÈH§ƯüQ/ºÍá[ ·®/M3î! 2œ't¼<^3ͬ·•đÄ©Ê öBY3!ª6%æEwÊZßƠuërè¨~;§#ăka₫y!ÇgqXHê·d§™ÑVí!]Ư6®LqÙètÏTØâ¤=΄Sê»ÿVe[b#ç¬;áaơ_íwbÜ ÄRTrXÙXM¾,"%ÓöE¥»¥µC=ưÖK—Á#8²½”‡w¹¨ƯfO6âáè̉thÈwB™ÁÁÎ"#=‡tă\ỷ•vR«r¨OäsæTI‘»8%\¿Óè®#1®³{ØJ!pâ_O~ ˆMºFc¸“ë‹n:JX³.aǸX6»Ë´÷GđmEƒ1ÂcÍtẠ̊Ûªvà '“|öÑ®fÓ“†qcô܇ça£/5Ïơ¤U¹öZ”ª8„yh,uj+Èi={Óá± R(n]móˆÓ7Çvh—5“i Üpá;”ˆâ}ÀºØAèÙûu¹iĐ̃¼³« âY:f¥y·]°Ñ́¾sf)œ~ËDJ€)2|:Ït ₫ÆVxÎ,÷>=Hä¿s4f%ÍW|ƠøÂ;]åÂ…&ÿY~ɦ´Œá­ö¥ÂW:ræ;¤&– ă~Ù'ÆnÔP66ÇZ¿öD®Q#ç B²X‡v.O]ñùG§ iÈ̃ [V¹"%¯„Í–æc;ëX~?zuÔôµ-^ÉuØî„Ûo=f.jÍ ]d?Wæïæ¡¡‰!Mă+dª?24´¯ç*̣̃Pm@! ¹Îj•Ă¹Ÿu^SƠ~•›‡° »é !FX¸XsIç‚bw¡CBdĐlCv£ïç]¾xE0¤Ám»5»íN=/Ëw3Ǵ“¿–´Ja…EuylôªsüEMè`Êß ; Å¬Ùm<à,eˆ‡W~)u»²—º.…€Ø¾Ä¼2R~„:Ă/e÷ú,<@êDô‡{FmsÉoÍŒMA…[=,âï|f¯tƒjÖv»œæ=QƠ Kxs! Ù^̉Ñèñ}¦O-í$éÔđ#^i;Á7¶˜°;&r½ 0!"o£©ÛüS±{½à̀Û¯Å-â3sé9Ÿ’^\Û£̉̃(­ađÂƯĐ»Ô~%¶U œö/l\:½ÄÅ`¿₫€ZOh;)ï|¤$†¥´̀™…̀ŒX2C‡[Éïˆ6Ḷyå6\̀ºŒégùÎăà~8́L!áƠơÚö‰[ˆ'RƠy×ưn0“£Lz»j&Ê˱̉ôD4zÁă˜1wIQ´?¿œºị̂ÚE¸(üè×Ă¼'CE f½V$Ù*ºf£«å"_1€¬b @ˆÈù‡_ùYỀÆ’p?sÏ _Öº·$Au‘ Œùfb~m¯ƒ& Á £ø”̃‚©E†Úk'&đ[™Ó)}ƒUF ¶°!1́WjË &¬‘K•Ê”WÏ£dQÖXÙDVÔ.Ny? 0·í- w µG·P9^T;ñ°‚̉*'´3†L}ÏוpjăÅ×yjg2Y)C[̀Î}B,BjeøøÂÖ<¬và͆ƒO‚g_®´mÏ)T‚­²̃<@SQÂoà¬ăĐ« [>g÷Ë5̣ëơßuET ¿ Ơ9dmá «;o»'¨olw5ºà̉c¬̃¢wđ:A·ÔHWX}¸C §h3Ëâ˜i&[̀`µ…5ỏxÍ’‰kªX«EÓ!ßIU!Gô₫¡ađÍÅ í­{́ˆ£ÇÊ÷.Å\iº*âÑ»ưà¶Éëï¦ä”àKUœ»éi 3Ư¸˜)Tú¥+̉Hơ²g"äMÑüÇùø$®Å(±¦Ư=Óhư¼kß-×Ö}üä“»¼ ¸+F×Úm§XƯ±ßc"oê·f³½™R2}ÎG6¸‡°‹’acÔƯt*U”t"nlæj ®†àMcµU>íh^$?I}ëjëkójĵÄX°–åèˆç/^ưACΩ–Ưf¡0B'₫åÏ_vŒ><9Í 7ù/ä·÷.̃¥̉.áñåè/¥9ª=4{~ùÑ?˜è>ј"GwÚï9–ÜÇd aM…݃Ó‹% ơ‰±:ï– Fdœ3Æ™‡ËƯdoá3Q/_BEûC €jáy~»¶ .¤aơĐ ¥0´.ađ]nØ€øñvé…4Ä(ëÇ̣·ÿµP7º₫èCÜ ă†z»̉Áë4 ç4–·Đå–QŒáÓ»—âÇ8"„C£Rÿ.ˆơaG¹bè?É~"¬xéơ³÷*păÁøwÙ`œƠ₫(ꀨ>™Y_ư¤z…/‚]½3µ^É郞‘#Ós"(Q*ܰU^…Êb‹̀´ØÜàWYr¨I ƒơ³PäçùH²j‚¿¥Ỹ„v®²ă£tm(»JH"ă&I¸PgP6Á \'̃Íè‰sÄ4.Ă–%{”<.Ơ¤•t(,\'mí6äÅ,n1‘Yœ~˜ÛƯ£ ¶›:Èq­v5:ɺg̃¢‘Dç̉¾Œ3ÅD;jR­âg8+l ^ô<&O[̣˜¡Ë䲕´-C\ÖëNN‘xt<²Vi$Xê;î‹o¸‘µàiƠK}P‚›Zî¶Ôv-äëUŒ²Ä¬¹Á}UW‹ü¹øæa4‚NO;Kïî!ïܪ¬x̃«™Ff!ÄaBv¢z–Tă$úă6À”#~̀:êW·đTfuc²ÿ'E ºö7mb[agL7»q̣Ùäún£‘eØn®†Zø©KƯ5Ơ¥(RJ¤#‰j²:À~`©ÖøÍ•ó<æ›È{W/đoÍ”~ƒ€™ă2ƯÔÚW‘˜‹)?¾i­,ûC5¡wÔ\z B’@36ă,Î+£³=‰ốK~ Á;•¯,x:3}~8¦@@Ÿ>ûF1'ó¿­“&æºf&@¾û}¿ÄF›eÊ(g^ô^b9f²q%̣2R B(dđsàäÄOj@Mj̣ä#X+³ŒựPp ûû[ü·‹ul=Â$—<<\4牥Á Áu|·5n¡Ü‚¶7 K̉ăg₫Pœ¯Q¾¦₫-œ·9̉§cQºLˆF ?̃s‚…p%÷k ­`]íäí)ù¨ŒưÉ¢>ƒ¿e<2́7…ä–¼l&1¥ê–5bĐNBT²ô|¤ºƯ’Kj„»ßR&©…́á1–x>ë’̃„-ö7²NtÓº9ÄX@ é™1cC:7kù'̣¾yC£[rx~fH́›#bf9S₫ôe»º8†X´¼Smé¥ Æ83̉Öz”p۪ʫEÅ&× _/êƯ=ĐÙ.̉J=MºB‹3„ Cµ̃¯̉UÿđQ‰o´â¾>ÖJÓ’‹^ù´¿Lçïs‹/ÊÓ:/Ăí–Ϥ®Û^2º"‡öu´-Ăó ŸNÎl£5FÎ0ü)̀¥á₫Oê|¼x…§₫Úáä‰₫¯å˜âEưHÿ³=RöéÖ¬U’¸]G\¦n°̃±ÖË­+¸,­ hN·º,©x̉2àî^iÚQЬđ oơºqs6^¹‹#üê P U‚@"zϤœ Ö ª!6êy±L»ôhÊ»ă ßúá ư1 SekGJ ×.èÏ‘3Ø-á¦sDè»ä@M)́v“±G·ˆ@~«dBbpËv1A»©kÏm-i<ß."§c₫ù™‚Ö¡|™Ơö1$œt#ê„­sû¡ß¹-Ïđ»Ô¡¤êÎ*:‘ô¸ÈؼP2èĂ¾1fê ̃Ö•°ÊïY?åưQ·ø©ûă ¿ €:µ71_?™yË÷5vË“ák?¼ñ[ʶ¯á.Ná…Z̉Øjzø̉¦Ø½¢EÜ_Ư4F!‹k[o§̃Øùà.æî@àDYŸ́§jú9i½àÖmyËE4 Ü½ơÙI½¬“‰I2€@F-p–'ßy  Oô$ÊŸgŒêmÛañ&­ón₫ˆé¼¿ß:ªñ› ÎO ­¢…ÇÔ†ºtCè/Ûö/ó«Å^XZh”øí¸_ô»&Ysyü¹[y₫ë½™i[ÁM¬œØ§§pÊ4c±·ÇNįñ#|γr‰²íɃʧq§.®Zà«ÈËŒLj@âØĐ Ä-¹Ê}pwÍ3F̣$¡%·Ñơœj•7¹ư¿gĂ><,$½³uHë&¯£ró[d"Œÿß§ç»Åài§ĂœßªƒÊlÓ›è@ñd~BáV{}£¡ó>¾ºêuS~ *)©°‡í4$ÔưPÍ»éÖÁ+ÓU\Iăv6Søb¥Ö8›•J‰Äy_èfeŒ“½l?ư¿ ¶›W8ï©0Ç©aàªm‹Ú=›ç8á:¿»¢IÖlÂ!m²záÑ Ôöâđ…°k₫:pû̃\.8(?aI6Nb+¡QTWĂu¡ôÍÛç ÛIûÈ`}ùV*ơi3;Üè´?µÑ¢éî“aÔ_ˆ( Ư€ù׺R£¼‰®lê³Vïl H7â¨NÍÖ~ô©›J;ç­³“Ç®=ÈƠo³JÛ­MKäÅƠà³Nê°§³‘N wú¢Đ+<ócÀÍ”g.aÿ«Ü²¿`Q1k¤x¿Ư ?e*­ ̉4[Á¼ïƯ•°ØñÜ8Ó®éóđr™HY:r“_œ"1¸/aŸ+HÚ×́ ZLj’Ơ¼§LDµ"I<̃Oug¾k´ă«˜ûº›Ê>®ˆfúâ*Ûˆe^²‚néHŒØzs ̀ ßÎ̀¢™+IÆ&¸w¦(R/”Eäñ̃ƒº…Iÿæëªj%ÉưB7oû 0?±ÚVÍLˆö¢4ơ#ÛP fªå3™C’zg^£ ÑE%0Đ)Jw]ÜÀ¾?›ë~'œl¨~•ăRÖÉ%© +“.@u¿(ăl… 6NhåéơÀµ4)íâ‚C'·î)¤8ÀME‰(‰P£^–·ÆWüwW“?ÇAyLz7ŸbƠvNêœF»£Üc iÚT‡¡I"¸À¦`À=̃SL ¿Ëbæ¤$<¨{P s=¤RƯ-QP :M`BèÚ?„qäĐê%ơÓ₫¤À%µt¾H†ƯèØt3êÂÉE½ú¬Ah9<̉U~q.‹`/vưùц´+ÄĂMßXÅtÿç†Añ?ê3úaeÛ«€+³q©¡;T0°}èxÑG·Øz2.c‡ó̉+¾a³—¯–lû…|üËbß“{Gê¿y-b)Wñé¡̣b>̉8 yz 8 Aơă1X“Z­ rÀÖäùâ[-̉ơ0Öùó½À{‡hí‰×QIQ™6±µ‚X¢́Ăùùô~¸_Nʃy÷÷¿a³°×ùê÷¢V>jÿ1M†öÆ÷àHÁm4_ íe“>Lj1Û£:(ù{0¸˜ó!8U(|́ô₫b¥I–J}{zœºöeáBÿ̃(olñ Ä™=ƒ)R×Tù«r¸é®öƒZp °+ëg+pƠñ³̃®aÈ^­¸ HIl o¤€5O,h×:÷D†H§î̃₫l…†˜“9SʺY›äG)ïà™ï@ûưƯZûܜȮ”Y”pˆ©ˆúóè—?T7> stream xÚ»TÚ¨»»”´¸»»»»Ü»ww·¢Å—;Å)N±ẫ—#÷ôÜûÿk½·X ̣́Ù3{f'@C¡¦É,nåd”q»3³³° $•µ´øllœ,ll(44Z wàßb «È ,đ/IW ¹;D&eî±Sv<́œvv^66ÿ \Ræ +€2 @Á tC¡‘tröqÙØºCÂüç!€Î’ÀÎÏÏËô§;@Üè ²4”ÍƯmˆ–æM'KĐƯç¿– ²uww`eợ̣b1wtcqrµ¡gxÜm@7 «'Đ đGÂsGà_™± Đ´lAnÉ5¬Ư½̀]ˆÀd »A<<ÀV@W$8@S^  ê ÿe¬ô—àïÚØYØÿYîoï?ÿt6·´trt6û€À6k *£ÄâîíÎ0[ưahîàæñ7÷49˜[@ ₫ܹ9@F\`IđïôÜ,]AÎîn,n ‡?RdưcH•¥ÁV’N@°»Êû“¹-!e÷aưëdíÁN^`ß¿Á¶²₫# +gVm0ÈÅ(/ơ· D„̣[ftp³±±ñq²€. ·¥-ëËkù8ÿT₫)†dàïë́ä °†$ôY!?P|Ừ=wW ¿ï¿ÿM(́́+¥;Àh£ü^"ZÿÅĂwy Ù ½Ç`ûăëŸGÆö²r;øü6ÿó|Y¥Ơe$euÿÊø„„“7À—™À̀ÁÉ àæâđđóüÿ{5sĐß›`ûí)¶vđÿµWH‘₫³_Ï¿ŸîïÑ ü÷Z*Nè~·¸7›%äûÿs£ÿẹ́ÿ×̣߬kñÿƯŒ‡ƒĂŸjº?ơÿµ¹#ÈÁçoHËz¸CÚ_Ù 2àÿ5Ơ₫5²Ê@+‡ăÿjåƯÍ!c ¶qø§Œ 77ĐJ äniûgcü%Ö₫cÄ@` “è;À̀ÎÆö?:È\YÚCî 7H?₫©BÆæ¿#Jƒ-¬₫˜/n€¹««¹ ¤8¸¹¾́A´zÿÙÁV°“;ÄÉÎ`íạ̈Ç̣pXÅÿưE<V‰ßÄ `•üMüöú‡xÙ¬2¿‰À*û›8¬r¿‰À*ÿ› ”~$‚̣oâ°ªü&H<ƠˆOí7A"hü&HÍßÄ`ƠúMü´$îo‚DĐÿ‡ø!:óßÙ‹Åo‚XZ₫CÜ¥“äÈ₫#áâúCâèøÛÿ³dµúB*üB°₫B2°ùB–³ưBrư !á₫…½9₫FvH\đ¿×é_‰ëü{Û[gÈƯvZ»ÿ–²ÿ-ưkrÿCNÎ2¯N¿³â‡ˆ\<œÜÿåÏÉÿ·ô¿ưÙÙ!Y¹₫ !Y¹ư®)ÄÉ èúŸºBÎÄÍÁÜí_Å`‡Äü½(ä>au·u₫«´́!¤ZÿBH¯ßÈñ÷ùÿkª,=\!ù»ÿyíAFî?üçSè ´Dù¶àd)f×öñ®AœÔ‹ywBx–fW7“Ù÷›k·ÇbưûÜ ×ñ´‘¬Ơmiºk±ẹgß-ˆ‘)ê]~O¦IÓ»](KSŸ'Kˆ7‘!¿bÖÛó{vñÓ ¶‡í€îU )tñàĂP+ƽóú$ëƯbjb"2Økœ±iZ_‰ƒtÂEßỆØ áÅ|6z¨%pñ¹„•É k³́"cÀE¹Å4o3@åÖ!ôÅ Ê æ:s‹Æ‰»íœS¥ưq| N­Ñ’ÿT›)UÿGc>¼RSïÍ~ăWFUñ~+¡µ<—“£ Q¾í†w© ăS«^íj} SSÊc]¹üO3è²rñ3–QÜ₫p'Ó!ÀLHU^–ñ·ă*1· XgÁ•Å Á̃û^ƧÍS€e¥rN ½6€Á±,¿&©˜‹‘؉º†\»%TÚ2U¡îÉV%éÿ+¢Km—vÉ,ÿäƯÍrU¦ñz†¦?«yFEW)AÍ!åđ ù Ÿ´ºH–`.ɇYÄüƠƯ›nC₫Q̉2ÊR{Ów³ÔPÓ³„ó™Ó6C—Hh#ñ̃•³:ʶÇsJÔœj0™+'x3ß|º0¸skñ˜z(§xßDíw2 œH—† Á5@ÿ=¬°́úY=nÁçJm&Ó·ƒ´^ÁÚ˜÷àzsụ1|ínÀ8(E@âúvW̃ˆ: Cx.©¸å(h2*´­8>“àÛ(̃Ưpîp/ÅÎQzS£z_‹&œ©̉„Ï̃W†n * A+<Ÿ~tO–NïZƯƠ ÂÉưËhEĂ™Ăº»«:”ĐƠŸèMZ¹̀¶ví™sp}ÉH MGc–C³Å̃¤÷S6¯í‰àسMJ ̉'*[hc99mbrîy9rÜÂơÅ;KÄæÊÁcD $¸ÔÊ`l†D{­™AËK O2L+L±ÔxÈXÂqc/đ‘ë7.°°cÙ)»Å v”ê¿5›Đ0™ó!—TçḄé_ÆØEûđ…Ö—Ø#á\ƯFe¸̀Ó¡I­è¬½ª¡x¬¿å+pÿ“°¬ƒ·±gi'v B íC/¶¿uÛ2Hư£sËÀĐú´¢£úœ+‰À.qTvÅh¼OGÊ£YÀípŸ,².+́‹ïbÄ yovµº£»Â§`¦|-ƒ]sYÏ-c̃Z{Œù\·¯F$b6U|¶]ȸÜ$•Ô¶ÏÖ‰˜Óe¼MKgư–‚ê¹<ÜsÍÀăă”Á¥Î ¶ôHÁƒWƯƯ3óô+(±®@„mÀ! Á‡o ÀΣ¹ÆS»hàâWĂÖ>̃Ÿ„7̀&vÉĐÅß Ïđ–‰QHl¢ăøßaEsÖ¡- †&”ªê'I¾F¶¤Akl_ÊZñy¯ )\ơ₫(ơ„{ÆĐà™••úµJ$Dgoˆ³̉1ëW=?aÈy°®syă¶ĂBB?x1’œÓ¦°’÷³ÀWơ`¢~±Vµ€æc±ÙF©3#R7ͪdÁoA”P…úÚIôú7Î Đ(>¢c/ &’#×8÷̣è¨ådơ ƯgÍHĐĂ0V•ríh­ks'`½¿k"ä .Ǻ¯­öTâ±½ ç;6́ *OË‹8$[)Q?¯7't]U˧™|ÅWơëơ`1ù>­‚½ïqI’ëeav<ÍßÉ-̉Tz·d¥ ÖđéœíäêR/±ü|„̀ù¦ÎpÂưrm÷5üˆÇ¹ ÍRù…Ù›k6­À"48y_ḍp;á"â˜1¯˜%ä‘î²̃åh¤®Ñ!̃â»á̀ç„É•cÜ¡ûe߇r¼*̀ë‚ÎHQ¹–Yôû| ªơÖ¥Åz`¦˜æ×™£èjÙ0Ư ĐË̉ˆ±-Fډģ·/I&7Ù—ZëW̉=Qëơ=R¤î›ûoøÁ£>Eᯇ>r¶Ư‘w¸b£à^¾âc2:/R‹yÓ>û½>ûTÉ%À…s«À[)²™-Tœ35Pƒ'Ù8¢¶7Üïïñö`À/ïÖfÚ•™ [€¤đÀcú²ˆøjÓpPêÀH ¤w½jæE2Ë–đ:zD̃Öx¦AÅØg›àDZ²ƠöôË‹–H‚ ¥Ç™20¦l•j^VẠ́ Y&ïæµ~¾Sœ?R¯xfùîắVâ(ư„géá;K « ¨ÎưËû&S¬œ'?\ĂÚïx7sệ̀–øÔnïÓ7á4Îâ«°RFÇY=\t åeßÈOjVaê0g2KÆØj}ñ–Á@I{åNư#¤´ẉà4OăT9Ÿd‘ƒs/'xƯ!®Á¤Ä¾^éA ¦U‰œnyRipí×ëá˜Û|MW»G¬´Ÿ¨Ï¾°¿|  ¿m:©éoÙåb†D@ øø&ÜvAUµS]ÉYTϲ­jmk+¡&\†ÊéF'íÁØĐ×uQIû>—8–’,®¿ưƯ•¼CU¹‘{ËơW E¤lÍøÖT7“Óí ÁIq¶ŒXºûu[¶̃k)ÊûY ăÂpègjZtœÍEÏn}ÿ`œÂF íGy"M߬̃e៰U3Ljh29öaëoPÊ÷ƒ‘°,”Ÿ†¯vÜ NT‰̃2sjßQc<₫#Tc»&Ïû]ízưγª7u•÷¦ÅÎ4pˆg OÆ&ö€!"‹^xΙ&O£—Đ„„ {́ˆú}p̃Ă5ÇØ»P1ơà$(B\Ïiÿ9î·œ›KÙ¬Ÿ¯+ß7×·˜bF_ôNÉZŸCÊW'¥p¥†0•Ơ½;.ç~¼£)Zî0̃‘Γ‹±¬y¿û¬ñªåâ¡@‰•üM€‰%·mû'₫v²»",ñ}d$©ùŒ¬ÿn8ÑÁ¦kSJÀ-=Z±uüù{ÖRR¡gO¡‹E5\¿bñá'Yû̉1TD5ưºÏÓ³¯U+»º%4r_Ñ×U9Ơê5 k¾́ } É4RÍëñ–-Jñ ™Æˆ'4ØF0É·̃óÚ¾fˆôtj'`)œ&Øđ–ăw₫~æî„ƯÈOqB°ßÙ=“ÅÖ}±¥gjk†G1ÑѲñûY³¥yE1HÍZçy´Èæà3G¢X‹ J8’‹e€»±1ṃ9—ÜôơØzßÈ=UbZ€¡¹)áĂÈ3ơ½>ÑŸLٸܟ†~̃Î9d°y¥ÿBáTtAÑú~¿:‡S76hT =ûñíY|²Ă«êHc‹28çg›¼Ur^Y$Rún÷ï †›:ÑÓ*E=K/_TMÊ#3÷cçĐÉ`<Íbj<ͦ#1Q†¢ô mÛ+Ÿ3D\ {Bù¤́W*’ǛԖ{Kw4hјcx×ÔäåLZEÊ1“’ªkO:EÀá´»/0¼[%Ái¦ a¾̃¹èiËÔÇT ö¯‘Ơ¹¨>èƒLüÔó‹”&£,{i‰§äÀÉô«HÈ“•_ï‡ưlDƒDkè}₫?1räï:•'¯¿¤éΟ3`22Ô₫Ø`²Z¯ö±.ªtôœË1vG~„##5[ÆvjY"6NÑ•«Åi8ÙÔ‡]ó'|£¦bÖ©é!aM@Í”w6Ÿ6«t3·sÙ&üà…éØ̀æHªƒ„5·‹œîœ…¥¥ v'.áYT¦Ô Ư~ụ́qW*̃í«£¿(Ù§ülÓ́„=G°œÙ¶x¸ø"¶ăLv'1ÊÂj]ỵYq:ÔÁ©5xL{i%+vP2?§Ă¼Ä½5vuÿÓ^7Ô…çÊêâÆ²Ë+ij5Óoá!V÷í7”˜ZP’†€—^¿ÊnŒr¯™`v?^œ« Ù_¬CÈKuëâ(­ú¶xÔåÍ»og̣"0†¤Y¶„z4ó@¹÷ư¸óYô¸óŒ­ù¨c4SCpúf‚È 1ơÜ‘NJ]*ó¯“olƠlw¤Î—?h$e1÷„Ơwh^î½ ÛïE¾(ß/Ơä{„#¡¨Î`ú:I€Vă9©BøªÉö#Àl„RÑ|/y€{|€*ØÊ«ñP—Fß!º'€€P€µ%D¤̃ R8'Óï«BUè;sâÿU”×çÎ7Ó–X³-¼mÓ̀Ư œ˜à@]’VÑ ÁĂáëœB[¶Ï" hÚ5JzAFÏÆf¢gƒÖóë°œ©|M9}ó—5% ¢-†øF̉6xơ›½÷PÙ:LSÉ”Ơ4¦‰Ud‰Ja¥”\«eߪ<ƒ» ¾\SÀ£́Î>nè‹Ư)ÅDăùynt&1#¾›PaĐ'Hetß!²(Ño¿i‰!K&uôÙ`'¾ŒT́Ăk×Y¸]€£!ñŒ´«Ưlûex˜¹̃@nö ¼Ck 0ænö9Èës7Á4¬¨A½cˆ¤v`DËĂúS̉BB CPŸ%œ ‰pEơíGV¨¯̉ÁT?6Ă]¨5çI‘IµúÏ h¬,.ẩă¨¯÷x̉0Ö• «KOVO‘½Y—óÀ!ªV>ËÎlSo!I'_‘ªwíó¹ ©HñdÚ¼WI«ôOàKïöHñ/1GBÚÑo×ûaùBQ”F~áÎß‹½́ÑMC©6Øéå Ï'±C¤Đ€«}¿[ă˜]Ê™{ϧ=dr̉[â\50.—„¬ŒNÎ|äÚØ\Nç´ÖÜi{Öè.ZíFĐyÛ5à-×ȯă;¥ñ?rZ i…Ă6ĂœÅÄu“`vT ƠzêMí•·^‰̃`¥Ï̉¿æÍ™²s‡¢¾ç4?S₫x̀ĂƯ_ü¡¿¨u¢*¢¤+¬£™›î+™Ï¢ëuđy»H,±æÊÜw*ƠU< ñŒÄiH ç§®ùyP¶đÀ¥¥É|À|&WØûJ0–Ö–V¦©bb™àÖ¼¥/øyHnO{Ë̀¿5Ûœc€Å¼[‰à¥&¨XSÚ]ư0-?•¦{Åüâ¾­̃ŸgîƒÙÈjAb‘Úhđ9 ]PĐ” –©?ö½Q×Y¥Ư`Ú++m¤ù耦®ÂJw»“ÙJˆ„B¬́Xj×"*#ĐA¿o‡¦}b¹ca…Ów¤·0ä×O”‘‘+)/9ÂöÄU-ÜÍ,y$­ÚjxĐ4w˜?²ÉÁËâæoywYxGøß_éw ´ósÖk¡̀Y³†éÊ}ùiz4zç4Lư1¯Q4̉”Ëû:—ç$;³&ˆĐC_Œ®æ¬R¾Ư¤duøƯimI*uưAÖœ6đ×eƒø¥t÷Mo Û;O ¦¤J 5Ỵ̈L®ºNå«yåưÂÉæ³Î1Z”ă¼iA4€½÷BÇô^xP ưèv"ƯkQd̃øiÖŒc(9̉¸•_xĐE4´OlẮˆaâe{߸/ÍŒq²[…f VJx̃¿[âi”WZ—Á›Ã_DÈÚÄÖ‹r%~Ư@`åjûœÙ® @ơÁé‡Ù{c›ïœ‚Đ`„Æ \•ǴÆ*¥R¦ÂơÚ rUƯ­¯&áj†Ëtđú©å Ï”5Mp´ÈƯ«ĂëWE’ˆï|ÉƯzk9f(#_ª|̃dj̃¾y8ă&ÈÜñøv?â~90'rÜeơ0TOwºVåR¸ü³!Óf„‹¿Ơú–%'>g’‡̀böɶ»ô¬ÂÙëè™!N¤çiçÊøÉn~̣¸Êƒàû0^¶>¼k…óC± ̀g:»×ë£2Óº̃ê½§ÏöaŸËÜ=^7S*–Ç ¿ï©D®†5l̀˜³Í¦ä3ö,é^',.EÑôiE½Ñ„Ÿ¿‘:(+b¾3ˆ=KIÛ}4ÁÎe¹7\¶øñæ*™™]ĐÈ́ăÁ¨Ù]‚o†zjƒ‘æÑ¹¡ëȲjê5°ÙÚf½Â ¹Ü§ôV¹âEåX„BY¬ÜlUd4fú¨Ḯ{̣,pe­‡qRïRùf̉´JA!Çh‘ÎFÄt£ĂáỔÎtLçƠ™]Îv3îèÈpŸ¢ÀX$…;Ù (,(TÖÄ0²§2²‡-v{¶-½RèÊVŒ!»ÛréÅÀî–ö¢ 5»öôsro­VˆF‹ÈHœ7‘Ưïew‘Ư¬™ˆ4I©g”GOç&éV-Zܨˆ®̣ßbÜ‹ăVǦÿœUäs®»Œq†*8đûéÚ„*^wŸ)«ô‰¸̀÷…Ưáë¾æs<ù!c™Î_) T¸Ù| ̃h-æùñ f́z&&F?Ü·Ơ_ÖßP~ø)[ñ&'´2’ª/Ä?‹,ɤÂ+£tZ—…¬ù˜S`mASĐÑp̀7u¢Ë¼kÿØOS¸(Úc-₫IF@öÊ0‰(ñîRÖKVß₫úIöE~J„AEuÀM¨¥(» —ê]TÉ™«³L›é>F¢jávÈ̃°'Øà‡€¢Í‚¦_i;Ø€ûÛ§uUØK%:ZĨ)gÂ:ÁôÍ¡â½x¨̣;´Û [^eºŸ5)7ErWÙï¬~|à¿ê àÁ[¥¢(„35ÚaX>¦]´áñḷ5zEÓ‡(n ˜Dコă{¹½ˆBËߺRk̃྽ß|L»=¿{Ø.é]’›ńN|nƯIKï°‘ØqiÊ’wܲ(7̃-1Uoj/¨/ÏFrV*nȺÔ4á¥é®l²'á<§›đ|›oŸœ’¦èù\—¿­\>„ê5H¿ÖÎ₫nÏè§/ÆvĂYZèám÷­‰ằPêđlÓÀ¬ÑNsÔ2×ä(áÜWS̉Á×—E¼“S9˜…ŸÖ×9B­†U°«Ñ³àhEîÛ^s·ZOÚ>U¶&¯‡¶Xđ¤̀ &¡åöY¬Ëçß/ú*ö3‹bɬ”D¥öu’¦öEé.Qá0`ÏdÅà)sa_Ê¡(/̀ÀĂ–bœXïx<Ø4¯ưt»Á[Ç,hCưp8:å¾…øÆnăzœé!Ôú{ÛO¤cE¾—5øâÖ 8• 賸Ơ¹Ë°_Îây ï6J0¯ çiäƒ+ÓØ î£y½‘*·µÆùLĐ+s‘½lŸ̀·Đ 1lWŸé¹"Mi1ó˜)9C¤HÓQQÀVNC]76œoÆ‹7 ¾V]ñÉ5ÿÈLîø&ó¶+,R¢—„Ÿ₫¼@c“¬qå"AiGk¶̣9À°ÑÅ:,̉…?¨°vç&ྭ‘Œ6‰ø§÷X(°‰SÔöt8’̣dnÑEŒ¿ó₫y.æ̉¼#Ưº—~'•̀V! Çá1®„ưíËñ›DëĐÏ»ßYvơÄƠûÜÅ;‚EDNk“^9’b$S`E©›Ü*Ôén¶,ƯR˜LRÖÊ·Ö/åÉÚ™äƠÈ78Œ¸fœaơR›)ăèmÁºå”(œMà¤Jt}çÛø çà$Y†ơkăng†̣’[ÁṛÜK`)ú棗’Ôñ1Kxæ4¯ *#§/y ­c̉Tdˤ̣Ú’±™̃$s®óÆëYÚJD/èÇA+aiPŒ ̣ …훸¼ØÑ¤́³Äu‡¼#‡ă“WÛ!M=í´8›|I,Å…ëö7L ŒƯŸ”u2ư¹ºÎ6YÖṛÍtÀÄ’₫f]®ª ́ÜƠî|y}¶́W(kqtEñà•3̃?aEóª,çÅøơléÅÊ››WÉ:¶œ¦ùô_pXå†:g3v“:¯ÏµQ^®&¦4>qP "`X¼ÂlÖ¯¼S_@Ñ„AWü9ˆ¦Û#T¿Aö¨—˜Hë÷~yóù/¡ă´±ÀQ†öùñ@–§ă'Tfˆnq¯Ơó¬}úÔy2üÜë9ToJ×ÜẲµü½­ ïzúŒ+q`₫=B½₫¾]köÈ́̃ƒá g¶ ̉t™J¶PăÁ6¡«;-ư ‹NNLí·l~iA÷oúî‰æ\>^~PƯƯœdÖmWRÔ’“°’ ‘ƠxE`pøǽ2+Yúù9c,¬Û3lÆBơĂ;e˜Wö₫.„àP®xÆNÄA94ô(Q5µở,!zßtwÆ·½̃íVÑüB±{OJy%(ä?Tº%€’¥ˆ2æ×` ¿êx„°P“lx\ˈ>ñ°b(b74Ă0}ֱ׳6vw <àXúÛP¥FÏêm™Øøoí®Í°ÎxÑ«ö‘D iêƯư…îf¢œ—qµ}Fȵ±hÊôu;#á{8Ú%)ä—¾ÁµøKK_Kj̀â ^¥é')Éboˆ&MD(ø§–n>'„Ä–û̉èâ{Ơ»˜­}½ñL¦1Ǥ¾K±çµè-¥–œ₫R ûÈ₫>̀ˆñ(ç×»)³ @"ƒF;â\ß. ªƯ£}¤_́—o½ûăF¡§ö-‚wƱâCOl¬>JL+}ÆT“DƠ?W a»+&üDy´•,÷dHe¼5N2§éSCñx¥„Dz‚ £¬ă»öw™t©ƠŸµ—ơ”NsƯưƯE4ß$½”íĐg}´ÖUWÄsº‹qK`|•;Kˆ£r“:£/ê‘Yè¸/¦A±ƒ₫8„®ß!èÈy’ÄÜa;º°!Ü·ặ3”ªd›đ-A’¼‰b‰$àäṬʉG>ø ³xuûŸ â«“û&c(X4“k‚pƠꔯ J‰¬”IQ8²ÈĂ˜ ˆîÅœí-AÛ³¡ào®ÓÅñ~Q‹Ó"40¡k̀'+đC#]7ñÙJ¨8AY9Fqk%·ï'j6~ ô´ï¬‹§6¢MFiç5>‚Ë›ÙǪ†êΧT¾nyŸ¶6|ÖïLCíd |Ο̣m¯é÷*•Æk6»¤=<²Œ<–/*jGŸ¬Ñ8ôÆÇ^9ü>)V¤nZz“¶…<:¢^!VêyäÇ;½E¡™ñơj;‡2Êl¶¶wW%äg´üĐ ¹s[>L®n²“5³à#Ù€»„B/`ëÔ ;^ÀS=ñ&+'ËC̣Á—ñe=ˆ öC‰÷À¯™ËÍN̉~‡"aÈF’½‚sx{i­œ×.·W<™cº`„×PS¦û7̉{‚WóXŸöÛ^îVK&f}¥Ï|î:ô4— £!S92R¯Ö8e:ÂnĐPÁ+áª{¤ÙŒçˆl4½‡–ë]yßLA2@üĐDëŸ)ä_ye‡qöÆă[Ųù§ơ©W÷®ÂƒÂ¢»h³0ü®€U¹.ñ Ë47]sÛ€QwüüRø!#¯br²A=晦øỢÎy l­=-±-ÅAÆ̉jZtJÆÈ1É{‚N¡fDx’÷QøåSßW6ư»á¨¦¾µÚ•©‹²o™­¹"Ï-¶ –4<ø̀hD²l8UYÁWt§uGsM±}ÙƯ¹Ë’±øqq‚l±ªÓxQ…ûÈ´g!®R_$ÄW%QƯwøƯ÷×E½Û×),1V"æ{¦ï ̣FøØhÖ S>´·ƯđƯVó£Llïon…æ’öp4ß&ù:3»H"¾‰v– ¦&̀̃a¼́hâlÁĂ›¯ùº+}5̣¡ ÑÁà#P$÷Éâ-é~óhu瘘Ơ[¨̣ß§Cæ·¹{v¡QiŸ́puÜÖBQ™Ùouq‡J>¸¼BÿAl²…LDôÑDA¬c ưÎ`ir•o= á4."Ug+R̀Ô₫ơµ8/̣ÏŸ#³ïzX+Jèë´œ9̀c ïbÎGƤÙømÛ5vÙˆ’s ïƒn¾1mñ0øˆ:¦àâ–$wäPªà!¨Êvrx‚˜Ơí—êđK™đ'ªúRTưŒ4:‚åWEáÂ…od (æ¦hz¥´Ä)vÑPøn%÷̉Ít»ø›k£OÿTÁÅ–À—̃{5uŒäøæI¡Ư· Ăơ´d©ñˆr‰¹£ÂA5¯f#ÑăÊe‰r¾8\>r9¢7JăµQăưƒ{ Áñ£ ;î^Ÿ[JÎ`aåR¬ÙOƯ.{¨{E?dÔH¹m›ê"’¥Đ¸:̃†Åñ­zåăS=S)ÅÔăèàÓ{¢}‰đB ‚5̉Å#f~û‘́.~Oæ¡j k”«K8»d8ØĐA{ëÅÎÄo?đÆ›aÙâC¥Cđé„l\ö„NBÿZE‹9t /Bä"±ạîfŒ EïÑÏí"ÏđÆ\… âCmù™©Qtm‚üm‹ăÑm;ëè˜(Eù`>ëI"]¤ˆ.hôKÚ¥’ü/Øđ—w[ˆ/»¹˜·U´ÀL5ƒÖ™lË»–́ Ûuq¥W7¯zUÆƯĂ–é.pŸ.²‰w 4dñCÜOWp¦AùUôæmø‚z)ĨF̀pj¡₫„́³NH§cƯ|Nă@ÓäP¢¥%û·5Z(Ơ.–v JO|ÁÀâÔ‰Îđư;]ƠË "VFZ‹¶AEú¸§¸Øåxé§*ô öáää.o¬ œùu ,6_i{‘;Táñ<µC™Çª;ç&3[H€’;—z|ø"́ùqÄ•TÛœÑñç&fï^— MÎÊ¿̉u À́M-„ESP=>p=¹•¸ e†±âëŸ4jÔÆ—×a(,ÄCnÇ̉~7m²‰UhAØ>úØÔkă\—ñtƠ$Ôơʇƒ8FWëîÙ,¸Ơºét£HƠj ¸èĐFÜÀ6ÈØ3a>vÄcfË€‚'>$>¶©n+”«Å^&ë.äơ B³Ë#ỒÎè{6-WÂÅ̉ê "X碆9°-k £Í¹Ư^\kX®_!b\Ÿ…2àï7tÂo¯4̣±·0Îv_Ù³æô¹‡ëGơœß±• G‹¶%åáó™NG©u¹í"²ïi¶•) M¶ưZåÿœ¼·‹mj¯wà/zª¥;ûAk(,?†Ưs„™/OG̀”fÄÏ{ơÉè-Ê´MAÔ.ËA÷­Û¨_ÀÎDÑ©ª6/̣áD€ÎY.]’mZh«];ëîe©ØÍá‘«smĂîY¬3¯'óưĂÀ£ÄHdÀmǪlOª&½ŸP&éô†Û€[79ñ¢‹àQ³ÿĂêÀ"«ÿË|Î:ơ9ÁÑ´½2¸Á}e·̀p036l¼u˜ÙeçHomhƯ¥7(¼uÈ Söḿ¸bÛ7h€P2Úöb₫ÚÄ¢êÓn²¯Sƒ)ä)Î÷ä•鬲vKÉe'na]Ơ¬"1ư.œéî–Èơ$‡¤Aó¥Ü¢Ơ9óĂ!Û°YX¦AÔ‘‰Ø ¦Q”]±4Ñ ¥,ªÓo|Œ»̉[³V¯³SE³³Skp̣¹ –ܽÓF åÓ ™?(}Ô)êéú Jj2H Ư'«`Æ7áDi™$ß¹¦ÓúQ„m‹*@ÇđZ‡Gw[ùåËêyÇ ]Â>ÿYB÷©¿d)A4S,·9~ aê©đ/c…î·œÔ(Ưéö„€4Œoí́€GW6S=ÿ–n¡%Rœ‘í6́Ù«dÖ#ôc»7EDÏTÔL®è“Ù½}|xF¸:W7Ùg0:{ưs3¿D0p×Dy¿ \1ÜrËZÍßN/ºˆùH\9~̃a÷̀üÀgM*iѽrƒ‰x`/Eذ²7â'µç×TZ|ˆæ\ ]}cđ÷Ÿ½¯*јÍưNú¨‹æ}ª̀q)EæhfA`˜¿ÙùÅ[‹â1˜·v§To)öDpÚÖsú‡>M5â€ẹ̈MJ”‡u2ùĐÁ V{­¦CÊ׳Y„á֘ȭ+kØo6Y•m×+@‡EÑgù×½Ï+´ƠÀÑm tn•Í‘É ăø‰ÓÉƠ|w_Æ&F¹Uߣ̣á~ÊÍđ.ùµ ¿Ö÷ä/¢$̀åKLÎFmÁC¬b‚ Ó–e£ë1n§ÅWD7ƒ ØÁ ë›üáûw0FÅWïŒøU¥¨)±X" ữHXxJ@Ê£y3&í.S©xK€X×̣ÔKÓ†mßK'é‡^ƒÆ×´`R76/ÿÉ…]Å4ï7 C̉¯ƒ¨\¹˺c^¹BMXÉ2éû` :µ†£&-µ°fb}’O₫1Â9˜á²R“Ûß(omÔb-ưNØơUW`öp‘2mE¾1£ø­̃«¥7ôºk₫Ú³cæÆEDRµ{,(̀=ĐrËf»VKVLLÙ8[YĂn ’]ë¾ü‡¬±{,+ ÊÙª4¼SàǬ́Zf–ƯdîR5O8+ßđœ’É’~9“bI¾œM~ŒíF*œk̉'˜Â§wåk±˜!óßÅ`Nhî¬ÊợĂ,†1°=Ǿ´ ÜL©¨à»Öz(ÏR+¾ ’øƯG•é‰ z‘Ư‚~.Ôuà¬%ª0¦³àtêxn*¬/Ûéñg·àÁ÷±DŒ.5Ådz‚¶á+†Æ"º£Rä6±Mûd,?>Ü^̣å@K¬ÇUV­ó½†zªjŒ÷aRñ|xÎwüjâ˯b{ˆcXä„U>Đi˜‡\¢5Ôeü °C Ư¿êĆŒG–ÅĂ;ùÈ­B‚>®ÔF%dT‘‡ét©JèdíM¸¤r¸KY·´Û=khRư­?ẈŒdº¼ÛpäMËi 7$Jh§ă¤ÂǴNáụ̈ <¤c0e¨?KÁô^́ïµ~'‘«b†ÀÁ₫&)M©s„×Iƒh¥Æ$ứűµRƒùX[Xư$…T_†±&Hđm¹đó#‰Zzú懯Ễơ¹#,ù;] }{ºá*ȶ½¬V+l@} _( ÑĐjëcüG̉£º/FôẺ: ÎΤbÔâ~E¯ í a×Êî\_µlĂïm/¦ĐúçkToj¢ñ%¦jÜ5Ô8.·}¯Z̀N¹M4'00ÈÁTR3g»hê·Î«•đ“Cöc´¾ ưĐæÀDFܦÏzRư)ÚÚxwJÀ_U^Ztâ%ag£Ç»nû&¿ĂjqÉÑk†ưíÛz5÷²ün›gƠÛ*/ÅnU‡&Œ3̉²$É)p×JÉÜơ;Fåå Ôͨ™fơ5#]Åê–g¦ëµ«ŒDđ`ođ®×g¹AA›&O‚€´)´(;Oa0Q;uKY%œ{½đçÛ³fïª̃BƠÁ¼»r+NS ‰fÇUGT%3hơYdKúŸ[x|óJTë· ¿ŒøÓh<.|}†Yå^*e.M!b“É4¨â$µN8øPƒÚ؆1T³µœđø}÷¤`4ÚlŸ/%^hø”#Szt¥´ƯîáÙ‡́ÜVùÂSHl“‰cïµü4Ë=dº>đ÷Å÷ ¶Q9} ¸~̉Đ8„g˧*Á!tåKZ¢Sñk˜ïĐV̉ Cv±I¨Îë¾èˆ}}gíA7;÷Œ̃Öù¿—ºå*½f₫Û£qƪk÷6¥o²̀׿+nD̀ E,æ¿§Đ¶î)%Rí°d gÏî5× cÇẒúĂb¶ÍÄyØ7Ù•‚Jy¨æ[ºÀw÷ó¯[ .µNߦC_× +·/»½Ăö́ÇIü,?®mû-¢Z»Î€5oj„ïuUƒ…‚Ví’ø,ÙcÜÛ2½»ºÆ.KŒơª½É•̣æ}ë˨M»¬azÑÓ«›[jùmËĉ‹\îÉWŒzS¸¬¡•©‘°óÎVÜ8³+6ï ơ¶ï |N->NµŒ®IÀTÁÅ£Á/!á|zî¡”0rô?¢ ¥×øzœ;øNÀ7®ùgÈ›q¾’81ßpƠĐOüƠ]å³ĐÛr~I «àÿ¹¾~ endstream endobj 1742 0 obj << /Length1 1380 /Length2 1234 /Length3 0 /Length 2088 /Filter /FlateDecode >> stream xÚSiXi–<:ʥ⧒$E €Aˆ4éiIºc§YP•¼pEÆqÑÁpÑTÜEätE¼PDFpe”8€ î₫˜§Ÿçë~«̃ª®ªï-»©¡‹œ¼"ơ'pÊ‰Ă‚ø ÈWæäǹ° È™ag·£dè.†ƯR”TbÎÿ‚äK¢0EÛ0EsEU2Àq7>g6‚€3ñ> ’°C€ˆ U2́| …–Äb¥ô¦Øpx¼Ù†pà-GIL ă@SRTNÿQ ËÀ"BŒ¡”vP ¦§”¢|6;>>Ë•,‚Œëàâ1J ÂP%JªQèÁ°èŰ‹¥˜²×·ˆPñ0‰Ú ĂÄ(®¤£T8‚’€.,÷’ƒz  o>€Ăâô§ë‹Ö'ÂpC0,rŒk1<H0 BüƒX”†r0艰LIĐñ°Ædp M0Tï…¦›́kQ)&1¥d)1™¾M¶> =i?ñ%är§” }}ŒDÅôèµ́[Éx<á ƒĂ‰¾D¥`/Á±5*T(è£Ñ&Æ€-¥âpx®Î]PXÊÖÿf±Vœ½™î$1AA(€„nMÄ$(ưb$(a5 (R…&&|éŒ@01bĐX g d§Í¨¤ÓB 1 ˆ‚hr¤ú¿VĐRC\¦ î-̣ ̣›5Đu¿ßLJЀ'Zlè=!×¾#qpºPë+ç‹x!.!À́̃ªéq}®\Ư'fßÂ8€Á¹‚ ZÉ(`9Ä…ÄôÁùẸ̈7„ü?Ơë³üá]”¿J&3P˜ưœÿ¡ÀrL¦í#Á‹Ñˆ¯ áhï‹PSÉ¿ö )˜^ o4ŨºOihµFbpÜÑiÓ­¹%fÂm&"8­¤ÅÁmmsu¶3;+r¸Ï₫ w­-³M³lÎ#¾À́=´JœƠ²gáMQđíK¡Ơ%aĂ‘ùbcă¾̃iC0ªnƯ5z”Ụ̂aó¯ßË»ÙFS:N¼¹Ơ~́ï鵪sNÛmÍ+”q~ÅÖE›́øïî½Å‰ë’Ä×tU»…ÀñdpÄ¢·#NbçÓvù́Ô|*=ơSc$Ií}üççê3rî¹aµø†72æäÎf›â‘Ñ*8º k}sV}TÑÜ«‡د¦¿—ùöơ¡àôÆ¿¸À“+¬*<®¶>µ{₫${ÀƯ\l\“ûmUƸ*Û&+9ë6›¼”³ØzCѼ̉Y'T•Û¨DÍ2â[ENÊVÆ­ë¼6s¯n3Ÿk×-’l”åoÑ\- (>;:ú1nn3‰çÑøôî½3¯ŒÜt™;Ôü‰ưЦï„íOˆ ߸{%Ÿ²ŸÆ̃éDXTFỌÊçä¯üA¾-µ"NS•Bv“Uʯbz>>®œÿض§&̣ЫɅ-'Ø£J‹Œ;̀h#ïƯßîÎf>²|sÆ’H¶ß!©Ùª[đ{9pß³íß6°Đ)-óŸGW6•%‡,éÎh½¬±“—Ă,cá—4£l{̉®s?75nâm¯x«³q<ăĐT­i+7_RåúntOàThØcZW̃~ËÜdÔmCî¦g^í.جÓÅu);₫ứôNÎIsj?-yË¿L*-̀Ï>Ơ>an„¿7¯XIÍå²íî,o?nơƯÅùqÊ+fA72êÁ Y¦Ơˆ¤•íÅ•Zûé‘RŸ_,%îOËÿ%ỜáyÔ,ƯĂ ×5^³Z|±ăă\/M¿éåÖ°lø§;=›–[™VO˜Ê>ñlôow”!/÷j&FåX¤q+ü´º×ßܸ±2µ&lÈ̉±é×Ft45¿̣3ÚäSbçV^{{øº·Ưz>¯e}stcË9~˜hêáƒÇĂÏ8•É"ö©ÉcẴ×m9œî·ù¢e›M^GăDß_©2aë₫O «Î;,é9«»È6›y¼~Îêm&Ơ¼³^’Ù¥kˤR:Cl}`Ù¶·tûkßHïo₫»1 bkkI“ë«Û̀£ÓŒ; ·Y^I!D(üÑëúø.(ålƠ¶}¬„̉?Úˆ  endstream endobj 1664 0 obj << /Type /ObjStm /N 100 /First 1005 /Length 3782 /Filter /FlateDecode >> stream xÚí\[oÛ¸~ϯĐă.Å;  ¤iÓd›dÓ&½d‹>¸‰Úølj§¶³Ûî¯?ߢ$_”ıƒ=(а#‰œof83¼ˆ27JfE¦u‘qn2.„˸a4O„÷™pD(•9y%ˆÀUA²hoQ¸¾Øå3®À ܵ £–(\Z-‰BáŒ' ¼#.Zg‚Q&‚.6Rƒ§J9`<Ơ†Z<5Z— DSá9µ°E& A¸–g’+µ"“B®•™”V¥2©< ‰Ki  k2iƒôÖf̉Ỉ׺Lz×XŸ©Â.À–rqö‰³Oœ}ấ#çßX&r„+r0ED¤p £>—è#d5 …‘£D;r‰€Ï•ô fasUøÅ˜rM˜ÎåÆë ¶̀1cØ,¦u8Ơ`:“ÜnÓØœ|©Æ´¶V›ÅÔ&7¼ñ!„o®­[ˆ)ư0Ù¶Ô*W¾Ă´jM¦E(טJæëŘvM˜Фiu§”9晋1Í0¹ÊmKM!r-äfM[¨³ë“ó“ªÅ˜ḳ í%¼V7˜Çÿ‹½–¯)óaVœ;Ơ`j¸m— é5ÙVK“ #L¥r¬U6‹ ·¥A³Æ„ÛbN°YL®ó¢åCđÙ¼0‹ûSë5aÂo1m0¹È•3ÅTđ[/›QEĂo}¡6‹éFÏÆ‡° Åè¹²X¤%Ó6™Oá>–~Q3-#¬P¹äÍ2ÂJ‘ ×á¶~M˜p[)c)`Z¾8< _f¡s•‰t+•̃(&¦³H d›µ›…tU0cO˜˜uwÎ3X¦•9íÔ˜kDµØ…L±&LÉĂÄ¤Æ •ÛÊ5aÂM÷ ¦À^™Íbb­bu÷}Ǵ∭E XđS)₫Ä₫‰Ư­œö cûOÁ} …©¤m±iùsx…•I&&b {?·aÊ]H)Il052;6 oÅ\qƯ °üóª4&Çâ­«î$`Ç KÛ`:ØÆ½sU5±z7²¥'¢̉açëV̀U' ˜ÛA·S#̉.Đm˜z]Y(a¦è¼ Ó­ “₫w­̀‡µ'Ö‚‹ƯÖ®) a2ä¹m0‘*xÇتjbđ(Âf8& xYQw'º5¬,[C&-o\yj[YVa₫å]“ßiƠ »Q5«UC ‰UƒíX5đù₫µÁe₫°ơoWrô¶²é;–¸e¨Aïá6Xv–ÖB匒²Kw0(`ÆM»®Ơ¡ ²xSoG汌U"h›n×ÄX XV í§4SÜV)Û²Å2b)Đ²*ă¨:̃°5J#™„ífLıàÈ\4 ơ$Y¸œ‡Öx±ZĐÛăOl9Ç2Úí*î±^(ñ²3Ă©[&0o›a2Wư(LÚưmyÛ @2·«ÅjjÆç c¢B~S©«ê'QHWu ™fÄô–„î›yñœ:læ#2)Îi³Ơ¬93W©ñÊ‚25euˆăÈ [** RªBÅy„X1ˆ+A°«6~U¤ĐVHq"SjUt<ªKmâƯ¶´h¸¸€ë4µc JIĂ˜\Đñ™©"™8ü/~ÎÿIU¾̉„Rđ Û¦à5‘^sÏ¿¶ÿƲ; X8‹*i4´ŸŒ !êICÑ’&RÔoàpôÇTÏ«{¡mÅ]6±Sña ·.D O1±Vt–j™`>½@”˜ƒÛˆ©CZO£‘®WU![4¶§èt-ˆPFP×êÍ–¸3dJ=ºM_ѵ/D˜œ¶:aÖB•†55åP?œí_íl ¹ÜŒNÈ`•`́¦Rb•N I£¡!º«Ä Ñ$‡XS…–Φçp4—‡ăy²ºŸxÓ"FcưcíH7µT¸V­-5u»„÷)+-É‚Øù—UI×QWZ¬¸¤§ éhPĐLĂÁÿ¨¶§®¦|hè-è¬H8ÈhÉL¡‚CÀ9 †$g)sº,ÁÔêù`C,v#K¼…¨¥&œ¶5ÚÑî³L©ŸÂÿ<̀ZưKw§zv4ª;±WB»ºn|®4É¡è¨FƠKͳh¡HW%y]³Akư§åø|Ô¿ GqíÔû‚'Ï^́?Û~ûËÎá^à₫Uïó8S±Â“pàî,ñH„ÀÄ E„$mAŒÏ鼦m8Á×»̃+ûŸ/'t*»e|öˆÓĂưI諭=ø|Uf`2)¿¼#·Å̃U)àqÙÑvÂÓ;b¿³vÊźă¨w₫g9¹*?M=¢6́|x5°’]±!ÿ…ƯíçWĂÁ²éí—nåwß́¾#åßq±X{¼°}N¾rœóZö¾Sûmö„í°§°Â.{ÎöØ>û°Ă`“cö*Øå5{Ẵ²ẃ êÁ0́öø̣¥Ç.`‘À•}bŸđ¯•́Óû„ó”́3»d—߯/Ëë³?a»/lÀưA #Q^³k:E¬¨hëërÔ^°¯lÄÆl\₫…æă₫76¾ê/Ù„M.GeÉ&Ù û‹ư;±ḯöO9Îô‹[¦_v^ÿ¶wôưr¸ß啲öJåîèy[¿<â*ơŒ­‘¼Ư1Ñ Ó*‰b•o¾‹*u¸NNW* ³&•ṕ})•Ä2*¿Ü?8Ư *ùÅá˜v¥Rú:I-§‘ZF£Ă—ÛG@£W]n‡ƒâ•F…_E£:ߩϢlđ¢•^ve„îÄY¥ÎÙ„Q~¹ p.¿̃ô®ª́̉Ç-ä?Ó9dpóåc9÷?î™N¾̃ 'åÅÇ«P!]Ä:᪹oÆôó¥xx"K gÏ÷Îö“Ctx¸¬=\µøĂ-₫ü¼a?øÁü¨ĐÛø€0;,aú¥Æ€ưßO÷Ï`ú“ƒ;g&øNc¥ôâkëßûUô%›G‹“­?“¶C#̣ë¬'OfÍ5m)¹ÔĐ²½öûÑË`©ÓÓ.[ J\’бuÓ2çS¦¢ËÚTß4u˜êÎÄE†:†‰îc é´0îÖ”¡nxW6>ÊN›-5víî½xG3Œ““N惘cï)Óûnç¢ËûDv÷¬wQ Íh·Ô8¶ựtwç5iwÖéH\¾l£/m|U@ =lhVE§G|Ä‹ÇăOt~U¯¿fơ[*-Ÿ>=<=~ưºư]Ew×r%w¿ï0Mƒô^•”f’2ùÿG Âq¤¢ñ¸¬Gæ*%,?`§‘:$ô˜Í?Êr̀lV¿*ÇăÓd’:0«ºÇfCơ¾£ó¢P^0ZÈ¥F‹g/ww¿ Ñ1R›Ê!đVŸ•­́wÓͬm~÷6̀Ơ>.è̃”"Sz¼cu™̉TÄçû´¥ƠR£Íá“·<ûå`gÿƠÎÁ³îᦠ‡JAßRÑØ|*Á½‹c·3KÑ6uøă¬çXÏÏhƠ1´ÎaĐMôÜ“̃¸ ‡!f7C¦l¿“ _îöGă ­ -vĐ«.8Çjëmÿbr9Ÿë†Ê§Ă×ôÅdZ^ Ù 9‰ü¬Dä¾Dä¾µD\¯A¢Ù¥ù¬D‚ßj#ºhLä—ÇŸ]GÏáËûăóbyü™Eï¼^Bưxè̀ ũ̃᪭¾Zƒ?L¯æäYÆ? ¹yf— ³É9ÿÄ'ơ#Ö Ñüô|N¦9Ÿå²ÛJsQ,——ivú;'ÑœS ®%R¼-Y‡‘ff¬sÙÛMÔμü™QÎáû;ºhJ¾†.™Ñ̀ ¤ị̂ă©.RkhÁÀ?'Ôœ#Om‘Lïè'Æô›74/k>ë·ª’ÿEÿơW‘WŸ™W_¤Ç>übIüè\Ưë?<@U_®ë¶D"¸â‰PBëêËz‘~g@¤¦HD’"₫†ÀC¡̉Ï ˆô["ưr€H¿ ̉¯ˆøê¿wvsq endstream endobj 1745 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1889 /Filter /FlateDecode >> stream xÚ¥–ͪd¹ Ç÷ơç•dY¶`hÙ$$M˜ƯEC.CCÓú#$o¹ê¸ärÓ¹;U¹üÓ‡¥ Iaƒ è†P̀ º²\·Dh†”í[LU¶œ̣† y&3ˆ·Âv“Y¶ÅŒ‚›Jº`ac€Øưbgˆ"Í2T¸YÇ×ïÚu´ˆôvß,s’Sû1™Áf¡JMÍjׄ/fÙÇʹ}g%; K‚ eBÀfƠÚ,´œÄ¨–µPí416ËN¹Ư@û1q»5o”E/fÑF’ E7*©Ư(²QEjV2KS³`#ÍzK5Am7$m o郓\¶dÇÍb³jó‘qK\ÚVôœ›K+Ij>¬̉©´T1©Y¸Y棖–G2ÚJoo¸1´‚¡‚±=R²·C0d§¤låäTÚḯ™s##nf´ 6²½2‹62ĐÆ¥Xô ºq͵YæCSëK?™°^ÊhÅ6ˆµJ+YvJVl%1­- •¹=2X3ä ̉,4«EÖoVúkûØi±̉])WFóaγ¶,![4r&³j»aƯ$(lej¯V?I¹Ư°p…±EoơÖ½ƠOr{-°ú‰Hóa%¥58XƒK¥æĂFAjm7¬~®óbơ+-³p+íA¬~…̉ƠÊ›µËƠ"³,#56é¢V½̉̃Y­xÈŸZíJ±l´¾X¯©%Tª%©Ơàj©h©[m½­ọ̈µUV­`­ëÔºÛầ—Ÿ~º¼ụ̈ßß_·—÷~{ưzyùù_ß?ÛäbŸ¿¼uLØ₫~yùóÇ~Ư~E²†·Ï6&JƯÈƯØ’=ên\/ÿặîƯÿá*Ý7 vr7úA7̉¹’èdǤÎK©Ư÷#~“+î®rçåî*ßt7„̃âJrÇt^¡nô£̉­â[\Ơ₫2½?’öGÓ~¤{%à ®RÇtB7úJ7ô-®h/÷₫0QÜÔR?â˪DWÜCç½€œ»‡̃,=OYÎU>q%ƯCÙ_†ë₫V̉OtY·²©ÁÅ-NÖ=pâK»Vôæ‡79j È>”Ư>¯µ— r¼eÙŸûâ>¹\–£RÓưÚ.k÷îº?Èpÿoß¿}úø¹!₫ôñËW{Á›,\^₫̣Á>]ëÇ₫¾ựÇoŸ^íø&\——?¶Ÿî~d²ß}ÿåơß·©}$ÀgÁưø¯¯ÿq¡¼äxy¨5D„s‚Ë ë‚ 1$±8`^SÎ#́…¸i„”) è9J¦ªÊŸuxfL àđ$„'ÀNà UïÔ˜ă½UoµÅûúñ6cG„}ÈÈÙꃧ́<Éwöîêöø@ G€sB É£N“¯.ùZÀÓ«8 /€€{À#09 ‹F`]ÀR@‰À™.`)˜À  =àÈHO€ SÂ!(ơ´§Säơ‘Ù[üđ­Å{=mqqµ±)ÖBf’ƒâ’Zb́2­…¸Zd=æÓsu@Y9a tºÓD±<Ld8r”‰<• v2ÁeŒ2‘§2ÁN&˜À(<• v2ÁxLQ&x*́d"Ơ0ÊOe"¹ÑH‹ÑHQ&̉T&’›”ôlR:a:ÉÊ”ØwĂ?á=à]&öÍ24z&W q÷µƒ¦SH.{¢!ƒ¦Å W Ôs F˜GˆN'PÀ¨4Ơ t:iŒï…S@§ç@ˆ:S§PÀ¨8Ơ p:¼F€©N€Ó ÀS hÔ ˜ê:ZÀ¨0Ó Đâ€y :Ñ́€´BÊxL ÔóI*8›¨.åºH¹)ĂèR®‹”kL¹NS®.å²H¹”œ¦\ªÊÈ8M¹d|&;¡”)áP=ư7àØÈ)₫Ü̃ÿ hø7·FW ‹Ñ}í®e&< .{I B,†L‹!¾p̀5§æC!—0G N‼íÀä€xdÀ<:iäúØ S-d' Ă8¶$ -±%{À·–́̃[²<8vµ×É»«Ưót;·?¸?>b-¦û#¸ưÆưñEr¡ÛaÜ€Q$§ë$¸uHÏE2ME’œ.,€Q$ÓT$ÉÉ¥'À@S] § x&’*ñ z¿÷†¤ ‘ưÍŸ6¤[&aX&ïöJLW3pË# Ëă bº;úBÀ)/®Oâs«# «ă/Êăts·9°9>đ¢:NGp‹# ‹cäi\aº6±6ê°5´¨ ³Q•Q‡q„ùÔÙº¨Ç¶¨Ă²8² °dƺ ‚{âÀª%°&b µ,9eq`ÁŒ•V:eùIèQ,:Xgc ¥Öd´Üg@K9eåÀÂKŸ²|÷÷(V:X§­/XyÆ:_N_$°î}ÿ?½‚)M endstream endobj 1750 0 obj << /Type /ObjStm /N 100 /First 884 /Length 1746 /Filter /FlateDecode >> stream xÚ}™Í%G…÷÷)âÇŸ~Œa0x5 f˜đ¢ăn{đăûdVfê*PiQ]‘•ŸâDJÊÓ÷.æRËâQ¸—E«4Å%qéó¸e4ÅïZÆeM)SpÎB“ñ»aæ -¼ôµ̀­(Ö¬µó:•V+&br«‚¿6Dj„©Këøg5Üs*nÑ*n!ÜkƠQÚ¯Ö̉€ºƒ¥̀̉º¶˜ªZÚT•J?‚ªv Te•~U¾>êKeüÆd¨ê•̉¡Oq$@üô3(áÖˆ~¥VútjégĐIe èKq|ă :Îđ:¸ çzÅÅ8ƒv)c&÷Y Lî­ n˜Œă¬˜Ü@5'®8¨±&ƒ5ÖÂdÔ¬x¢ƒ §/‹Ë„ pë*˜7 ¢x˜GPÑY&‚¾D[™GPÜ:‚"'‚b€[GPa-ó*Là …[¡º0,:” Q¡C©P/„ /™ ƒ#("Aç(t(•Y1À6çC̉¸%x2)– ·$œ×98®"/ÁùpC ÎO “q><*&ă|x@“@6O<=Áù0!ơxᇑ­ŒÀ̀È&Æùđ”q>Œ /Öă¯+¬DP>Y8Æs•#(˱'eéÇvé€a€‰ŒÇ GPÄÁA@#‘„ëz}ÿưë»ÿ₫úÇo_Pw‚êûÏë»bHĂŸùúå÷?Î’<¯ÿưå¯ăjW?üàVO[ƯÜjn×­Ÿ¿~ùÿYdÆjµ_“úơë·ƒ}Ưư×/ß»íÚÓÿû¤4Ư£Ö'*¤Ûóç#*q°g2ÅDéj§Ÿ"ưdú‘i«:V¸¯ö°æÊXSk¬©Æâ”5«F,2ÖHYíuírcucƠŒ5Ô±fÀëa IYäX-b±±fÊr¯]n,Ó8RƯi¼véYƯ4öTcwG¤±›Æj́ưƠ#}«e¬¶+ÔhƠÜ>©ækuV7«æ6“¤́ªæîmWº·y6 »ÔŸ₫3÷˜¦¾yơO”ơ5êÍôVMW;ơ-R_M}¥”åzY¸¯j½¬ö”åzYzY}z™®•°ơÎ z™.5§,×ËjXd¬‘²̃ëü̃åÆêƪKƠ±‚^¦úÔ¹ª¤,r¬±ØX3e½×ù½Ë5Œ•eúalßY±¼WÑ”Å佋RÖ{̃ß»ÜXÓX=eUÇâˆeyÏŸäưµ:Êt¶Lß¼ØÖË|̃]̣£—=ÛüèeWÛxzí1M=oêï(WÿŒê‰M/­l59ơ©'SOœ²¦cEû"«s)ËƠ9EuNVçT3ÖtuNQO«ó))ËƠ9Eu>­ÎçLY®ÎgTçÓê|¶Œ5\ϨΧƠùĐ”åê|Fu>¬Î¥,Wç#ªóa™>̉L®ÎGTçẶ¾§yß]̃(ï»å}Oó¾»¼Q̃wËûæ}wyߣ¼ï–÷=Íûæ̣¾Gyß,ï[÷Íå}̣¾Ỹ·4ï›Ëûå½99mĩW—÷-Ê{óuZÓ¼w¾N#_§æë´¦yï|F¾NÍ×iư$ï¯ƠQ¦›““¥É;IØ=¹ûmw½“îm碌ưßï¤̃|LYb1½ú'ÊG̀Ô“¬i«{ºú]½,X¦^WÆRq¬h_ªÆâ”5«F,2ÖHYïu~ïrcucƠŒ%N£u.b%Ơ(N£¶ˆe%Ơ(N£DÅ4Jª‘Ơ±"üô2a‰Y×êH³­Y=M_›ơ½mơt§îăñêÓÔó¦~¾w¡ G ™^’tµSÏ‘z2ơ4SÖ{ï₫d_ĂX-cÍåX±̃-SS;VĐ»eZ÷”²̃{÷½Ëe½lö˜u­º×´î5̉̃í̃"O_¹6ß{÷ưXï\“-¤6Ù Ûä#dd…Ä,lm_íÄGM̀¢ÉfÑ6–³hñ¾̀¢ÉfÑv–kk‘E³h²Y´åÚZdÑÄ,lmc9‹&‘E³h²Y´åÊ<²hbM6‹¶³\™GM̀¢ÉfÑ6–³hY41‹&›EÛY®̀#‹&fѤ~’é«#S&fʤf_œ°ûóSôWiÖ÷ïMî2x^»­ªz̃­½ĐÁ‘b3e¼™²}ơ»z^+bMcơ”U+Ü×Sç¼Y´å,GÍ¢ñfÑvÖt¬±ÈX#e½×9GÍ¢ñfÑ6–¨cuỊ̂Ô9‹¤,r¬±ØX3e½×ù½Ë5ŒƠ2/Ç¢ˆe™Îi¦3;VPçl_2§yï¾.åèëR¶Û˜Ó¼g—÷å½}ôÆôĨ_«ŸLÿö…™N endstream endobj 1776 0 obj << /Producer (pdfTeX-1.40.25) /Creator (TeX) /CreationDate (D:20250119164745Z) /ModDate (D:20250119164745Z) /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Fedora 40) kpathsea version 6.3.5) >> endobj 1751 0 obj << /Type /ObjStm /N 56 /First 513 /Length 1785 /Filter /FlateDecode >> stream xÚ}XÛn7}÷Wđ1z̀Ûđ Œæb4IQ Éƒo]²Hr₫}ç,‡Zqw­‹³3særÈ¥7PTZrʘÀ¿Z™˜TđQỴüë•Ăs¯•wF•Ͻ¢ù—ŸyRÁ&­¹–T̀‘m£Rä8“Tv́7^íÈpCüDGe¬áPÍ.K³Ë%­ˆŒ÷–́"í/(³+˜¬(±+$ĂvEïxÀ®DIQ Êdđ–90Á¤¬1Œˆ”­²–5ee DAY¯9†gÀúTâ #~bÄÈ+æˆÉaî6s‚rÚF‘gÉöI9ë2FY9GæÂÄ •+ÈÁ(×óŒLÄ…„¸à‹6ñ\gƒj̀×kd¦á­vñ̀{Ư£$å)ö£¬|Œ‘kD^Ÿl‘yr´AÏLjä• “Q“`©#qî³g—ŸV‡uÇ‹Ÿ¸~¿¸|ÁC*Ă›å®Ûúơ+ö®ûÙwEo½ï~Tdz½ơzµÛs(ËíÍ·KX9ëjûÀ8O¿x₫¼©é‡¶­é›T`GÙæ˜íó¹lO£Û§X~PïĂ<–dÏ1ñ4dÛssgRƒ›¹«4ËÜ Í:wn\rïFâk‘R̉ÅÂnëÂÙ́F¼ŸïñÎÅ2§Xó¼́€¥ÏaÙf"…e‹eóËÆ³XÔ`™9¬0`ù³XFa9Â4ÚG4J6Íd›A• ó­&k囿ªÄJsÉBÖæă"Ă’¶Ÿù Í'zqÜ5­S)E«¾¨19µÇA—zZzZ7ÛHÏơzZ‡ù́23f®‹ơ Y·’‹âÜΫn6­içƠ‹Rna¥ÈŒ@ÊiÈóÙE ÖsÙ4dŸ˜Z¬Fn%&rơY¹”¹i$75rÓœÜ4ÈMa>»§ˆûÁLö 7—«¬Vn:•[ =&7 rc:W2†Ó’iæđ¢,?%Ùs⣲ơÙư[ß2²3Zơ•§,¶oÔÓ¨f8LÚăöX¤” 3Çn\Çl6»Q̉Ö >˜sX”¬Y^úˆEé,V³¦Â²Å¢aMG7¬v*¯Q¶²Í#kZ̉kƒÈ*̉é*Ö›¬âûå}·W=yjÊ”×ẓÔ.ø^Lb¸…r¥Øđ ¾sV-Ơ°>¿çó•k®îW‡ Ë®¯ărFs¸“r¹å^À†…‘Äp RĂ<ŒF0̉¸pá› ˆÏ’Ù ‘d #F†a‹Ñ3‘(«áp“z ߤ5‹₫Ÿ©’Œù$™( M$,4‘h²ĐD"Ư‚0M&¸đM BSB•‘±€âAq‘ä4K30&ú€ ߤœ³ˆ}®oÑç< Ñç†ès†èsÆDpá›dI.Uê”D’Ç2Ơ14%Ñä¡)91@¸¼z ߤ‡¦$2<4%‘á { †ḥ†4™gd*oÊÓ‚À…oZ0#^t4‰ ̉pTĂÀMdaÈ"ƒ1Xø&ơÈ#^¶²M`ˆ&0DA“©A¸ÜO ¾IÁ€‚„z€(S ˆªÛ<@TƯ梼P `́'-ƒ-È®i=L¢¯çS@y_7}ˆ½%SRoƠ2VƯ=t“}́'3]uŸ+R"6_ÏÎh{«ú¬Ú̉*¹â±´ÂiQ€Ă9© úN´€¼Í/ÿlw{†®›óÅÏåj½ü¶î¾h¯¯7‡n÷÷̣{‡Yá—Ëưê;œ»Ưj¹fO¥xô|ººáÇy2'ØIMĐ„çÑûùC=F₫¼_̃ờ>ǘv?WƯ¿ &Ưvµ½¿ßnà|ư°ù~Xm7¬+˜X½?₫[mîpÆ—5 ¿wwüÆ„ÎP[îÍÍơK6Ë9|ª¢åXâ&B̃t›n‡Ù ^đ®íƠ‚¿HÓ\on»_hw›êƒưa¹^3E@/7·øYo—·=iªoœwÛÛo¬+:Y~ƠsZÇ•b¹R=²Â&L?̃\/T6²üeQQûË“WƯ]÷}yèn¿,¾[CÈÍvwX¨T›™Wt.1×"₫«ơ/'¬]×÷Œ8˜W?9¤z–£À‰^9F× &…·‘Û?₫ø̣Ó»+< ̣ä?¯û;‡)§ø)“GHÊ‘Óo«[î?±ÿj(_T¡ấơèômwÄM5'Ë ÜHË÷DÔÚÁ;Ơf`C%*¹PÉ•Ë{ù̉(ƒ<{=2±̣‹•_´³rGù¯º=ûúÏ•§—ßÿ~tệjÉ›f{‡ï]‡ ú¹îĂĂ÷RyTïÀ}—ô;å’|×ñvb”Ïû®Æ÷Oß.¿uë½zöL]¾¸g^ºßp>]¨Ëệ•z₫Üáw <4CC0A5501BBF68D882EAC7A2ED178845>] /Length 4116 /Filter /FlateDecode >> stream xÚ%™[lÛYÇçÛö^ÇqbÇIœÄIÇÎƠ‰“ø’«wl'¾_b''NœBTÀ} iV% ……hƠ9Ơ)¦U«>ơ< ´Fªö¨H VB ÄQ´û÷?/?}ßx<{f­ß·çÛk%Irô#K’ư‰%•¯6P]I*Ỉj ‘¶|­‘:¿Z̉÷J_ó×&P±¤uYÇ^V­ Ù’ö½º̃Ny^’¶T’j¶'I’̃H>âØ^Đö°t‚à èƯàè‡Ápô‚cà88úÀIp œưà gÁ çÀyp\—Àe0 ®€«`\×Á 0 ÆÀ8˜7Á-pÜwÁ=0 jà>˜Ó`<Á,˜ó`,‚%° VÀ*XÀ:ØÁ° ‚-đ <Û@³ª)Û¯€f¼oLrh(P ´€=B…“Û,éüN6dx÷̉\Ûë5—{À^p½ ôƒ³–LLê*msæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9sæ̀ ˜0'`NÀœ€9¡a5'À@4fP´€½ ́@^5Y2ô®"s΃Kà ¸ÆÀMpÔÀ4xÀ2X–<ÚNˆ6Á3®¼t‚à èƯàè‡Ápô‚cà88úÀIp œưà gÁ çÀyp\—Àe0 ®€«`\×Á 0 ÆÀ8˜7Á-pÜwÁ=0 jà>˜Ó`<Á,˜ó`,‚%° VÀ*XÀ:ØÁ° ‚- a¶Á đ́€Wà5Øo6y<đØä±Éc“Ç&M›<6ù= ´ạ̈Èå‘Ë#—g’=“́™dÏ${)Đø»Q´A^‚× qƠñ ¨‚= ́Á!p'-ù‰C%‘Îi Tº! ˜*à4‘†XƯÿsé4)*ƒ“DA¹¡ç½T'ˆj@e Á™*ƒcD3@e ‘|4oG‰æ€Ê@Ă¾I-U€æh¨­U€&t¨ºˆU€f¨m½Ù¥™|yx/Ô÷½ªÉµTûˆ^U€t|T O›̣F|ö}* W pN䪀V"* W`{N䪀"ӭ麀* JÄGæûHuî/—üMDçT@N‹DT@®T·KäeP̀éß(ƒB'ë3(ƒb–H7Dº²î2(éy)ƒB·¡Á¡ i"¤Ê@ϦרSÅ}"MePè)5«”A1I$(ƒBC"_(ƒâ.=a£ ²Ï²VP£ Vj@êJ›ePÜ"r€2(øFª±dQ£ ¢6@ăDí€2(XÁ¨uÊ %ê”AqƒˆƠ²₫ Ö ¨€‚%ZPŒª€«D¬¯Ơ1LVNjÇÊ`˜ˆƠ·Êà2Ñ) 2`­¥Æ²\Mep‘h¨ . •«3µs@&*̉)*ƒ!"]Oe Ó‡« ÎévUú =›¼:C¤å94¡º+ já4‘Æ™~¨Đ#hRT'‰4ƒREÏ{¨ N±pTShp¦€ÊàÑ Ph8Y[ªỊ́;…_ ÅQ̉9ÀÛ Đ°̣TS°ÊY[ÍÖ PĐÖÖXœª© 4µë@eĐE¤ET•<`骦28@´è‡ IóP¬’¸‚eŒÚ À2Fí¥%¿ú+Zk"Ưµä7WKüT…_7Û|¦¿¢rÙXâ÷_”¶‚K~i,•|íßô¿ZÚåĂËK¾1¦S´|¢–½ñ ÷½wtîûăgUsÙcÉü¨NfÄË£–üaTÊä•',ùÖ?(eöËÓ–|gGWyKMå€%|B§ YyÎ’̣ËJ±¸¼hÉ_¿£¯ÊaK>¼®‘ÊK₫ñO”Rå¨%ÿúïKĂœrÂ’ÿ)•¢JyÛ,ù1¥÷Á¤™»¦7Ê)³öRå³®*U_:¦»lLÅđ ̉§à‰Ùï)U«»evçëJY[/_˜M_—ç ªÔ½Wf 7µ ó̃˜­₫ib•Ó‡tŒßØăf¶ưI¥4›í®)m-f?^Uº́5û©ßÖgè;A‡Ù'»t^Ñ̀~nLiè6KÿKi/8lö‹}JO€cfá«JO>³ßØĐå›IÏ€ÓfŸÿ´Nfïn*½†̣̀~¥—ÁE³¯ÿ@éU0lö̃'”̃#fßüŒ.¯å»q0jö­6r L˜½ÿûJïÆtÿåǃs4¦û»ŸQ:ÓưW?¯”oñÆtS—×H.€9³¿ÿ¶NY‹fÿ<¤ôhL÷*} ÓưĂÇ₫)xbûx̣ƒ-«´¼«Ë³¹6¾¶­̉qY§hÍè•Uº™jf¤o¬̉»Ó˜î?₫œ1¦YÅ*ƒÇ•r“Y+¨Zạ̊»:ÆbfÖf•[3Jơ¢b•3c3Ûg•Ùư¡°̃™uZe£Ô±€åϬË*¯¿¬cƯ€ƠЬÇ*?ù·:vđ*ÊZåSßƠ1ÜÈúÀq«ü̉#Ó›I÷‡ë§ÙI«üÖ´₫Ê›‰Å½j6XXÍÎ3Vù̉tÊ@ U²‹€Uµ U²aÀúZ†*Ù`¥-»đ%ă=“±đ–¡J6h²2TÉnă²»_²IÀÚ\†/Ù`•.Ă—́`½.Ó[cĐ7e¨’-Öđ²e€/Ù*`I/Ă—ll|ÉVø2|ɶ­P†/Ù6x^Ơ+À"[†/Ù@³“âUJ‹“̣ÂHén̉f@c“:@O“²Í›̉ΤmARÖ¥R˜´Đ¿¤€Ö%=èZRVR–”UΔ^%=hS̉^@̀~ÚhỈS€9OûH:èAR–JRÚô óH/ô ßH‡­FzĐe¤× FzĐb§c€"4é-@‘̃´é=@÷ÖC:è̉@»>4̀é ?H­Aºè ̉@C®ztФ@º xù§[€÷~ÊOß”—kúĐ¥;€—zúĐå¦osîơ"e~Ù6q^‹­ÚÆg~Ù6ql›8¶MÛ&mLjcŸÄyæ—]çµZ{̃*y·.Ê]ùM«¼ÿÍĪ^¯T6Z-çµĐ́8ö?ûưÇ₫‡cÿñÿáØÿṕ8¯²Gö?ûưÇ₫‡cÿñÿáØÿṕ8ö?ûưÇ₫‡cÿñÿáØÿṕ8ö?[Î76+?øƯ3F°âØ q́„8vB;!ÇNˆc'ıâØ q́„8vB;!ÎO[å{ßÖơf¬̣_TôÀæMÑCkú‘?S4kMé+³¦w†Í[SœR´ĐØxûPÑ¢5ỵ̈{–¬ùö)Z¶æ̣ï­XóŒ)Zµêäw­Yơgש½l³ê¯_̉›D_đ̀o¡!VưüG)û9­{3â%#Φ¼£s%#^2âZŸ¤s%#欣s%#έ£s%#ÎV­£s%#Φ­Ó:!}˜+vöp]9nƠ/M7îà+ßH₫­‘ endstream endobj startxref 370610 %%EOF instrument-control-0.9.4/doc/instrument-control.qch0000644000000000000000000034000014743226261017474 0ustar00SQLite format 3@ .v‰  o–«A $ § › 3 ½ ? É oX''qtableMetaDataTableMetaDataTableCREATE TABLE MetaDataTable(Name Text, Value BLOB )t ##/tableFolderTableFolderTableCREATE TABLE FolderTable(Id INTEGER PRIMARY KEY, Name Text, NamespaceID INTEGER )| ''7tableFileNameTableFileNameTable CREATE TABLE FileNameTable (FolderId INTEGER, Name TEXT, FileId INTEGER, Title TEXT )t ++tableFileFilterTableFileFilterTable CREATE TABLE FileFilterTable (FilterAttributeId INTEGER, FileId INTEGER )f '' tableFileDataTableFileDataTable CREATE TABLE FileDataTable (Id INTEGER PRIMARY KEY, Data BLOB ) 77#tableFileAttributeSetTableFileAttributeSetTable CREATE TABLE FileAttributeSetTable (Id INTEGER, FilterAttributeId INTEGER )33/tableContentsFilterTableContentsFilterTable CREATE TABLE ContentsFilterTable (FilterAttributeId INTEGER, ContentsId INTEGER ){''5tableContentsTableContentsTableCREATE TABLE ContentsTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Data BLOB )x--#tableIndexFilterTableIndexFilterTableCREATE TABLE IndexFilterTable (FilterAttributeId INTEGER, IndexId INTEGER ) !!‚ tableIndexTableIndexTableCREATE TABLE IndexTable (Id INTEGER PRIMARY KEY, Name TEXT, Identifier TEXT, NamespaceId INTEGER, FileId INTEGER, Anchor TEXT )h##tableFilterTableFilterTableCREATE TABLE FilterTable (NameId INTEGER, FilterAttributeId INTEGER )l++tableFilterNameTableFilterNameTableCREATE TABLE FilterNameTable (Id INTEGER PRIMARY KEY, Name TEXT ){55tableFilterAttributeTableFilterAttributeTableCREATE TABLE FilterAttributeTable (Id INTEGER PRIMARY KEY, Name TEXT )h)) tableNamespaceTableNamespaceTableCREATE TABLE NamespaceTable (Id INTEGER PRIMARY KEY,Name TEXT ) ØØ&Soctave.community.instrument-control      nn ‚ .instrument-control.htmlPOctave Instrument Control Toolkit Manual    âû â‚%„Nßxœ½‘MnÂ0…÷>Å“P7($Aü6,«r'ÄVÛrL ­à,=KOV™HP•J́X̀ffô¾7󜧔z̃:M RI\OÖỤ́0©¸ Ểă“Ù%ï(ÏqBiÅúe U#:«¹W$$µ„qÆ€Êjë Œ–‹U¹mPZ/ÈO₫ pd̀]ÍüæÍpú₫*yơÖx»3b¼ƒ½®_@µ¨—tvà¸Ê4̣tAíx©)­¸vWÉ?-0u}„(Ñó|=_ WܶÛ×ÙË2÷JY`çOv¼"ÁMÕg^|Ï]+j³l C{̣1 ej‹† yƒCºø¡̃ÿ{í#¢œ8Oµơ-ăsư'́;ƒ¢|†Åz̃xœ́½{sÜ8²/ø¿>NÜ>vDUIU*½Ü¶âºí9Úí¶½¶zf7æN8¨"JÅ1‹ä,ɉóƯ7/à J²»'bÚ*H€ 3‘Hụ̈å¼}ÿæêÿûđ3Ú”Ûøbï%ûç?¦Sô&ÇA‰Ct}₫üî7t…¿FÉ:E§³ùmÊ2+^ÜƯƯÍn’Ư,Íot]̃9>(iÉ4E„{/·¸ Hµ)₫ç.º}µÿ&MJœ”Ó«û ï£ươj¿Ä_ËèÅhµ ̣—¯våzz¶±÷²ŒÊ_¼_•Á-F—IQæ»-NJ¤̣4FWi‰Ê—´àk5 ¶øƠ~ˆ‹Uee”&RsFbû •/ø₫.ÍĂb‰é._ái©~y˜®Hu­xe]ï´ßÄéukeÿŒœeK·Á Ă¡½đ]–æ¥Ṭ. ËÍ«ßF+<%?&Q•QO‹UăWó}ài%_Đ&ÇëWûÿy•fû(Çñ«ư¢ €áü«}x~¡½LBü•è߬0}£ÿôó›Ïl¬ÖJüä­×1F鉂µ6‹2ˆă(¹™I8Ó Œ’F.Á_K©¼$ ’ñ’{/‹̣>ÆÆMÎ  …ù¹…2 99instrument-control.cssinstrument-control.css> ;Oinstrument-control.htmlOctave Instrument Control Toolkit ÷÷ doc îî!qchVersion1.0UAÚùét/˜­̉,‚^LI³ÿ¾è:£̣₫ÚDaˆ“T†x•æŒá ”¤ ₫ÅQ‚§ƯlÊèoÿg/˜»í6Èï§1.KœO³)#¬\T|¡OÉÚ$Z ¦h^lZ+Ơ ïí½ÜÅƠ¸hËoÿb¡—qtñ2 ư€Ísu:ß7Læ‹9jŸµĐŒ©µ|ë,'üKü?•‡óÙÉOè܈£Fz’0½+¦í¦ ©?¿˜Ïˆ=D́a'á÷ Q o£¯Êùæ·óÙ¢¯}e×Ôzưùđp’µ–^^̀gKô~½’¦lÚø…‹'Fö1³côK5¨œÀ˃]\ưPiưÑjú[Üàéû[œƒ©'Í¥¦×û D#̣ñçÎóèơ®Ü¤y!5Ë́_,fsÄ~t²äơmÅD>]Ơ]Q«¿Ê $^ ªVg3”Ÿˆªq‰>ÊGŒ?ô ă‹gj-2¢B•Tm̀æưªÇ->ó]¡BJ T=Ѿ_:-́¸zó¡Æ‹«7€ô’1âê͇A\rbÁHÏæœlÇÇCß̃ÄHô¹L¡zHH-€¢Ïú3à··uüö–ộ˜¯”·ĂäxœôlÎÉv0úĂ*uPzDÈ,€ 2Œ}— ùÓÑÓxsœ¬°ÔZưå₫ÅâO‘xê,=̃¤ÛmˆNÈbDµ«†>]( ̀:̃›(ÉvƠê’A{³9ªF‹Lwe{Fè-ôÈ@0ÇAx%×qºª¬6å!!y„äg4AW)ôÈBk‰øo»<*q­sêSBñ)mÈ*ư«r'H<°!_£’"O©S$ôÔơ"kö¨.û1h^’­ÖÇ™h¢z̀æH<0p–»#~!•}FÈ-ôÈ84¾Å›´(¥9T=#aJG½˜ûạ́'™³.G₫ÄÓχ‡ËĂ”xđ>¯a“öÜz½Ó¢o7ŸKSQèĐl₫7+¯è+ïÚ §Ńº@J’,´Àç·ÄÚ® ¬,éÄ‘Ö úιÊzí́_ÇG³¥Ö…ú‚îÑb$–l EIµ.WÎ} bÉ®´(éÉỌ̈ÊЇUœS/°h­zBˆ"ñÀ@ ­ú ?3²›·¨K>L[êcBïœĐûl³ÚDuuR)OéR>¤D-&¨]F[œJ¾ö‚RSẾ¡-qm¨)á%l3ÈE–JÛXú‹9Bä—¡~™G778øoJc‰Øï>b₫rñFöy,̃±%º\¼ñ*ă£ÅÊRÄk%¡7’„+7/Èä»Z4¿P›wIªªIëGjë2U53­$i©¶o3ÏÛÈ̃à̉¦u(F>V¾Á¦eÛF°°k·àí(íÆv£Åª2é+JäÜ«æ¤Aæ2…ê!!u¤>ĂoKzê*SŸç„¢ÍBâ••™«<¤KôP´˜¼®:Ơ§”äœl˜pƯ"íWâË–¤}DưÛ«l£¾s› ®•„I²¾u˜æÙmP|ù«i•7–'YèïƯ»dyzQ̉‘#½#bO"lZỈƒ¥̃³è k”¼µ²¤Çz'\¤¯Nú£ư€TåIwN»óÑ<4´¸ht[-ÈÙ);{ê³Â?°S*ióG@ôñ_^×9?³4dCç¤Ï‹¸™4j&»¦¡4éÍ¢¡7J̃´æJ“Î5tÆaå«äk¯©8éβ¡;6+—f̣́œ‹cV¬A›+ ½”eVºœW-ó¸Fj§„Z™[v. Ê@'Fbg@ ~Ú £¼‰<&$Ï9É02™C¬zQ¥N’<£ËñÂï>"ˆ^Á”9{‹³¯ p~KR©£4~ÊŒĐ³êås¯2‹ô[J¬zaè£$¯h7i%¯;û ½QN%™Å{d{2`jD;4°èVu¤p*‰/¹_V' ]͘D{­,é̀²Ö±.“6;&J“®׺â䜔ɛ4L­,éÈI­#ÚE&mÔ-ơ¤#§µ¸XvqĂÎC+Iúp¦÷¡ÿÎC"Kÿ¼ÎqđŲ#r ̉¡s½CR‰!³åLÁ93?¬÷dḳ˜<ºvaXÏ—Z5Ú·8†r¼Œ‡Ñ—Â;ûv’W£¬Ih̉IVfx'û¨2µí^MPC¡Z·Cd~ϾÑ:´o5¹ …Há}Ë‚<*ï{vU¢½«‰r(EK ï^Q¦Ùu$EÁÙuPT£]¬ y(ÇË ïdí¼Áª̉aÄél^ÿP̀îh¢P#™ØOJöŒEvZ‘€ˆd yDI£ê‘‰ûDE%+©Ñvˆà¡…ÂåuUåª>¥$ç„do!3˵€é)?ăÆ9éñl”ĂM2EVi²nv9¾Âù6Jè]Óäê¬ ½¯™íPă ¡´ÓÍ[J;­<é ®#HƯ]Ơ„­¡Z«Aº¥ëÚ­kƠŒÑª•'̉•픳ñZ5aiÀêH§t]@;ånÈF¬ŒY¥4é.øI\Z™|F‰˅bj®Fº§ }̃=QlX?{N®jnéû̉¯áS«×† ±é¾) ½º1ë3Ó >ÓjÖ«S­ÀåÛ«ư:hŸ>-1¸[¯>ơëT Ưjó´Ä°nơ]’äªmH§¬B8DqÍvʸÙ|ơÈ\ƒ9&S²ÇH}ÜËâùp)[:.æ9úôá̉¯e“E¶¾Fµ$ôF¶X²ÈÑËÈÉ}fJẢüBm̃Å[Ɖe±R´~¤¶î"9QóÂPK’ö—jûNZœ‘5©o©iúXiÚAa3‚¶\¯˜~¢´<€ç&="# Ÿ* ;(FĐz¨¥‘>SÚ2Фîë$4(7–'}9¯÷…½7†̉ER ]ÄÈ!Üf4×lđ!©O)µ9P³r ñÚêX~H).E›-0««m•§”ä!i}(ƠÖG­ñ%maYµĐ86Ưn NÉÚˇäNÑhdå*³ÔXZỈ7Ie•«̀Me º¦´Z¶¿PÛwØ<+T‡r ¥iGêq9Sè›ăÓ₫,ëưq:‡-˜ µ íÄ±Ú ‹BP5û4ô¢´ 'jœÜ‚²IÁªiNƠ8èXAƠ΅´’´gj\ô§k0läb´ís¥í₫– §hËx‰ï̉ÚÀwƒm#cM«R±¿uĂIZ¸<̃sU&ÚŒw¹ªîwÁߌĐ€ ˜«6XêSFn ä¬̀ ^]vå!#yLHZŒ-¯¬^èÏƯB×î@‚“PK}ÊȲ–#)c‰Q9Cäg_„ƯT^(V}H(ϵ»Ë>-Œ¡êấ7W&}WíZĂƒ¯_mƯÆ@©§Ư[4tÏÑX‘Z0‹c­0í̀QCgœD³DƯB@ë¥ig– q“Ơ}³ÄÖ Ó¾7ôÅIxKÔmDx­8íÎICw,e--Ë•´̉gD­zĂ€Äø„ó[œk›ú§ôo1RªbÄP™ô]#´†1"µn#FjÅi÷ Ưs#R f1¢¦9j茓‘¨[ˆ½4í̀²¡3nbD¢o#ZaÚ—ă†¾8‰‰º©§Ư9i襡¥e1RH+‘B,u[1À!H[̉đÍ#² m="ZỈ7I„́BGˆ k’jAÚ₫BmßA:(T‘†̉´#Gơ¸xDúfHSqÚŸe½?NÑ‚É#¢¤8V;áàTͽ(í‰Ú'ˆ lØjAÚSµbZP5E­$íÀ™Ú§kĐr1Úö¹̉v}É)Ú2^â»ä¶đƯ åb¬iU*ö׆œ¤ơ€Ëă=We¢ÍxïÂj÷ 3BGi®ÚàQŸ2rK gåáƠC¼Mk4ÉCF̣˜„'–•‰¤ư9£{JèÚùX8 uøƠ§Œ́!Û;$R ™-#„CΗ º™Oc£Éøë.à´Ⱥj’>«Æˆ)ö_‰®‘›¦ª´Ï‹ö>;ïÀä–m¬ªz¸æ|©4ÎÁ u+̃¦9_ªö̀€ M¥ µRÏœ/U»Æ98S¡n#êÂ2çKƠÂqÊ”é›ơ¼9_ª†c0¦L¹ÏàHcsVëÆÀ¡1«=bp¾T ÇpA™r¯é!ÏƠ ²|3’W°mú# —}TơÉ\•—•b&”˜>́A/eøé§«_e\$ú€Đá\1 m$»€äiî˜Ö#Æ<2mtsÊ,.ö*RÚ¦ỉ~̉gmShF‹¬4Û]Q¢k‘“‡ä“Ê NÈwá•)¼ß8œÑ\2/³‹Ë­‚D­%èep}ó>«dơâ}©Œ“m”DÓ2]ÑÄlƠ$Vó̀Hkk¾Ñœ\F­_Ë+#‘X́_´f’Q©´$‘‘hí_ÆhsÅH—ûí‰aTZ¿4¤¬:̃¿¨eƒả[’µ,»Xƒ¨VSù́½ÜiuIJ׳ü–»J¸q‰Ù-q•YØ/³‹?¥9A{GÅl¡Ñ³_¢d÷¥I|ÿ|Ùôv_ TrĂ¿†´uâȱ†¬ehO!é«â"EÈ'ÉªîØ¼º¾Gë4Ó; Vn€6ÍŒ넬rxx}‰^́‰\™Ñ—hF?É—YI©Ï¬Ÿ³`ơ%¸Á 3Åú]ïăåÙê'*–£ë2ʳƠ4$‰¶œ¹ 7÷ëû·?ưö©j>*®)Hâ°†öƯd5wk9£:§o=”a×È™Ä5bBA]®Ñ®àÓÆVsææ „m:\âßEqŒ6P6ˆÁ¾G×'Ơ¨ĐI¦¸@IZ¢ U— A…Ă½]ă2·%øçèçTôƠB¨4ÎÇ]BúP-…UºƯ…BƠh}¢µ̉M™Đ FHNƠFSQ1ÇÚS%ÿä₫EöåÁƠÓ†Ù„s|ÁfW¿YÖ’:¬s®µe3̀¸–¦†̀;FRv/³‹¿FåŒ ’(/Á%˜ Ks)d"†©f’€LÛ“-iׇÿ.*7öö‘‡yÀ:Xß̀3‚KqPâ¢ăÅtO×ơµu%ëkŸEÜ~|rkÍä:ç[Cr9ÓTkldĐLk¤῭7™‡Lµ é$ó’²_ị́́vj2§ù=º6ß%I”ǗYÎ(*y“µÉü$§n}ÎNá*ô¬ ̣ÙÍ¿†ˆ´_ª yǤª̣ æ’ 7dúü¢́Ü@™à› ‰öaËo‹ËMÂ/É”æÔ¤sGRLöʆÛ US€¨‘4ù đ¡•€œ­ jé`8m̉¸"ÎƠŸcåÊiNÙˑӮƯÓœ4®Ù‰c‘ÑW÷ë´åFư]yxẒ²…ß’øÓ Úhñí4Ï=f8[øx†QÍPË5ªƠjÈ$ªyºsªä”¼¡'AÏ Ú^Ÿ$ÇT½JÖÍö$«¤ê0P̉U*.ƯÅÛ®BDöÖ^¢ÀÄ[U´±Y_¬FO±¼zÛüÄOx×T´<̉•̣èV«T·Ug×\§Lk 3*ËÓÛ(ÄEÏl̃NY¼×ë]PœŒ%NÚQ߃Fµßˆ3"Íp^¼¨y!£o£a§£Óë]C Y=¯“0vú´+ƒư—?ôɬ€'7((¡Åx¶J·?Ü”?î‘å5?•x$è×`““za°:_, üÍöë,Äjéÿ+Ư$èm¤7›&åÿ‘n’YÈŸ%0&~!©"Y¤ª.·[¬MÉ‘c¤XÓ!L%Đơv“\Vµ$¢ÿX́-#XTë¾%˵I4̉4ȃà:Ï>7°‰I*–)xsB ‡• /̉½ÿD–óƯ&(ÁO˜y„ t‡s,ùQĂ]®̣ܾ—Î2„ÿUu+ 1=a˶>¶gRúÓfÛË>ê!Èq¹ËÅœ̉.2*9Úá€JàR ³f‚hÅAN=sqz7đàˆú*Măëôë_˜kă:œÎ÷¤Wï‚-F¯ˤ}‹®HOüSªI„^‘7ÿfgí›OæG¯ˆ¤¯-àQ´XUOà ×Ơă%<¦j¤zx\=„Ö«'đ¢\eƠ“Sö„^©­ŸÁó](•*ªH·˜,(đ8eË`”qp-©̃b·Ú  @$b‚høÂ^¥ª%[dx­£hqœ3=^'įLª~E)9h%E§¸¨#Ư(n̉È>nQDsTSJ˜£JMÙ&=BQ`µ¬¨´i#«ư_ƒ¹2ß¿è̃nÑ·äf‰¶é«̃t´î®Ûg|5×7Ëz‰g³¹%¿8ÅF>-/ö^–d~pA^¦»Ơï£kâ'# yYæ/ˬ´—E™§ 9Yçȯư‹wï¯~~y@]¼@ ê¨đEéơ?à€cô|)‰æß÷äx)È2Ă*åI¸öêÎ1b \§_gd ‚ƒj¢„>ÀƯĐ8$öG)zBiio¨Ùđ̣  á?9ü¸P©iÖwR…9ƒ!DPq²2\T¼…PWÏ~øç.-<ñíAỸÿöé§9}2Aóùñâđđ9j±-¢¼(‰~Üâ₫ ̉Ou% ³‰­S€ƠÅ¥úŒƠ*MÂz]˜C:å}MĐ̉µddÍ*8¿r\æ¾Uçx%°ưëŒx½†î¯r”ƠI;Wetô'°1Íp^FXL/Æ$Ö÷—(ÍkŸpCĂÛJÿ¥9h?Fñ‰„ÙCN†ël'\>+&ˆ¾äĂF=Gÿ ¯Ơ¥µÿĐ̉đ…zɽ¢öŸ@'₫“pE©&Ñ~EJñZ ÓY¾‡ f™ ă¢Ø0¤OƠ@Ä9µGªQ:>+j}i°ǜª̃à4«Ă’´¯•J¤”ÛÔ"g]a‹ûƠP:]¢‹ø§H>"4ótw³éR;ưu )â]ÏƠ?t®á åß½¾±uóS° ?Úé^ÔZ稴;u =²ÎÚůfqÓ*L¸)‚ë{´q7ÈUl9~! ½GƯçÍ&§́́n ¼5{عW³G ƠÏ­ºê~î?\̉ØÉûÿ%ª1V›VĐÎ_÷ Í÷/:J%ι¾ëWq7vưl2wÛ8aÁ"Bëá7ûÀ…'°Ó^\›₫k̉k)¬±Í +W¨]ÜêÓ+WÓµóÅé́pv8ö¬¯åuùa˜C0T™̣BeÚms)Oï‚ÎĐë$DiFïf †́‚nƒx'4Q¥×â`Wºị̈m!‚›¹™%dz8đăxÁ‚¡Ü,SJxÂiè“æFœ½7É”Z2WåS€6iQ“6ÍQ”q>O˜¶$œ­33 #ÆJAí€23 ¢\˜®œ•( †$§Ă8û]Y˜ƯÓ}/C>é4Ó’=V,K>A5KQ)Ê÷ÍÜLäUYƠÔªn*̣ẫ½ơZüđkC [₫ûç×oÑúï««óÙüÿäÿ'ÿk̃/jCNĐña“ß̃!’ w€»A€‰?wƒ¢â-”ñBÜ6ëd‰¶›ËA¬*$%­¥yU`_}ÇHøUv”è*/Í+!í¨₫*6y‘Üß™à6]‡ø¾²ßWvâûêÅ÷Ălôí´$œ}Ée}÷ÏŒøÛ ä«[Oiï{øî½ûÆ]ß÷5íÚEDÀ[v‰ạ̊–ưU»°ï·Ă·́ºëf¾¡F(ë¥E†luĂ.#A:m×Ùüë¶ĐÊ‚=„ÖĂo×O`»ÎB©́6ëĐg ă"„=-»p”=z”¸%Øk—^Å9¯é‹Ø’Ÿü*: ¿ ~%1Äë`ÑøQ„ÄâH=¨ª‘çd$7Â₫¡vNHC‘ămZb0̀˜f…Ÿ„Beơx0O`ˆ£½b&µ÷ªùû~¥H7^ÊüÑñP'-78ÿ&́·î9ü;ÚxóEñĂ¯M'(JlÁE©q¼Pèxȉ½@Ÿ~"[hIåZ¨ÇEÉlÖ‘‚îàÍ3¨‡"]}Á¥¾qnRFTó¨oĨQ]ơø>ªg$Ÿ5̀“̃ûTF/5“Wµïư^¶­ï~¯{SN¯(w› 7躼„^Î$e*.³˜ Pï%°ƒ’_M Æ |k6*đ+?âJpNUù³_̉ äÑvÈC¿kÜçÎuĂ…é~‡á9°ư(¼G°ël¼c‡Ü´Ûnäû]µ®eµÑ>B —Ư ʲ™̃KÖM“MÏ«$9Ăâˆï• XÊÅ-¸¾âb•G×ø)Nïz€À½I·Û4]ªƯܦïÛZï\³™­»ØăÖZ.̉ohĂ³¶̣—‹7ú́ËÅ›¶̉¿Œ,ư*6}ÚVç» ¥Ô:Ù¿àÏ»/14'é’Ị[ µ„]Tkw#ÎÍï¢Ö₫p©Ô:ß¿øôá²+$£9ÇXSÂơî – Zi(QÍ‘Øæ}jî]Ṣ³.ÿU£¿J-ÉĐƯ+`÷¦R Z€B;̃ê¯-À~z§iƯiz§Z‚º0À„Èj¡$ä +‡fç«ÎmI5̀æ¨&́ ª¡‰Ú@ú\ È<r\NN§Jđ¦Ls uy*9U~7¦…Skƒx%×qºú¢Ërù]W}+B́üy[=b̃66|̀l_SËR UØ7äh¨Iá°UÙ.^8ûÂå¼Ư{₫£„JĂk˜­2åV¹Å,•éĐùùI¶2Ó¯áÂí:!¬ä/«ÇÔ¦Köe•¾Ä7i~ôö/^ ̃Sö_Å5âơ«ƠùÎ\ôè%ñ•KEá÷4Èov âôÙËÛ@@<Ưù₫Eˆo_ÜùÅó—PúÂÄ̃¦ÏibsXS À÷„Âϰ2³]‰®wë5Î9ô¨:v×̀€—(|t¶+6ưe††¦uZ'BvÑÎ4åçà¡{@đ9äypR>²êû{"[DçÙO#”¯ƠÑưwi‚«˜¯–“œO˜Æà½¨æ$̣øù ŒÖA7Ÿ­3Ϻi^Í ¹q«å̀i^Ïœ§MÉù\Ñ\ =̉’®>ÈiMÓêưueŸôYÖ]~Ư^ØƠô[Ú†O´¸‰€¼¶»Çbq!Å2°A¥>dy«”†¯o™]»®/Y ¾ß0ƒ2`óñ[©¨U8¨&æĂKíâ¡ÎÖ¯ˆtmNÍœ^|‡œ ÆAgÅÂ(©©¯ñD¾Ï2{=¤öÂIj·tÙEj‹ă ƒÑ´º @,î3,ÂßÈ“ @Ïx”ĂyñÏ]úă.JÊ3ö÷ó>Ê`ᨠúr¦ÖSúäv÷#ƒb£k¡,–Hl-¥:TIP*~A¤~ÊîăG1p6ØH¢NÙƒđ×U¼ É‘HúK¯ơKGNbéÈ»X²’G²¢oweYñúÓ›Ë˧#1T—…Ø8FªăËÀ2₫¢‘.E‚=EI›8Đ¼‚#0£Ø75–ÄÊ_i˜ºüùçŸṆ̃́l¶¨;p]°ƠÔÉ.DyqO«ÔÉu¢€̉Ë.₫`U_|*üñÿă T¥…î68Ç/(®Ÿ(Ï–É$ÇA”đ‚'7åúœy‰mAR<é$ækÓÔ{' Ÿ¢$Èïé÷&ô´K'IÛâ]đoj×̉7²À•¦# Æ¼½üKG1ßÍ«§àü“’Z›%÷ ªl¤öp“O"ăIZk§ß>µSRû³Ü:¥´ƒæ_j%€;ä,fƯ±“°9~pa#YWe8 ©µ¤8v”Ưúd$M£k–§¨:d´‘”î`IAÉx’@́ l¥ÓÚ‘¤ ƒĂv4œQAẶÙ ăÜ"Àµsk9ë!iNœ$ÍÉCH…ÓBذ§}Ä̀‰£˜éû•÷ÜƯ0© ‰º\r½&Ê£ŒzÆ&éÑ}Z` ôk}í LTĂ^›bÿuâ©Î¥§@6Íi©îx&1m¬Ă˜(Ü?3=I¼h É‘èAL̉«ö ¤"oÉM·z “xåÔS}–QÁCJ™êcBĐ¢à%2Ă¼ æÉi#¼½’î§j•.{<À«èúÙ9±¢¦y ºè¹%Ê©£'Ä©ôúĂ˜Ôâ‹–,··Q‘ÅÁ½l–AÍ6Ù©“MvÚÏZQç V(deBö Đq\§»rọ̈,V~±#½ÔU½º–¤,*.*Äí»‰JËnc3R`ù¦́̀¿OÇ“hñ*dƠ±²~¹‰wêhv3»ÚØBÊêÏBÇ,¬­´ £=\Ï0B¾4 !gĐ5¤ûSc»åßj³àéôư»Å̃R1:ÆU\‚̃2¥Ü­¼xÛÁÚñ8[kTÜÁu—ñ‚?)ÿÿ́p._áÚyx· __s–Z™%^&)‘áÚkÜ3I(n(EƠ*™Œ÷Įӯ{JR,âXàM¹±ú¸ΜTĐY?¤ ‡̣gu©ºLÑ?å3D8X© 9˜Êª¦”aâÆ® \Ư~#næ¥ ±j›^¦­0ŸÙåZúO´XI¸ ¬hIÏ¢¢ ºÛD«ÚQ1l{mî0§+ú£—~;sÔoƯ#I`Ux,¿l̉äE è§t€ÅÀ́ÁÀÂ3N…a†ÜE$ñt•$8äå‹UqbÅ‹Ÿù]dÊ öÓÄ Q«•®éă”[¬HM3~Uî ®z¹p/öäÔrrÖ¹åƒdSR̀-S̀µe“[Ö²ÉײÆ4¥‡;Ơ³ĂƠÁ7Ü#·*q‘¾•ÏÀ¿%ÑÂ%̣Å%ÈŒ+H#O–4·iaÙ%ye”€Kt—¯Q¿ånËË‘ñu˶â|ø°·|Ÿ̉ĐøơRÈ”»ư¾ÖDº³·‹ưó½a6Đ«îÚ »¬f°>̉â(@ .ï̉ü Á¤E9\‚gçïEö®‡{îdÄ÷3b+̃¢)úoùc$(»¢¤Ø))×#-îÅ!Ăx!Á¥–ú ¢)́†J́Oh°{± /Äú©•«> —Íyîhsöd¼3¯ñ×T—t‹ËkWw5y£µye…\• 2>OzRQ‡Mr±ÙØĂƠ1R?‹¸ó—£Mü¿₫™p9‰(«­{ØỠƯƯÍX‚½¿Ñ ̀̃₫à Q„ư—Tö¿ÿ¸·Ç  5‚Ơ(t‘ ÿbÅUƠ íw¾[®2’xVw:ŸêÂùl¿#]€E=ÑeX,ͺMHê9îḤñí‡ËŸä³Û#DÎËM·¬Ö S[2-¬lo>—Ÿ—‡tùùđđx iÇeMơ³ÜÿÍB±Z¤í\¶“8 Ơêg½*m(áD&•Ô‚Uâ´ŒùtÄR'®aHØ“.VA²Öá0TÚ¤ˆqZ¢£e¨ÄI‘6â«8§q<:n†xÑÚ­,ºÖ!àYWỷùú <§5?wO<^ŸÆ½‘ŸcÂË3 BV…ư2Ö¢Œ¥u:9Xdiï_ÚÊ”yts°J́ç°‹¥mt‡®NÓ‚72›¦0đ%aÇwH’ăÂz/È¥êĂ~Ẃ0œ‰¼r… @^¦DÇñØèö ·5k‹i½@ ºfȬ¦ Ô”„‡9 „Ú”¦ÊÜËŒFÏÂƯv{ßsfs¦&öû 'ó]m"ô‘$K#]U.¢-`‘.‚Hxñëë«_^ÿ48˜ÀÆ4²X!G¨Ñ`²FxăƒV 'âaPR"fØa¥´Nwn^ú˜đM‘é[§¨té‹=:V9ƠÓoÔ/1›["‡²ù́Ûc³àcĂ»m:y£%vŒÀäÚó©ÏåÆÀ¬VÉe:áoïœP·Ơyvû­‘*"‘¨ZRF&vÜ4-}"}©;}e>¢?‘"˜$¯¯x‡ûd5®ú¶»fv4[¢‡ÄƠ=üÚÚ×´5½Vå=fpØm´ơà›h®[6ÁŸb?vđ±xÜ ‹è_nBPđÊÿtŸS·Đđ£‚¤5p¢ÎCk×!êFÉô»,a’4ÜœÜ%=›½àl6s‡NN×q8~2ăP‰ó|[Ü|c£Ôró^2ê>â ,ºÀèµåQí¹Jh w!†`0 õ ’*¶nĂi‰ßi§ëæ²w̃,½Ü5èÅnHđDC–q§9Úâ’¿ŒkẢ& ̣5; ±!YÓƒŒHFĂƒI(ù¿y2̀KÊ÷Á́đ)™)Ññ­ÈÇâ±aî4íHJt|;̣‰O;_°̉ÿø<€)h¸ éuøú›'‚e₫ÇáŒH»qđ`C>‰Q²5" zJ‡Pß́éö“́ÎD³;¿c‘¶˜ÅÔG4ÄXdM2 Æ"¡4ÈçØºLYÀĐHºĐ(OúbŸR–Q`>:½û¦*ŒÀé†ßSä´óAUŘ<Àz{LÖ¦óĂ`NÄĂÎ »|KcŸJMi¨—O «Ø\ m}ªˆ]øIt‡¨b‰̀pm,ˆ ñ̃´-<)–ùá½0Ê—VÈ'€l¦ù´9dd™¢7ä¶.fÆË‚¾-fă"¡à&c‘P2)…áÓè<Đ¥j#oéU¡…í'm}k "ñ÷ ªñ¤D¿¹ÍÙfº6 ˜dF4ávtvMäó ³–»}Ê·Ôª²·t—6C—k”n# OÈé–‡€–UÇU/! 8t́ÙsTl‚8Fô^Y‘A²"7”ê+±Ú?±>‘·Áº–ărøtL‘Á@ÆÚ­ ‹¥{¤» X¦>t)Ë´ü,êâĐåƯµD?î¯Æ¼ÿT?̉´I˜¿¶4(0qŒƒîv¯£˜g°ÏÊ47,U±Ú\–‚¿ nF5?DƠƯ!Ûù=‚.Đ7J!½K×èmq(Á·8矠ùœ=O€6\¥,™Åü”=Ÿ²zV`̀.Ø¥+2ˆTª>‹®Ëmúœ`l®w9¢—AÏ.>Ní®à0°“má(b¡<¿tƯÄîđib؉•¾·aÖ§oó’îÛª'l:-âŸy»®ŸPîïÔ®GvuÖ™¤•áêÑÍÎzê_p²`âw/qÂAµ~¢7A¥pD¤DºfW{@ Sëƽúœß²4‘̀MnÀEi2‘Ö‘.ṛ~$CâI20ø p„(Æ„aâ0‚CD#1|åBÙ”u<üA€`†G‹̉ôŒYßø ׃˜2(wÅO÷%¶ßß?̣ ˜ñÁ?qøæ8.ô£—Âé́…à#¢cº1‰#½îˆ0ªf·\lYï‰-U@^…UĂ!¦>4ˆ>@đdđYµ±]KÄ‘o £$ˆ‘_‚Èp ÆHq*)°€~H_eXW´dm x:~tÊÔ»~8y¿¦áơ®è€Ê£:Đ̣ôÜiTÈö{ÇÉ»\¼‘ạ–@MØ­´Î<2%†`äE‹•D^´XơGȤ»̣åøx‚p ¿îH#ܾN®̀-5Êèh¤opÙ†top;H[;ÑB#z¢-Ú‰F‹•-V¥I»&ª£àÁ;xnªÛ„/;§¯MÏ‘àW×Đ̣̉l3?ơñŒ@§-£=°”è¤åÔ?²Xox8ü\¾èæ‡Oë†Îc#Đ?́ è.od¸®ö~Œ€;§Êj‹É¼@u >`.{ó4“)©'6‘ŸîœÅt¦Àsưf3=d}¢ sª½a±8PƯ °8ˆ±Ü¤˜ú(÷c7å̃rX;®Ơ¤©ÛR‡éÊ_FÊ‚¢À Äơ)pz~ˆâôçè:* .ûùlè§̀]•yO&K `vÙ*¿ÚñJ$ÓEÆ%ØăX%Ưσ²¾±sª‹I–jÈĂ¥”?E4*"¤t…ëñd̃øpVRïÄMêµ><ÀÉ’¤9q•4Ư&<–¶í ù!—-Wöđ[*%ëú)baÚÄÙV×8G2^Ât®Úƒ]ê«—̀8u“-÷ÖṚ²i'‚N]EP7ŸØÖ₫‚÷ô#.­ĂjçsTƯ¢¶˜Bg5R₫DæÓe“.ª$]£hk|ë‹È6H6¹ÉÆ– G+kHp!É4#Ăơæ•tg®"²›]]Xsb̃>Ôœ+zĂÂé ó!ȃ8Æq„/̉¢ -í:ó„ Eç1|"Ă®jÁ̉ádœÎ–ĐhDz‘àth©`/émP|ùk ¢fQk@”sk¦ ^‡µĐ`G"®cÖ,k´;`kºI×Ñ{kÄûâ÷èä?ê¼9inâcƒ¶ut®S’P‹Arù‚ªÑ&¥ÑÜ;– j¤©Ú?˜Pox`Ô»Ÿ+T„Đø™¼8î=Ä·Îq×~6’ă§é~ظwÁ̃1ẫ;s9vĽÓååxîfP·Üo½¤Ê™fiPsÉç7$ĐÎj>wµ»ỵƯF½W:zŒÀ÷F[ÇBo-ô₫UĐ í%ubˆ“È ×c‚˜ÁñÈ$’¡9’U›̃'!t¢ơ=¤Aç¯û‰h…ÏơdE·Ûùcüôñk¯Áù-Îy₫D×6#dgÿ&Aƒ ßDœp ₫ ơ4œœ0}ÍNµ;Ôeeñ=‚~A3à3&{ "àW› ¹¡µ*̀œ¼Ư¡Ză å̉¾~÷₫_£÷ѳ4‡¿Éógï̃_‰—Ï{Ø 7¤6Œ{‚AËAl¤̀Ơö›rz4ÏàÇ0BøÎÊü„pÆwoÉï&.æ¸ăüî€ÎJï?º¢“₫2lú¦Ó4ºÏ§‹åéób€(`̀!$cGBRÖ(IËÊøèåi\¸‚ô÷Z2 1b„ṢĐ÷³fèÜÙ‚±;“>–PeçÊ »eø™µ¯³jrÚ§önđqs—+ƒœ́3ư‡Rrîy4?Énô´ßƠ€t‡38 —_˜5Đ ×đÇxu¥bUµ¥ođ1>6$ÑaưLBÊn–A¢“œÄº¹ØÇk´pƒÅYô„Ådå)́˜r®‘ÓV ÷>!.vOg•F1¿Q8á#̉ơƧ9¾á/ —ưɶ̉K'K” é&Œ¢Á$•CLäÈc²úª/¾¤f'G!¸˜HU°çôÇ3/,T´¢)zŸéˆpÜăܤwÂ6³\Ü÷d«j¶‡̃é/Iz—HƠ™o,ÈéÑûü=cW¹Oy0!/ä'ü?O–Ơ¿p÷*Ʀ»ë¸ßÁüÂ=©÷ú¶Íe+°‹c èO:.d,û€¼đsD¥bx?«úF€†à+ø=̉Ri{?ÛúFÆĂ đ…ù¬«øÂù¬káó´è óÔûbœ³®ßü…Œn—}»¸Æ;+Œ¢LsÂp+©ƯùµÆÂ¸¢¹œÍ-*IŸ­É¿Ûms\æ¶ÀÙHDÙ@.Æ÷yˆss5˜BQÚ„m MóĐ²…»4Zø­ÀùÛ  ̀ ́ œW0ÍÎĐ# Wh6ƒ0 =RÅlZ†«KxJ¸× óĐC8»·0v†ƯÏÚfY 8Ñ¥C•‹=(XäƯ ×ï¸ư[t¤É\$O Mºaе.ÓoËÉæƠ¶è ƠöˆN¶GöƠ½#Gû»p…Ư‰eñ”}a® j†yîjÉ<ˆc«·°`N-˜ƒO„¥N ¶d>z:Ä@$›´?’n&-¼¦AÖ™H@çLeH 1ä•ñ`̀ËLáÁqÖ&½«YØÙïơÑÚăw÷zœfâ(R/-Û­ ]¯½ƒ”æ¢'ªă ½C±M¶<”V•i‡¬̀ Í–çóD½@Ư@¤Æđ[ }tÊ›oâÜƯí´÷ºxêçî[q̃´û8eMXÅ)º£\»t#F½@̃lMøBơ¨¤ Åơ vØgoZüW¹Ê¢́¿<È,KZqÉçeJôa 8Ÿëí&륈»Î£ă×̉fD»Í́ßÇèPđå.ó{À¨uÚ¹®£¶üF­ÀyÄy¹k9úràiQÖĂxßfơ{äưC/™Î´¬R~¶½¨Đ:) ~P¹῭ƒ¤ æƠÁ‘ơƒÁÖßg—å†i¼è ·Û ÎX¶¶é²1ËUĐH¤ë%•˘BØGw-"lXºđÜĐäñáƯEq áC°íh´œ>̣ÖƒDÇH‘AdRà²T´–|áÚ gß-àĐ"ôăË”oja÷‰.Ë*ù‚˜iwਦ[T´Î+[‚7év›&S2W¦OD£å₫,˜đIGK"RAÉ úKÅ(Ód´i§gT GRÓÈ‘GtO #xĐm=ü $-KÁ»Ưö#&RˆU›hk¬É­[ऑáq9 ‘×a±É%@éÊ2Xm¸§ xÁ&4çđéÇ«ßlÆ–F¯~s?ÛözáOÁ.ü”jZ x˜e•·IZ&ËƯ?EeÛ¸Ç Đ9]ÆmT>yQ úH¯‡±ơ•†¡~Ißâ¤.đ“4á!zϵV?•iÖÑ÷¢L3Sß{q¹âµÈ•đê |ná¨&|>¹FßÀÍ£A›ƯGÀ:µ́®ăhe›¯å¯…¨ (¢›‡Gº1ËƠ}¦R¨̉’SÅͦ&¥Ágos&X'z6—5å´CºÜJđ-±„T¢üVÍt­%µ°5MfVk3ŸÊ Ü©ô ̣HƠăœh5­dñÛú¾µ’•Ă(7ÔÍEĂ>Ñ:›ñÈæD‚́Ô—Fÿx±Æ. 9ăa‰Y>Nyx’ïù§<&…µ_n=<÷¸BÖÏ‘&ñĂdA’̃ˆ.÷s—Ú;3BLdƒ¶˜à‹† Nạ̈ĐùM;0hz O³›zj“›ê?/s= wÛí}Ï9.¸b˜âà+–fxå.6LpºsŒ ´Q ä$éku… ¶£€ ₫}PF×Q 2E¿¾¾úåơỎ宑֋œÔ‰'¥C×ËpP)[ÇÏz¡¤Æ_/½Â ׃o÷¸*Á‡aŒèø˜ÙÅă¦s±è_NÇZ¯üÀø ÚOr|_0«¸éˆºë†¨3[$M6¯#8›ÍœÆÁïÁ=#Ú}pÿăP‰ó|[Ü|c£d8§gÈf Í’H!‘’mÆ}à}ßƯRk.z¦Ö¬Đ<ˆ(úÜ}Đ,$z'œĂ,öUÜ‹|Æv_ ùóVÄ5$· ¤eGi½Ñí®™;ụ̂Ḿ+%<¸ùKe3Æ(Â¥æ̣̉ºa©3œd!ăD9UV¦Ÿ4’Yh?û¡æíóê–uÑ3kÅ2¤Yùoá•ç ªéÖ^ÈăR‰¥Í‚CB|{9«ª™†Áࡱü)4\u%̀£[¸Hª%² ăèÇÏo__½~{ù‘”lÓ>cÎöZz;GÏ»÷»ƠææƠ0&`¶óÉåH¦-6RÂJ¦Ö.Fåi Qz‚Ä1µI”*”‰S…’‘*Ñ*V[Å¢8̀`¼©cƯSèii|ä¼S“#p‰;Ç1 Œ´bˆ€/Vy”•©].z.ÛÜrè-zæĐÓÖ“¸(ü“—`eCY×|x†ï=Ö7X,ïSÄCI,W7¡ëcqB₫Öv™¶˜º–6 ¶ñ¶²›̉3Ü—=û~ûd™̣Ă\]]Ù¡̃‡Ä놼h{ê´€(]’ßD.„?æiŒâ(ÁvȾLB¹%;ê™TÊI°6Y7m¾M1Û)LaÔßb.Sr¥—ÂŒHÜ^&à‘k₫-« ¤¥¯©¾!*¸A;¡ˆƯtÊêf# ©Pg k”Ød®ü„$ZĐBeœ!Ch§2(]*ƒ̣¦2€Üˆ*ƒ:zÆT®nUíûư« BùĐú¨ ÏCâÎu•×#ô…[Z¢£YUÆÖuô¿ÊÂ5ûŒOMÊBú”NeåÚ”E5́4Eè_S@t¸…²8GR̀¸½¾ Ô=© B˫֣|dÅA"́GƠªOÏY”1VŒ£C€ø©àw?Eâwˆ €…:aæe¡ªî­­ Đ̃A₫Ự́nhï®I"¤ĐazÅà êBi²w½+‰ƒ€¦wQˆéÍÈ5x†äW†ó(Ûà<ˆù…¾MZ”N…Bµ­wôH¾t — Ácź¼¾ª˜gĂ©(Uư¨A\̀Đ³KzR¸¦›¯@¶¯Ë½4a½ 2¢fRÊm£› A@ƒmpƒĂYŸÜĐGnùwzæß]=×NªÓJÉiG3ôi— qÈâ[^ C~¸À† Ƈ(MöQµ{đ§4¿ ̣°jäùh̃Qs½f§1¼”/ú+¹æ1 X£ ñÔh,„Q̃i/TCb²¸0ôe/ĐÛ`·´¿2fg*PẤJÈ›‘äèü–^°³W]´üăê-Γ̉¢A“0Uéåx‡í[ˆ£ #|Ë×É5W€á¯¨\‘j*̣˜ØmCª¹Z—,®ơ»nÜ;ƯƯüó]}2ÑvG_\øn¿¥/î ÿqO¿{å«û§¨ *Á¨ö‹ư“oÈ]zFiqÓŸ́Ï_n ̃’½¹íª?oDĐPJäOÛ¹%Z̉±©rÁ²̃HOÜ™|–GI¹ÖÁôh)Ç&jÀ'ơzÂ"Èäë §uúƯ ÜàR‡Ш“,I.¤éŸ×9¾èZRIצÊ¢®ưÎc̣èA‡Ơ)çñg₫r`zư«¥ örX,:§₫YĉĐHœ¼F<#°iÔ3²6„<ÇDkl€¿ÖQjl¡äØNÍ Đ’ø±»T%/ ·–fƯ¢wŸáW—`â¥Ùơ ø©Ë™Á0!uưiÜ~J !ªVí¥¡y!G>BÆ¿¯üm„|¨@ȧŸ?^¾₫åÑàA 7‹Ù½¨ÍîÊœ6Ă¥n å‚1ù‡Ïỗ@¤êÖY+Äf®Øṣ*Ÿhr§ü J3yBR¶ªt·‰VêÎ'iÈ·ÁêB‡ƒÔâơmÅ„?<-9x»{¹aÜrïờ1¢Dv:ƒör¿¸¦O1|kªFa!M´‡#uc˾ÎB5 "¶Û.‰xG‹"JÈ£,bÇF|Ïüx̉¨úH{qDë ëƯz{…™¹¡ÍơD›¹âƒlø4_r…(±ÅöÙ©tƒ\ñ́ %¾pÏüíáë‰Ù́O÷̀l¹SÜ3f¸¨g ÎH‹•r\[)̀E9l­đ Z-”ˆ'uˉ¾búßñç^á‘.ù—x›ÅÄH:ỔFâƯ]₫5Ä ‘››¹zj́ÍN“T<²n|îqdv§›ÿGn8GĂpX;ïưk,øáâOçz™®°5}?V›áÓ¶₫<ˆ‹qCM.:đ³|<•RÆ+‡'ĂŸ/°G?FÅ¢:]ä}S`-“}€Úø>OkĐi<ƒ÷P¢ăc÷<É ́±µÇuˆÎ}Ñ÷öØr;|Đ8y7ç`m÷Cûƒ=2tƯ ®†A\Ùº}êñÈûª/ß¾s¨Çz ‘…~Z³À]a÷̣èÇg@x̃µß7.èèYù1àΧèúÆAÖ!Èă ư熹vÔsÍAÿ=:Àă‘+ø™9c<ăI-”̀™®d Êt†! Q/7¸ô „æ̃1ôni仕ư"Æû(çÍœƠ!é¿öÍëÇöÈ>9ܨhTó˜Ñïÿ̀ïé*ÉÉUiÚGø»¡ËơD—óśß&öe¦ƒSe\ç/ú‹}WP:[₫ wŸMư‡l·"ü„߃!§édI Û Ô¾¥åçwQk5ÈKg̉” ˆ &̉i—Ë››~± ơp₫‘U—|_ÁB…×{XƯb¤Ê” Qi ¡áM"gÀ{è¾ṃS¹̣(Jû@ K¦< ̉C²®é̀:Ú:1h_oĐBŸp¢‘âÚa¥ÈYo§€–n(|Ë(|RôeË)³`¤rN»à₫^¥IHœp”ë4'(ÑIZV•È̉ àk¼WÛ̉ÏÀ$ç6¼Ñ%½Ơ&e~Ø „†ö»”Â×.…\†M¯ÿÿ®¦̃·+äöÁ`îr˜ôc£§~œA‹«ñ̀£†Pi{ßÛ|#ă1ùaƒă8Ê~20æÎ'¿¥zß²'zß“Ùè4#áh$ˆ'n…ăÁU•]AÀ—:Ç ¥ ÀST¶{d± ÊƠÂѪ!›I៸ ô$WcàºqV¢÷Sª,³ Êí"¼?ˆf„l¼¨™X­Ư:Æ•ü.•ÚơqgÈWüÊ1ûI™Ö8­yIiRƒåTGrB×÷’_wÊ~_́¡Ă :>œ Óă Ï'h~´œ 96µK¶ ¶› W\YƒwƯƠÏFÆ̃Ơ /,vGµ{ø .ưmR­?ƒöL5j|aͱ€fU¬‘ñ\;Ud[ôúùw˜áÓy¦“°Ùk{¬ÙQF©§­Iàå(Áw€_~ƒK„¿FE úEœøó+X w@fè}ß\Æ'³'ÎSØq½¶Pn«Ë«cn¡Ô%ÄpN稖&₫¹&@Uö¶­µmÜÉi_̉i*Ïû6üÁÁkÓÔV»â½ö>B$LÉ¥ºq°öüCƠ[‰b_ ¼».̉—x†~+0Yr0*Pw‹ËM’ù…#Öá§,Ô} ˜DÁ¨̣£îE¼¨{AÍ£ºg4GU÷÷kDuïz[¤‰c¨zN₫T½}Xà(#4p ¼ªú{¸æưKÖơ}ô¸’ï²'’ï¨z\ ŸJü°ÀE?>898=8³Đ°RơʹU½₫‘ŃÁG uº¤k´K*·ZK2æÓùĨ† U {PfvÜ'¹ï+~ZÖyÅÓ‡RÄöØw5T ÉÑ‹ öƒ§‘̣§|GM +!b>ªP‰a—nH`ËÇD3Ê(ÊÛgÏ (W$1k*Wá膶Z›bO…́êEذø6Œ”?aC)lB®7¿~ßóŸ́Ʀ›  pÄ+BÇÀ§¢¨Öâ+æPy!p×ânHDˈ:cjqi)צ*î´…WHξ7u—®(D5é|ùÓºU>Ÿ€mJ¿b†•̃ç«Đ£â[ƒ¬J ´f$§^̣¢?Eo|¨OÀŸöd$ÇT"•Ơ¸7OIî’[bÄÊ“SƯiû1Æø ă¿OÅÉcé+‘ €¤´çéÍ=çê½f¢ÅßK€-Áø}”¬ÜѲ'ÜјJVYip›¹â£ÍÍ…=ôºÚWW—œï.ôVÚ®¨J†1hRÚ*«ºƠ6+Û¦µUÖtvù„TvẠ́Zèâ3¶~M#ÂIG¾đzñPYâåUj!ÜYq{¹^?$̀‚rĂÎ ›ÎƠPàÆ"Ê2è{Ø(¸k̉ ¤¦zÉf74¢eO4¢Ÿ,\vÔ–›»Ñ%–<]K,h&nÀT¸VAă¾ÛĐżÚSEµ¶ Êô^RÚÉ0W⦤.hƒÄQM7PR vöi{±X=:],î>¼̉ ûuÇé¹J½»£•t£úE×ñ3ˆåh˜\O "ºI*7mL;R† ¯T­îÓÅÀ/p’³è˜Äe®‘ƒÍ½8è7âVô0éZkư¢ Ê]¡P øe[Æ1ÖH_Äû”æü)‰% }ëLjLUöÂb½ "båÂßpÏQ£DAäQ ê±ro‹̣Ó¹‹+ÜÁÖH™¿B»k••»  ö†‰‚8ÑT0·µézÍ₫̉ŒHä?Đ3ÚÊo[§ ¿m=áÏđ­Fñ, Ăæ–ªo©­ '›3" ¡¢ÏN¡÷g:G+!.ù‰ qÖe­Ní‚kmb8Ê‹!zÖ‘¥D*êË¡r&±ö XËÔáfă0 ’æ°¶°"ÏQUÁÎ’¤¤‡[“”/‹¨¬J–4x/{’V±·)],>₫ơF„~e ¨À±%0ˆ…¸Ä«’m̃AéƯ%̃ö1 ƯPÂm°́L¢cW .C?ºfDĉ H-A÷jHA´iÅè½FN÷»àNôÿæ.JÖé³₫¹KK®úÉßÏßvW3Ư[$Ư>~£LQHûpúRJ₫<¾$ưÅ(ûƠΔ"uÓ¸gn1#ú‘ƠuƶªWDKâ°_=v•:~B RIĂaµPÁv*!«^) S=@¶—đtđ0pëyï˜TÙQêŸT́V+\ë]ßÓ/yå"AÁ?–¸çđüµ-p|‹‹Ft}P ]””gTr{“›ÖÉBs« !q¢“‘̣';Y’‹qö%½q†g£0ˆF×Ä 5Ö™Ä#É:!’.Ă„¤lÄñ‚VóTpå·¤ë”ü~ohĐ!ºB]°ë£2æ]?1ê£`àçoYḤ‘$`1,I%>tùªât©)L >¹DqÇIâp“W2±A4¶ÊÅOÔMư!ÍÉ&Uª“·Ó,H09É.ö̃á¯å ô2àúôárŸ Å|ÿj?Ù‡ z¯öüµÜ¿øôáø5A n4ƯJUÚ(Á¶|‹!á–ÂÏs…dÆHf9¾k›̀“gUç´‰ß2™8—]Ó˜ è­°BsÇhî2i*AôCr]d?¢¿I₫ùÍç7iR„ʨŒñ«ư+"*Ó5Z‰7„²øyÁ«Ơ¿Kä.A¼:́©KÏ₫yDjñS,2¢›#m@kc(üÅÑ́ 1Á Ó|×h4Nù#;¦L)ªÀvBm£$–é &U]T`„ \¾½úØF÷íƠÇA¤?^}j#ưñê“;if̣7Pî\U9nÍÑS$SiêôUKµv±øÆNém܆Ít(ÆV™ị̂ØƯÁ![¹F‚Ă7t d‡€Ü·í̀ơæˆa8ߺ́ÑZ¸á1²©… öO„ß (*7 2Çç¨Xb׋ ä´øơ§7——Ü‘¿ ’(ÛÅđ¶ÏNÚ ¸éxpS%]ºó¥C¨ ?÷¤ççÀr?øÜÀ‘FA#!u@Ñ+ñ@E‘ ¸™6îuBä@ŸíV+2^½(¿R¶ñt DOBV9ưwÂ~Çkú/zÆâpWoxappêZ¼ÆåÆ :OÂâø¸ŸGÀÉ0/†¥‡!`ö£!"kû ơ«C#J»›Á ×F7l r̉)Ö¡’̀"5ï`è”ߺHlÁŸ) ÍÓ\(„v¦ëÀç–kTƒø|ö=̣™âŸ¸3º%ô]2:*Œ)2€®ô±2ÜpÅ{â ¡)ø!"!¾VRïå4f†ˆvø<9˜?ËÓÛ(Ä䈲6±IUm&{À¬„Üøg±µ€P8@2VÈÛFƇ½T³+™™ß†jf¾? å¬#&*Ááê™wd‚¦Dü$văÄæă—Áñ œËØË>îˆ ưªœdMûămWaó³Ù¬§8”xgˆä³;Èx¶ư2ơiW3ºL4±'‹¨*Fº|uCP;&Æ€…黸¶»e*+₫Dx‡øSÆÁ^2Đ½«ïk3½Đ̉|ZKỜˆ£µ q¨c:JçĂ…áđ 8dµô" ©£ñÅ`?óopˆ›X|=e›`‡O£ ú‰ó¸ ÇÅ:¿â•ÿSú[€&|¼¯¢"J"=+nú"ï)v;£q‡ăzÁ₫v˜`™ÿqđZ×yê/qo‹›ol”̀G]tƱÊÑ̉¬_7¤ÂăXrÖ¯”̣¡ºIÆÀYtkr^E¦!ñ›_ë “ṕ»×—W̉_‘ˆ=v¬̣̉¥rxt¢3©ƒC̣ÂaáäÎÉÂyæh‹‹"¸Á2§FµÇ-C¨Ïf:&¯à3Ü"÷lÍ"{ưØä”Öâ)ú&†GXw-®áƠÇ|êBFu|Ăưéƒwă±â©ï¨KX’ë̉CƠ¡äßqOÈ¿Fuˆ̀úPúZöN8øpJĐàÏÀ¡œƯZmñ=€{â;-T/+¢>ë̉!Jç—Ó#Í»¬}ˆ9X+û›Ö$´öQàØ8?<*B²ûÛ‹×ĂGáp£¦  )N@üœ_-ñg–ó¼Âg©nfË̉µFpç;~(|:“k†sW˜̃xÀ{˜ ö¢¿*p…3°æ¯plêÿ] NäûOBư&(µ¯C)ŒƯE®Ơ(8R‚4uv×·*w¹¼ ”¾35}ó] ½¦£¾ÖoøPpR—j:‰’…'è=À¿²3ÙF(K·<Kÿ)́±Â8·m£¤WĐ‹̣ÜqO乯ĐZ%¬¶‡a+_ߵдçMV¾Ô;Xá*SHùQ¿2Á.O*W£'7ú>óBH”G¸9ëZ̉n å«ÍÆt!)®P½×C¹a¦ ĂL³½Ä(˜©¨°mh˜4ß₫!lX§9ÁƯN̉R2‚Ê#4?—HÖ£^*Ă.ÍÀ¨aWDö[‹̀›…¾‡ƒ‘bèÁHáë`„à ¥×ÿ€W†K}"Ma0̣»Nn{ˆ5ƒµfE‘‹\«ñ̀£ÆPi{?NùFÆc̣ĂÇq”ơ¼ÇVcÍ%z¿g+'nPt'E7ÆÙJK[•‰ đÂE¶»¢Ơ9PTœ Óă Ï'h~´œ 9^}zâ(ÁÖíƠ’^˜Û¬UAÏ̃^}lj—l%l7F®¨-îº1jØ…ÀæẮ”8œÅf©|Œ!ÈùØ/‘~ Ü2>b@ÉpªnïĂ¡ {#r”ù^qáèÁá_jiI‹T1đăíƠG²û˜ÏnøS'=ñ§ºN"øuƯ÷ÆOpüo&¡º” Dúô=k?qÅX2|ûp ‡ ’£%&ˆb7>Œô!ø‘̉§{‰Lú>¤¥¡áEú|¼úäOúΧ*}Ø—ºHŸWŸzK7\¸4%}\ad ßî[ú<€Ô±¾²5oÄ”ñteËĂ­*‹Å`™CIFØûĐÓ¼­%ØåÑ1̀Fóđ÷;¾ƒt*z¼¨å~OëÄ ´çäa@{ưÖ‰+ÈAc_Ó’!Ç-tÊR»Ä–”ôđˆ‘LÊA1<\$“l4 «GM—NÏA.eºKäDÖ‘`dP@ !ÜOû}œÑLÖ»¤³(÷á3\ÖsÚ3ơáëÄ ơâ¤'’Ăƒ'¶o?Ÿ”Đ4~h*₫È1ÊAĂù_vñ“hNÑi™̣8Ô“;¿Ûmq­ª"­i)—¯R‚óµ3”æpº7ˆJˆ·8×*Ó́'× ̃,·6\Ù¨u³=·ö1ü¨åÖ₫Sœ̃½¡§”vt:z¿ ̣đ.ÈkÏ‹t]JÏkI¯míW¬Ă ½§ ;ôôĩ56À”`M–í}OÑO¢wß¼¿̉Hц}É:ăôÄ ́®ăhe»̀ßQ#¯'8‹ "ºIpÈO*icú:¿ÏÔªƠæ€JJ>ÍH‡yÎöæ$ë°@ÉIä̃â‘+ª=H×Z몧y¯.¶U!–o†̣ȯâ´À¡±¯M"Nm³H“$‘.đ7l4JïvÛŸÀ*}D1ŒK‹p£¦ûJÄç¼¼È/ÛÚỸÄ_©ƯßÙ‡ù́ạ̀ïG7ªÀŸ¸êc]~Zr˜% K͜ʑ Çöa₫­Àù[²1–h́ œƒdĐç2ßBßM̉”T;Êc¤V²ßỦ&ǘ,)-Ÿ»K ø7›iª¯̃ÛZÍ~ ăºÁà\eHˆơ@,¦˜üA»¤H¨3e<ăú°çJØßm®TR^€ ‡À¶× ÉÅpLR³“cĂû¢ÄÛ^›m7L­“n»•i*˜¡̀´¢b“̃Ơ¿àYAíO–”‚D¦H°₫ùW‚ïU$#…B’`‹ÀÅÅÊfcŒ›'¶»W0-kºfpÄ0MH(yÜkÁ®Càc¿×8øư)‰%¿¹‹’uʦz5[Ù\÷˜|úĂeϤÓWo>˜ÓF«™¨¯̃|hÈƯ‘–$.6¦¡₫À’l₫‘~úÓ‡K9íô9‚ÜߦtӴΠ4Ó0y¥—Î"$J¶~­©¤³è€–è“Ù•“†½fk¾h  \×̣i„ûfæ„뉗å̃i=5ó±J·gNfF´Æ‡•ª# ­¯§*ƠÙ‰Ñ:kÏT²®œ%ơ^'áGç ôY¹ÖÁY´QdQÇ{̉6]4P̣sçêàå)ø üê^…ÀÏîäÇryΪZư[‡§5V¥†q·z.§0®d‰C0Öđ àcBĂđ1¥e@Vñaáç}°vÙ¤|„l$? fư(X€ºä!sÀ ö~Œ'¦(*‹É¼@uơ5`.ÓfMe ái&ROm"S ÁË ®¦3œùöÍôh#’ưÛdëCúY]x,Sma_ˆÑ*ƯfA]G1xËưúúê—×?|¯[‹ăƠM°‹ĂWΩc9§ÆÇ₫¦rNyN˜K‰8ü$S9 €çLº”hw*ƯïvFÊ9Ơ™ƒ×uˆ¼Çmÿ9§üÆn³t†̃c·ç9§–æĐmËœS1ÅܶƯÀÔOz‚©kaÛĐƯÁi¦ÀƠKĐ _ ùáó‡‹ävEYïË3=f~₫÷—sJuGZØ̃KÔà¤`|ûK/åÇüf)xÆßœ>Ư´FnI‹<§¼dT½ç¼ü†Æa¬ôR8•=n-¹ë=78û“Èđ}ỡăßSrÅ̀7pæ1̉II‡QZåéGTî*ÅKæ(/N’¦güMîCg‚C+ÇœE~÷¨„äø7‹8mgï9£:÷¦]9£²ÈĐđÔ ₫´'¬¸à˜-¡(O^ªp„#¦’.!œ ºÂе—éØ%W¢=L"]}Á=P̣¢²en[°BJ;=±éV€f–¥±¢Z#E/ÛĐ(Œ,#…1̃D7›ú%x§ẃWÏ~n‚ÂÀÖI(ØƯC¢’pxƒë]¤×¾¤wöH‚ÖÙ?3R]±&M¯‹X¯n–Ø_'q½_uêÁ ©¾ßÜm46gLĂÑö,đƠÂÜMGO™‹₫2¿ÿ}ؤ:Ç€‚̃ H­đ´́ñ PpÊÇÜÙopê–œá´gr†ó—Û{N]ó-ôưöN¿÷x₫g«´ çrZNê.ë½äQđâ&P¡ç½û ¾Ü₫!pư~Ư *mï₫…od<¼äQ0ûẒ(¸ùÜ(œöL Pé‡!₫†?̉&X{KÎyKº|ă>½%~l¯‰H-đ`̃â“÷hÓƒ̉ËÁà oMƒQáéa˘ûxëÀ‚3T¿¢ănƯyĂ@ơ²—ç'¯ăo6Ÿîi¶ÛYµyÓ9̣Yơ©ªüiOTyÏgƠ=v–®Øñ†/|Ä3gơ’Ỵœ×%¿Đ6P‰N –C‚’'@fFï@Pz¹¿ÔÛ„#ɤ»|8³Ä:;ÑỊ±]cnđó§=áçû)™Ơèí0Aå 3ß÷›]`rç@?¹úkqŸơLV#ääÆÀ•²è¡0{ÅvÚʃP} ¶' eO¸Ÿ,z(ôƯÇdócïRÎZ!îd3鄵{êƠ~Úª]ch pW:Â?hß½\£t ¦ZN.ÈaÆÛ „øöXvÈ7Ç-p½Om7Ña8ßI)Ñ7™{¥—¹^ĐyŸ~]rŸ¼@ÜENæ™5?F%âß }x„'¨U¾ ç˜Ẁü¾3Ũzm 9«9T{ºE" 7b[ÖA¶r55ÀÇ5a‹:(%‘V)0Âd¤ Ö» RŸxßß́Ë‹LGÀ½R…bƯâœÆ55wÆàTQ],ŒÀ9ª _̀¦ L| Q(“̣bV‡fÈçáx$ñ͵/4Y–DSËt«c˜ÙZG1hêb•GY™æ½̀ 7HÿÓ₫Coí´’+ºáĂ„#ƯĂÚ¶\›/€i²\ÙĂăÓTJ₫Öunv&9nL:/*×'ZÏăPÖH!ûN7µt®D ø£¨‰œ7ÆÁ-·đ{É 7d̉Óđ›~dF ŸáÜ\ó8xYâmV $w¾Ù¹LJ|ƒí«$®0¥>1»‘̀F=ƒ₫IÅ`Ï­wq|O¿(j4–¯%ÿX¢cDfzøk[àø4$gXP ]””g#uxr+‚ÎB^¡ §ÎR`z8ÔHù™UÅñ9IWÎçáG‚]ÑƠù^ă›I*÷»8 †ÉF7¨†Ó°ăÈFiO ?&B’=₫\c‘›‚å$éÍ+!é\Q ́ú-KIöŒ²Ă²˜T¢A—$$§% ‡!IM"ç§ñ%êzLBF?b³àórüØLѳ´;ô% ó°×¡dæt$Éè~0ÙÆ̀¡"’ µ2t¼p̉KŒºƯü?íyó1ªf: ̉̃[^WPÓ¬„)›JM2•JRr*ê ¨¾v¾?zư›8"d;ñêi¡¤ú—]ơ.ÿ@¦ï6®~~ˆj ¹‹́DûöY6æ¾\e0÷å*ës/HÇ»bÓsO(CWÂä8­ ë^P'¥\›H‰hjC½mĐb.Ộkä{愳!M‹¸¯ëŸj¤{¢ë ÂHø„r_(|NZO2p®̉í—d€¥NI™ă‡“»]2~‰8¶å— ụ«\eûå*ëx/ŸªÀÏNQÀËS¾À¯.~đ̉,M"­P̣<ƯuØ—ÂOÓFô#ù+£ưkÂÓ¸7Jpÿ’Lí¯©·́îß;Gÿø·÷o/cpÿ`m<Ü¿ª°mfóƠơø€ÉLÛ4—1à†OeBªûåƒà;SëhÀÜ ñ­ÓÜå đ HǧøăêÑÔgÄÆtÉøW1Å?§»]Sß(§©¥=€Ơæ ø?AAâ1(W» ‰®wë5΋£37,±³Xb‚Chʵ$é^è}#ß¿ „a²2y°Å%Î!4æVÄ䤱6§ÉĂû'{ÔÑF̉+̉¨oLsDK1¡»(ÁÇD‡}\Ig®8G.º^C¬Rq¨ask£‰ê˜îyªcÖƒÁ:™Đñt-±¢×oÄ9"Kv [dOå¨wÅ÷™|á• ÊpḄ¢’ªt·‰VºîÈƠömđ…Æm©yå«ÀåkŒûxÅÏÜpmÎzb».ZzÅ«̣Ô+̃KÔ¸Ö> DSÂUɱ4º°an.i³¬Kæư(nxËJÈ£ÀaÇ”8ÜøH"§úB{™£(ù^ÂĂ ôä¬'èɃ W¸ĂG DŒ*;́’Î%¸́Ê©=@^øÊèÇñEóà=1¿×Éhö~Ñ́€ưœ_O:; ~c³>NPÓÉ̀€ÂÛ´F(‘é‘—Uˆͻ/ƒ>¤? é₫>Ạ̈ÆänéPÿ Pḯnđ¯Ó|»¹íÓ®€Ri¦û y¬N§[₫gn`$gĂÀH »·üµÿáâOÏz® $†/­à9W› VdDX°Î¨²ËîNÈüPB¸¬~È-_©MOü¥6]>1È‘GNmºô‹Àˆ¯dfM§èÔ®0~₫°'9ă¤6]zÎ-F‰zßa|÷©M—~ØQï x¿÷Ô¦̃€ÚƯíT74ª³ahTF;µ7Pûf6=s…·êË4̃ª#?©|đ[ÈfªÅ=ÚØÛg¨!r€Áí/©“›Áhv;Ûÿ­v:ïÓ™₫Ça¬t¦-ת{Cĺk;7H¯³@I}µƯ£§3=s…2pæ eå°wµrôhxwâ%Ÿ©—£ ´è8üó™:ôrfxÎgºß=ö°ùL{GÈgº0‡6ç3…€¾₫ùEÎÜ@•Îz‚* =j÷_ÄN¾»‚1̣Ư¦Md7‘ÆTPÖ óCT»h宣<%Nôr4JA“Æßñ|C‰ưnf(Íñ·2ßKâÄÎ #÷ÇÏ*ÿ¹ß²¿„/pÎäqă.u^;ë ¼öxîRuÿé¾³tÅ`ë˲géxîK«d˜ Âçºe1@ƒ{I‡ée—©f4Üpû~ó/I»èùœFÜûơ/1-ǹ5§ÄtܲºáÖu±ư’OéîˆßuŸeôô“Ơ•Kë4‹9̃¦%̃¤Ein‹–EPØS»pĐº]Ô> Iand®…(aóÅ ư…;¦s´ÅAR `]>=̀ÖUÇîY#Ï\a «whÖHæ̉Óa€;W‘†àzËéÅ•Á NÇw ÷>5|‡·¿’ت)lÖơ1‰ ,—ơđ`a•’¿Eư­f±­RCŒtQ#ÉWâ˜åÖ}ăæ–x₫À`‰₫SÜZîȘÑ%h[ hÂhMS•”ïl'¦ï%ü\±û|y½Î±z]¸ë‘t³«–₫­C×s’ÜZN‰|‚ä̀/–BY´àC. b₫D3#9¦Å%VĂHBÔƒ¨”¸à×a©P s¯>®K¿ƒ3Œù†À…=8–à;ØJ̃àá¯QAözââ¶J 6‡\£?{rüÏ.Êb†®ê¡h̉%8"µ£8xpZ½è,x̃Xp½XÓbïj»p…AMÑ{ÍÁ{vªÍµĐÀƦh[ơ›•Ǜm:á^!¾ttwóh<29ÜwÛpÅÖ#ĐïUéÉ,•‡h>”?…ö4Ó¿KàF̉‚®±}5¾ơÍḿ¾ipC³:ï ̀4p¬Û¬)Uæ 7A…p×¥¡ô„ ô5oa¢ơ®øV6v¥1“ù æ„g™mߢùÍB/€ù A‹LAh>Bf{€GĂÀéñCë·87ư{Ókv|tÿ®ëü›úKu<9›ÍúG†p8rŒđkPÆÁµÀrA(YFOyëBA…¾{ơó :'ÉÙÖ5Æ E.åú­ uW$»6‘e8°JTÅ%§ ̉yO@¥j8Ùatu%ÍQ”t>~vØBØu† )z/Æå“́ ’²¡é—(M´ăBëh_ùôhØùi·ÁûFœg‘ƒ:Hˆö…¿ËĐ9fËüÍ­ôOr]Æ3÷RT®¨U†éG× É"Å´PàáH¼®‡6y¥ŒtR«B‚¬èoÈƯW«$Áí4 ï“ïØ{‡¿–r¾{¨ø ç·8W2B',£|‚¿–ûơN o&èCo£tWè„ó²Ëd3F6Ëñ-%«¤”'ÄËd²\ÏL?bâË\©±wŒà.“T’( ÑÉu‘ưˆ₫VÑüôó›Ïỏ¤$•QăWûWÄTpyñ†P?/x úw‰Ü%ÈmA‡ư"u‰Dß¿ H-~™Œ ́æHW}(…+L‰9¹{@_˜&µJ¢qZÙỤ̀¼¢†ÅNÛ(ùÿÛû̉¦¶±mÑïú»øp^ReH€ î>TB̉¾—Lçt½ºƠ%[ÛX/²ä«Ú÷׿ZĂ4x̉vNI°-­½ö´æÁßO£Ñ̃zM¹‰¡`Ö( Ç₫}ËŒ§~è¦Q₫ôæÚvÓ‹¯*^Ú¬+¸…µØµ‡<ª’{vÖ¤Øeư¸jˆ{­[”:Ï¿©aó.́ÖIao«Fظ?»5@¹Éư»ª!Vơ5§Çrp̃£ĐH?´Üí|ÅQ^­æ /9áµ’!Wá×D˨ØN£é*À ê@-R$*ÉHW>OëXK,E‹NƒªÔ„Ú†Å:g¼â¤!mnÉêÚµ˜‚®_éƯµt+bÁéíY¿¯úMƯĐŸeß̃DñªWàđCƒ‡Å¹,ê0¤Ö^¡åX»É£tÂnÜĐ£tÉj@ù-ÿ,C·6@D`h<«„S8 e@áÇ&%ƪX¡Ÿålm´ ë0£˜›Cóç`̀jÎ Ö(__^©‡A{EƯ]Ùb(ÓGĐĐ_cpöÛ·›iCuk<®8uk¤£Y‡ư¢ḲƯ:|ø¨‚“Ø×”ó2[¸¶Ø¼uUü“4³!™ºĐ]̃kơ¼o¹a]¹cËÚ+7½¯µ̉-÷ư! ËÓwt¥©}pƒ¥^ƯYÔô*6<› îp×âdI£^ÉĂ›ÖïSë$ö•]2&4₫|đGRóå₫§ëy~±q#8Ö¡ơ©ïIŒ­+ò(mEÏ ɆỈ@‚œƯï™̀‚CI†åZ¶rÍhëÖB\±–u9t"cŸrDºg̉ë•ă?<8®`ѵ‹̣ÇoZ¿•F/X ½û5O__Y_jˆo—W#Èî[û=y~{‘»(Ó¿”//ÓŸS7Ú¨WùđẶÚi«VoưØÜ[øÈ“îÿP·°ÜÅù‘ ÷Cu÷lmÍä›Ăƒ7Ö¯ä_ q=ÿ7íƠóÿĐ9ƠƯ¡z₫ ªf5©(ÿ}}¶±¢|Ơo¹éÁܲ¦Ø;\Ï@]×óÿP¯°à‡ nXÏÿ2›~„ÈÈS•S₫TƠư?Ô­&¸é>uuÿ‚W|ÿ¶Zìà[)÷ßæZ(̃º»#ÅåƠ”oWË-o]ßƯ‘i§ÜÿjƠwa¹ÿÚªïáëzơ©đ½¿Ë₫Sˆê›f®Ë²6+ûY«́Î@¿vEü»DÆŸÜÔ]>^–H*YÓ|ÀÁv—à·n̉†²Èª»ÔB~cÈî̃$±ñáÁ» Tå/ăĐ¼6+f ÎCë̃¼µeákU}o×¥Ë@—»tèMè¦6ÿjopǵù_׫û„ï5S¢™‘ưpEú­%Ư˜—-_Ô'(Ó?̉™)+Đ{#¬‘2©7L›T`ZI$`OWĂ?çZ+‘R½±­ỦÍ ¶[&e”Ϫù{g·̉³Ùuë=ëœÔu_׫†ïuY÷¹YêvQ¾\»ˆ̣ ½"Ê^zrƒØ “±Œ?ÉÀç Œ¢@ºX?A†”ø ÏO¨ø**ä÷ho÷Q́§“)•y0"e …!•̣çNëÚT»n­gëđǹưתvL7«fÍçr0Ä•Ÿí—66ï¼mf̃Yë›[’¶Ê@Wß„2Đ¹a‹—dưbĐfeñăëƠµœÅ‹›/Ÿ*:W]ÓY¼…nŸ°̀si\æ¹äek¹̉³5Ä7ÇÛ _ÅävÛrQôd,ôäÅ 3è;°J¥e¶½,pæk^l½Âœó´.üåd¶ mH̀ßQÄi½Ÿ0{×*0]]‹»I?'âo–Á÷iÄû|>ÿƯ§ªÄûEYưgåÜÚrÿ™Î³ư;ƒßl¥ÖA¹=V…52ø ˆ¦üê\5̀àOL ~z±y¿…Àª ~²F¿5Ẹ̀ ~bă ~k€ü<ÂæüÖË3øy„3ø­Veđó«2ø“rÊàOtá‘3øWåƠ–ª£|ÿ’^Ëq² ¿¶3ø[É1¬üS}ă₫6$•·™.¾ üºÅ ₫a¶Û°ØOŸÁ¿4wY?Ư϶3ø_׫ä‹ï5ÈáÏÍæï₫­Êá·ÎÄÆ¦Ÿå§b;³øK2̃:¼ø¨‚7Èâ/ăĐ<‹ÿ¸Å,₫åEw, ºVÂs»=?ẹ̀jC;¶¬meñ·[wˆ./5´£+Ư8‹u=¡\?síÚYü‡¯ë•ÆÆ÷ZÉăçüyüÖZǹ¥—¯æÖf̣́$ë°éă 6];“¿8~ÓL₫÷­ẹwĐöô™üÊ S3‡¼Ư®êr¹´“™üö"w‘É¿TjZÉŸS7‹»¨WßÛP§µ×oư\₫Ü[øÈ“ạ̊[‹³1ÛX¾-aóÉë¬~» ³{ñmW¿“l₫Ơ™]gó¾®Wßk˜Ï›“™v;­ßZÇ%• Ẉ©û Ị̂u˜ưÛjq¤1¯o%±¿E¶Ư:MÜ‘4̣FÙăí*½à­«¿;²#í$ö¯Ö„&ö7Đ„ë•MÅ÷₫ѧĐíwÍ"¿—±¢§H́ÏÙ́Ÿ"±¿̃€[ŸØ_·lÔBb¿±kwoX7±ÿ(ŸØŸ Ék*³´–Øß…‚S »7omNy­”ñvưé ´A÷]ß„nû—úâŸ&±¿^]^|¯™6½2½“yưuËù®ZÓ'ÈëOt¾ÊJ₫ó̃#käơ+À óú˜Ṿú“|FG5Qk1{<ç–Z+{\½±­yưfÛÍëg¸O–×ÿ,;Ó|ƯÛơT¸Ë½;¶îʺđ¼¥̀Ê®[ơ¼¥ꕼÅ÷¶¯4ÂĐ½¿ë"TÖEè¸HAỬ¿«̉À¶eÔ,RP̣X£HửƦª÷ÍLUË ¹%i«HÁ™ Î̀!Ëî½Ê–í@ÎŒ‹T¶`aª?å—Ê ( `­Â¬ªü@ ̃ÊkfÈ-uư fe¹RwJëÅH¬µJ¢j•Êßơ₫®Ïđ|ơZ«œ°°Âæuྭ¨›@WrY½„Ûr&s¹^­Îj₫»^¢ ̀UO8¥ª+˜é2°M**,>oMê+d̃ŒÎ^.*¦y³WôÄùúô² yĂj 9À(/*— ¡ăSu‡ tEôôXA€ƒ-ª–€àá:€g±¦ăEU4=Rx©Äûè HhÀå̉? /­ê°t±²Æ‡<ÜÍjj( )kĂ©9q ñálVCaϘ hézẽlï$ófK~GøD!àÉ?—’ơ¼'§=­zV>-[=ơ4‹hôBªd¸åïđºÀÇâz4®íQ £«MÓÇV!‹ºnî-Ü(ea´Ó¢…a=K4̃À§˜ØÓ‡m[ë±Â™v&(w°^ ´ÜưyÖ½Îi>ẽà0·•₫̃JƠ~Γ]^SfDz‡ke ·[J†.¯³cËÚVú{»Í èn;º̉MÓß—wf,¤¿g̃¬AâûaÍK‡Ë»Â,M|ÍÑ₫²Ưk7ÖY±„uăï2oÖE´]…‚»>.ó`̉{2bÆ 17F8-V¤!xË‹z¬ô/%Ul6h@¯P¯ªÉpơüVyc Éî ]¾xœø£ ]9Œ‰ºß©Đx̃_i¥×ÂO­ơZè̃¤óĽjzŒƠb´Ưe¡{sÎÓvYĐËÛE…Ơ |ªû+@X`z’‡5K/­‚ØË>×yï)º*Ö®U¼bi~Ø® œäÔ%³ZÛqøZ”r¸êó«–Ú'´‘@EÑ»HØ¡ö í$˜[ææÙJ„^©ÖWË@»Ü>aµ<ѽ9µfÍêåkÚœúLMk×)̃tư´iB.Oz~X40ôVz$´¢€jÊ·Îvv¤"£Büír đÖYÑ́H;=VsŸê uµÙ¥…%Ă®æ4M´ÙFŹ¿YϽ±ơ á-ÛßÍz6„›÷l0‰¦k7Oˆå4Jå$JÖèŸ@Ï x¸¥q¡4ÜÚăb¹C¦[̃'â°vqíT¥iŸ¶ĂwioYßó|˜¯ÑÔóÜZCˆVl.\:¿{­tk{Ôj5Đnh"ƯBßÿs6„I 5ư(<]QtƯzôÚÔ¯µ±íF0Đ- &ØíNí†;rxBëá?Đ.uq?klüEP:!©Y ~Ñ™}¦’›»ä»`K—Eœ ¡ËÛ„D†P=ºª‰L–H[ç—Vf îoÔ0`Ö.é¾â8t5ƒµב}AïY5+„ÖD EÍ…Ù̀›=QcơXMÄñÙơIøft‘§Ü"7ˆOÓ+¦ĂE¬HB‡k¾º±ÔáR¼v-ïÆÓtÙ…Ưh³í dqlØz†7c­¦3`.ª×næ¨fùµEÂÑ" £rV6VM}̀ƠÎơz##×áÑûƒ×¯ù3̣TQæÛÅ­îUĂ¥zt¼~Ü ¿­lˆ³h„× à×>u‹{æl$yƠ.1·â˜ ÈÔY§LÁ°ªŒ~|c‹ù‡fóƠƯtŒ¦qÓ˜p­*fÀBĂˆtÍÖ)™7[ÙCĺẠ̀XŒñĐF¯[¦,‚`_{ „mo'$*ß+ mù /$OØ›%í¢7 ÊûnGYJÍE6ẂRëë(o„)ȾZ°¡7T,lP­¨`Sec‰xơgóà5CåK3\%î`p.¥ỆpC:H7‘Âc?€ZÉ(ögi´Yáµ£…¶°p£Æ­f1¹£5«®µp³©)Â:û­Đ­Ö¼×»kMÚ»ƠoÅ¥n©"Z¬Ÿ3cZSthEÈÍUXeT&©¸½\ x „J v̉ ú\µóÍ:Ö9Åï„n鱿)n9Ÿ‡Ỗ)ÆèØŃ`K 8”I冕4LS•2˜ÂÅÏ”WŸ_ªU_Å.!&™Â˜jV);Ú°hW;©M ¶¢À ’,ôÊL¡¨YªXe~臩¼—ñ‚êhöö®Ï̉·i"ü±đü1¶€KiåYĂ/ßL¯]|y…h (^…¢^\°$Ă&Qă,æ´^~E–](ÂMÔlQH±×~"§‰ dR Ặ/¹ 9€„Çî¼5b­{%­C¯ß »£̉$[ĐƠÖÀÚ#Ü ²KµBß”Hl „ÔZ…v é9èOăâØLÈkus-₫R/12^ å#ØKîe*ä_~‚[Ó¤ØôíĐ‹ÈẠ̊2™¤É”Ă!­|Q¤è~ø*@r#®Y³öÑцE|ºáEg­^ÉØ”[¢ª̉ể5_íªá+ôת¨ïü¬sÍ_Ø\ßSTu}<“Íc…UZƠƯÜ6M·ÀÜ67ưI˜Ök2¶bJ  Úcj²ơ$ä6܈Ü6®ZÆ ëF˜–Ömƈ'ôă6Q+j–ÇY”¦ü´̉’P÷ơr e±¦p~yÄ™ÂC̉‡ú€ù9«‘ GmCY»¨̣ ứn…–ÈEâ ÷¥ghF‘ü-+³¼‚†‹ˆ`“^äØD|Ẵă·_Ï–uÇ÷_Ø“zq̣R;í¿{‘[¨ÅçtíèÎïkôW¯7í1Nç¨aOqđ8bVÆ( Ç₫}˯Yú#7I—ô‡·^•ߨ¬ry茧ËÅKºçÇ6¯Ô¼Üôü¸<\Æçf€̃̃o*†¨ÓßÛ Rêñư¶bˆÍÛ]›ʽ¾ßUŒP£ß·¢Øóû}₫Æ}¿5đ̉úüT†̃`y’¥ưÊúÆ=Â5đrŸpØd­ñƯÀ…Ÿ–´é!éá?ZnϽŒ"­ṼäÛu/"Tµ²×–bÖDơ¨‚×\ÿ(CE ÿñäfq?{£Ù2’/–ơ’m’ Ÿ óÛL%Yo)[4Ö­3à •̣Û=nd;Ó]íâÎß3F0Mà.-ä±IÿA©ÁD6­«‚Ö,Ú·¨VÓ&½‡­É,­D˜S”"U°˜ç'(³ƒ¶©Wă@\é*v~ªzà˜Å²̣c²dS¥³ṿæÍ=‡1©¦›î¥̉ó:|̣h1Ÿ´„ê–¥[+œ̉l§ghàĂ ‘+)¦­¸tå’ñ´,¬EüÍ¢AÜÑ6,7¨fÉ+@ɺƠMYͬ°À†~½N§·gư¾j37uC–º´›ªY÷mQͺu,¥CQạ̈¢6qjy! ‚&°Ç&?Œ̉ Å €óŸT¨J@ùƯÿ,𠀈ÀPjª„SØô2 …fs¤cŨÑÏr–ZÚÀD<4éÿXN/8Ôă¥ùå•zl¼nˆÆ`‡ÊôQÊP¼Æ̀’·o7俵 ¨¯°o9ÿ%̉:÷¸ÄqɮԌÇ̣ø;pï¿m­÷ö₫Ñó«&l²k@뵄\£7÷₫¢§º]9ẹ̀˜[VE°Ư5ưYk¥ÛÍ7e ËSNwt¥©û{ƒ¥^ƯÎÖ´WÜJ†qËùd#£fÅ¿EqZP…ƯtT¿Øt4Yh[í{6KsªJ{Đs`¥BéIœ?2ËRx–âE~çÇ]̃fl¹v­û…mgËk7ó~sđ¦̀˜›4ô.ăĐFSïvسjLư¦ó·©÷sÑ7ơ>ªY³gQǪơkö\…íi{Ơ.­½©ºu½ ^áu(àÛ2¬ßW£8~ó&ß­”ăæ¤Ưg·íR“ï·-ë)t¹²ËkÜz“ï·-«/t¹ụ́Ăn@7M¾ß.U{ênQëØßäûíRÁ«î>´̃néß½É÷̉–MOÓ•æ¸f©ă +HUÔ¨œ­x·ºÓ÷Qíè[]₫m:}ƒ(×Èß•̣u×K´Đơ»™œ`oaéáíîú½ˆR5ëú}ܽr´½ûĐQ×ïăƠNú®K6×,!´ơVÙáó·₫>ª]Äx…}́yZçê×á5ïK¼¦v đüØMÛ€h­ x÷%¾ xƯ½jAÚñ}“‡'oñ]XÜ´ö,mâ°¼¸MV7â5 ¯/O\_¾vë'¹ZïàOßü¸vYÙºăÜ\å7uÍĐÖvgüT®oFKÂß·×)¼{®¶CÂÛåh³{–¶½ªë¬~» ‰æ¶qơ»è¾ÜZđD6Ù%û7,Ù÷cv ?®]loS%₫©;…çr¨×aîªD†¼½•¦á­¨«…&Ë­³øiQƯ¨3u»¢@xë2Á́H;MĂWë¼ ›†×ÖykV½;̃°ê]Æá ôƯFzî¿WópÓ¦V+”¥½`6k~Y«y¸"¿vWí»DÆŸÜÔ]=Z–Hê­‘oú±öHƒ-ïß}\»ă ƒV ư»•!½k£Èú>åĂ×%üÚđ)·ÖÏ»Ë÷IƯBGævú“ÍzµßP¸û0Đ­Ư„méçƯrví>¼t§6¶q?ïå‰uuwi s|¶f—¶¥Ÿ÷Ú¹DƯ‡Ô¬y{¼aÍÛ:¹A?^Oïg æT~z|×®æ»Âtû̀á1V Äu„çr]AS)±i,D, × à6Ë…_Jú©®d;9ííÀj¦m³a„»œoă .`z@§–>P7()·VëpÄ|½w¤…~8 2 `vÅ#´HlÄkà;nP€Û<#CÊ•XÆ÷¹’S3.y3·}b_|2\EñŸåoç"ź·áưê·‰Œ‰ë(Ε–hƒ’"ƒªb‰U¯Á›•#:®]p…Ư·®i‹7P]‡6j̀¸üjÆu¤.ÈÍ4jĂ63«0yĂê‰Zg˜Jck5Ï ËĐa?J5ơv[@Í́Úơ;½  ]w¤ß8ÑÍZÇU½I®́z2ơ’×,µw¼aƒÚë·¯=9è̃xeÜ9)üg=†\̃f;ñ—ÍúÆ_@Sö땽̃«̃úmuƒ÷Âkƒ. Ÿ‡°0…Û‰ E0rà?FQ ¡x9v¸ỂÄMhv ½"$YÚ}mZ»Àß SÁÀ¸Â½[j4ÇYƠÓE?¾±«ñ°™«q­¦—|˜q#aă(¢Gô­fĂÀ=Ñí ÅzƯØ–¨̣%»yÛTÑçêS¶₫m\`‹¹Âmê¦Y’{=Á¯̣¾Q]Êz&C5-(̃EbOxoåt;¡—Ù4|–ßß‚…›¾sáªçuKÙ…xëÂè_â(›åà›"Ư÷đ›"8Øœ0Bgû!«…À‰ÁÔ+f-bæ†sQ*‡o4j§T6Ü*/lôP³×\ u·f¯@=‚gÊTº•îSÔFj³̃S¿ÿ«x¸¤ơ₫¾¼óv*Z̃iê‰üƯa6I+= Ä½ÜßkUw)ưj£̃R|Ju–J†étD)çH36“Â_ÑC›4³±R½°aÇgj‚/µ:.ƒß´u¾ÜXéM₫̉^?ôP±û}»üD¦¼?ïÔÛ.Ư FĩkË–Æ‚P^†Ÿ4ˆấ›·*ÏƠ–”·vg¡Ü©­aư/ߨ"Âh'~†a¾ëÜyoR€â3”I3뱪/ <˜0©V&]X£Å¨ld¨Y ÷xĂº,?-Ơ¼›¶}·\‘¯sJ׉|³ÛH£7ºŒ¢¥»ˆ ¶í*+må&^6Î7¼‘zUV\H°½mxÅ`âÛº^ÄÑÄ0§‘đ§PíYbÿY7ơ‡~à§søáëéàâôc'™2E‰d+r\º"uó`K£7/êÙJº ×ë₫́TQÏ¥w£n¡¼÷?́·_Ôsé½ÙlYº÷ơl7IŒ¶öăơl7sœ€¾k=uüß¼¨ç»ÖÈYŸ¨«Z³ưq³:öU:ĐNUơ<®Ưdă¨&³ƯtÂqs´5êzîD5Ï’án1üMI ¯wU¿…RíHâ\îp “~¶¼”gËàêæè́|)ÏƠư¯ÖËÖpĂf|đMÍúÖoƠ·^‡>9ÏăÚ_VDLu¯À~œu8Ê[̃‹•! ²QD'Ăh! !=U<'û¿Ö@äÇ› ºé¤u1˲^4¡¢u‚ ßÔ,üfĂ*Bf- /¶¶ctü„17GtKí w)úiZÈÉâH›W|xEó~Í_m ^»¬ư ÷ †m!bµB×́3¿¯Œ^³̃h‰àXNàuHÏ;‘ó ¯E€́!“"Z[DÉÀlJ–˜?›;2í#P‡Đ䧺ä W³pƒ!3#–t)\1öègÁX³47#G5ëѾٴ­}ÑÖ,ÏSº›|ßÖ¤8µ‹¯0Vèü“v.₫Ú¾¤÷ễ¯ăB* Đ̉­'`­^z´ou"’,µ–ÏƯ†ÆÛ\xMK䤫ZúRẠ̊®¢3`>̀Y“À}P}7£)5 M¾Ù°Đd;4¥Z- 5Ø¢²Úc Ư1SΫd©~˜Ê{¹ÖÔæMí‚×›*“¶­o¿²Gf’aô×8 ‚9M #€ơÄVjœû,;¹CÄZטØ/Ü8vçmLëÛÿ~R¤s-³_yˆ–ˆ'Ck•z’aäi4ºpCeîÏææ¦ı®å¯jWÈRÖsS2Y³,â› Ë"vI&sW>ô41ÄK߃¥ÊbóƯ×̀Đ¼ÚexW(Đw³(´èF.K/G*êñô¥±›‡Ó·s¤)p|ËNô–„Ó¯>×N¿É±̃̃hú"#_çz¯GÍXú̉ØÍCé_·Kÿ®û̉É»Kÿ®Ư< ´û ©­ 宵-‡GĐ¶rº‰¥×nƯDÚzùâ>–₫ỬÚ‰u÷áíÖ́ĂK¿ ̉æ±ô(IÔ !¬YöùM³²Ï„̣îF̉¿©ƯqdÓ…<’¾díZGSÁëÆÑ—Go!Œ¾%)œc·°zÿ–ÇÑ·̀ưjë́o‡ö¡«8úƠp½8úF °fç7fDmΟ?„₫Mí’ÿ+‚hº¡'¿Ç:¬ä-íΉ1À&ÜA4ç è‰b-ØW´&Aâ§Đ#¶HÄÇÛ]‡ØèåZ+ª^‘’BP}Å…V¨ªÀö™®=¹YPûáÑûƒ×¯MDû’¹ë0z]‡S5Ü`Hx»@O1́8ư:!́öAÁŸW…X/´sƯ7_wđNؾ̀u®[Ñë%`-‘„îc×s̃ß·ÜÚûwù‰×+®¼}È× a*]‹ÏúÚ‹÷Ậº¯}̉›;%°Ú<ç»®mÇ?´sƒÚ Ö.¯íú±ÚÄ5«âé:ºEƯ…K[|·©È W+ûÎPÛ,ă&jL$D@ɉœ&2xI% Kp“V£™‹!7땟„‰³6UiÁ̀RÖ&]ÙÎ@æ\ĐSgd£®á¥bơ6b̃R $^#pXœ¹!<#ưtB„„p(O—¶ßLgYˆ¯µÏOáëTÆø–i‡;›ÉĐóÿª gÑlvƒÍj‰sôëÂZâ:¶º–øhß|Đpu¼o1€xÍF ÷Ă4¼ ¡ly¬đQqËh—¾\̃í‘¡ŒƯ`ÿûǴ_ø#¢̣·ó”Ÿ§âËåà‡=,øáUÔ`Ù0•ÿh͆ÀåÂt®(ư¯Œ¢Ù<öï'ªUîx$h{'¿ËícÇ=qôAüGJqôúơûª+àùÉ,pçxcYøvËqOAÂđ`Wylñ@ă*>ÇRÛhœ>º±Ÿ£,ô\ºôưpt ̀¤²8P+:IÓÙϯ^“ñAß¿Ú;)|AS;ñ< %gĐiƠ₫40:}†Y*ŃŒ‡nêOáG_rÓ ?qÚ(áE#d=1̀R1¸á=Đ2_wms¡ wa‹å ¯•§^hœ"Ư)ö#Q=Sèóê)ê½EqêJT[|^É̉:¥́áZrœ 5Ñq;‰ÚX¤É÷wzqDcñÅß“¼Pȯ&عa ƯF*̀bwm*‚ àWOR¿ø‡û] ÷Ñ‹y”ňM±ëDAÂe'¥•ĐâăÉH́&iÏIWNtƯĐ£cpŸ¹p}¤̀èTüæn.‚ }fîcwú©ç&“_̉HLÿ$‹%œ‰XN]?L€i– ù)v5‰ÿo’ºü-¼jR»dbzƯ£±€©¨~긳Y'úíQq9o ¬¡̉÷=<îÖ8G Ư,DˆăQæŒÜP$ø  à’ñ"$G™3ñm"Cñ(¡‘¡ûpÊ-C~‚IÆÀxP"H#µú=¸KÎ,FB\eñ‚)çÏÈ­:qSÀÏ™€4‚]‚̀a²®¼¹éùmzÁßÓmơ: ̀£L<úÉäeO!b9’₫¼œÅ#éIo`µîeä_tƯ>Z¯Â3ÖÖĂƒx”H1ó到 ¡å#'³è¤%1¸ïaô¨áz(áÁñĂ{ûºFđ~ |p‘'¸%¡¤…ñ́§xF̉c=‚8ƒ3!Àô" ë&ßù'¼¬Íêɘ$/|ê@€‹ý™É8uưijY&Ø ;Âk]¹UéD:æ$E±zxy₫çÏex¨ÙBWÍÔ> \œ£YÏQ,ä_.½¥h$Ùhb¨@Op!T—Z=YÔÛhª”Â2ÙÊBe5#̃Au 8Äq:å¹Dă<ÍôĂÄ÷đôM{ ̉I”ƯOVLƯ0»£4‹e¬Hc!Eq H{ÏÉÎC•ª(û@̣aHÇơ§4GÚđđ>¿5{© èDưœd¤rê¦Đ£â84tdW'²-\Ø8–. *ÊVz₫ƒïen€Ë”%ÀL'₫h‚".úµe0bDbˆŸX…°¶3l€wàX´øQ ©́jG`Ux™Ơ*ĂáB¾Mü¡GÅaiṆ)W‚Âô@€— '¦“û‰Ä–d©¦>/µCbˆ¡°„ØÀï 1ĂUjÆ ’ |u§qH‡ß„5g°Å¥̣åú¢f`n½U‚Y¨‹Æ,Bà‡€dOHP"‡M'±tS ‹5ĐÄ©Ă¹9Œ3•×Zê%teg”ơó¥4öG©¢8蹄%À16’x´œTÈYÏ`Áá¤f©Œ̉IđàOÇM…áz‚¼­ûùdRÅî̉n <8¨1=¬"QÑ#Ó“-l8#œ²?r<†{đ‡ .ƾLƯx'ƯȰi:9ń*É7rC¦1Øø ×CËjÍĂ(„ÈP™×9ø´ âV(±E¡ç§¸ùp(Gd±?6̣=&'#棒:˽ZYœß|½Ư?½ü´vuù©?è_]̃*Å §—Ÿ„ùm•W o±Bi® ³)"Ê=¸*qúϽלT,>ɱ̉ øẠ̀4°Xå?büDo<€ê®ë³PÍ0ÀµB¯À¢1•n˜n¾øß¥ÜG̃{R"̉ÈÖ+¥Wö˜ &"‘Sv4AwÀ©›ØJ§™׬‡•&jF-N¨î°®ê‰ŒŸ8j~Bœ»£‰z„Ôd ]@¦)xØy”ñpB}Ç d¢—"ô₫͈yêÇ)hYÀµ 9bÅ÷nèÿ¯›æÙç RƒÀ¢G  Ñr+«Jë yzî É |˜¹qª¶̃qüî·›L`çIn¦f$0#@ơxŸ̉‰KŒiꢸ7YyD’q96µÂˆ¤·¹´†ts“°˜¹N4FơÄ'_é¦(Bă_ụ̈5UóRñ ³j§ê•Qô céáÏzưqÍØ0^C(klÔa¡”®Ú „î½›ÊE;äá©D•Œd d¦nÚĂOQ–:öº?’KjH,GÀj ;&¶Fuc?˜‹é ‹cØG‰L„Î7Rô>av7p{B₫ÉQ–²) ¤£ØĐ"2ü ºÿà’»}ͳ…#䇣 ód¢‰®“#º/p²ĐÁ•¦)l ü²§T®+ H~Hü‡†° G¢Ă0F- wÄRóÜD<Ê ¨ÚQ>Èê›tˆ [zNH¬¨±)åÀ=b}·ÄSV·H3<â+^`GuɼswQ¾p̉IŒ‚©«y·e ÈĐư Ư0“7ĂeƯ…LŒÍâ˜̀1Í`ÈFc+ƒí°rΈ[Ă6^ ¦t§ SÑ%DO-Zx{ŸđA†¾’Rfq4ơCÊ^álHg,ƯTk¦ ßi,È„¤102D,´ç¤2H'Æ ­̉¡˜´¿à#ͧǿೂ¢¤'=eÉQ?AÊLËŒ0®á¦¨7GâÁ—¼SÊj, GéY³Ê»Æ2!aK>™́p’£h:uÑÆ‹h†<ÀpC×™Ê0ë‘ÅV\ø)˜¥ˆ*!¤©”hI¢ ²ØBuR J ·d8C€6óñ°Œê@Œ d2F²Xî¨UïÔæ,H†ø:Û—œ´ºÔđË+j&me®#H|Œ ààMX@̃oAapcCp…‹đ¬µ§;MdßÇߢñØqØIÄ( ̉„ ×;ºưÿ•P$bys0=ơÔê\Öơ@ IÙÈOh‘tŒ²ÀƠFÓ)¬Qà†÷™{–¬ĐsÀë{ Y£ĹNÁñḿ¸H®™D)yñX­*âÂÆ.MĂlro ưF6â{®™ó~Gó~| kÆ=N¢@̣íyá¾$Ó:¾í©U Áó¨#ầÜÑw÷XÉW÷ÿE±8‹¦³(Ô>­È‚J`D7¥Çëq¤Ă—"‘1…@ÇiÔ‘Z³êdf5̃M̉¸@>0Á> ¦ẹ́y¢̃ăˆœ:úYæ|I‰m©NôȱŒUÖLoJ*,àÂ;Ăg ®0ø@ÿJ{ê‹)¾Â(jĐÈBđUçÅw‡2zÑ£ S-S‰(|© &t,G*)¼ç‡>‰ùKh²Ạ̈'$΀*ቆáư@ÆJusHÿ7̃z.T}ăqđ†̀b™÷fÎgß³(&c.¨bLº*(“ŸO¯Z8ó§e …:S/œød q3yä/S€f†6øHÙÍÜé6àcü$P@=UQÀzº]„ø-zSCø­IºêB*°lpJœâ½Æµ.Ú̉("Å‚ÈơºÚQ®u¼cVÄ-qØA€%EGMq¸¸y9s g6hj«zƠ:Z°d­Îb *ˆwI4ÁÁ£­8₫È~^|>V¸ä×óD –œÀóĐ‚c2˜; ¥­Ï†zi”đ¡u‡pAmS&`{âÚàH SêªàñY¨Lh¤ 1³ĐP¦R²DZq°¼¨nœ&¹åÍƯ›ªÅ%Ç}œ´¢̀ö1bœXª¦î•8K̉*ËT ·Bù«[$’ddsṢ‡ØsÔB̀G7ñGâZ+Klđ8…¨ ̣3Ü£g׫Ưđ ªŸ•üV$`R%ĵrđ ưĐ8–iTJŒ¤³Æ>ϱ¬PđøT¦ÊÖ¬Æ×€?̣AdvÇc̀Wè!ÉÂÀŸú#ï¾PT§¬£²ÎarmRœ…!̣XÇÖ{QçÏĂy~9yú´Ÿ©'îư D9q8&§G¶N?ÍRV đâüÜøŒéƯK™£|…c1v}̣n‚‹ç î̀ƒ[Ò’çy…Ơ+t‚¹sTÁz¸:¬‰̣ĂÍr£ỹî{RE­ưJ"€°ạ̊†¨ˆDôŒ́ÖG{s„g]!Ă:CáH;Qùœ%¦ÏÑŒï~xOfT)óB³ükd ÙYÄ<Ểó*±G:8cw¤œcr„†\³eÍ:­Ê vsăæ [jA‡ÉjÅ-J@ÏbŸD;æf5Ó»‡çƒ́̉Y¢ÍG6’Å=b®Ư“è¯É­D̉₫ åÄ Æ=¾ăøI”¡—Qéáeƹ‘ơÙrdLéÚ( Ù ÙÇ‹gWOCzfâQ–*øEe@û5ñg´˜ó(3çơL/›dtüÅÈGÙ”¢4“|”P”5ܦ+DiÄP‚áZˆ[7e˜ V FúEp„²8| jŒ–¡B °Ø)ëµqqƯÙ..²ÜĐE₫ Kv¦₫₫Î̀ư0È\SªÁŸÛQØS—Séi„,åJ©MÂ(ˆîé8Sé¢Û¬™eÊ ÜG1΂±x˜†ÏW†Ÿm+¤’iûÖ¿¾²(J Nœ¹p½h–¢EQ½ŸäHb éá‡ïà¢9‰?ơAgCóµ:7êü²ë-§¹u`¿CRˆŒ¡«‡ô"OI)RàÑ…Ơ€³3;z”¨¦Œ£xè{Ni¬Ü 5¨̉FØ ‚å_ơ^}"·̣/Cblx¯˜hóDj£ƒ)¢̉å%FÉa£§0 »RờÍ9¦ ‚²3j¹h\P6I–ÆB†@vQ3uï§NQ4&q¦Gä€<́18Té4ÓẬ,7^Ù̉¥17üwExFö@ÇfX¼ç•‘†–#ƒça‹EÄ‘tl„ ?œ‹©ôülZMÜĂdæ2rÖcô€±½ßÈF2£/ÁëÁA‘K-t¿8ߥœÁn‚ÙߥtëM̉e^ÜÁ)œ;`ÔQ‚̓öÛyl0pG£(V‚=Ó¬÷ÆWDÇ̀[‚¯¢;L$ǼẶ(C!ÅoÜăÅ Ç ¼©6Ü %ÅËV½§&caĐ¹0â¿?µµwEuSE¶$ÙliŒ‰ÓD™˜¢%'đ«’YÖ₫]‡cTEÛÁQ’xYd)ñ´ï³È™{‰m?Ê.hbĂË´œ¡vúMƠfg¢d7Ö˜Ă“ #ü™W¡̉; ¹ÿÜsµ›ôP¹I´ t1rcrï³Qµ̣<ëø2TˆSÚ9:r1€̣¢û<7E›ª̃•CQІÉtªÔºO¶àJ·ˆƠ—‡År‡µR4oñ$TV„ùÔ0µ˜Mö—Âesœ· 7W¦¤fä=aêÇZ)·́†ó‚p¢õ' >LɉY”$2Q)®ñ6æØz(®…èFϾÄÂ"1­¢Iê9LnS›±Èñ»¨÷D,ïƯØ 8»#éæ…€Áăör¸B/F^ͳ×UcÇ Ơuçå‘3=¸ÇĂm @]„à'‘W€D_Å¢ÁÍÚ½¾År'n²Ä§”ôˆ¤‘lNg¡_éX¶kåØ\qÛvÎñ+8EA,9=ºµµ¡U)”î)Ú‹gú* (<₫”­—Z̃ÈËatdháƠâ±̉“FWÖª̣Æ/T®A'ɆÂW. )',!!ÉCEÓ!ú”ƒX“HL™‚ÛXö#ôÀ›ê4øô¢ £ª®H̉(vï‘#å¼±Jd°|ó¡2J»÷÷p¢ ÛWX›åÂ…HËƠoÄ…£l»(êc¦à¾(Î _Q ~^s†rá"±ÎÄL°²H:xÚBT«6B¡gg®ĐÈ¥¨Ơ!ÊËÆ÷k¤ h #¾ŒÂ}æÁŸ£xºˆçÍ4†lÍ6…b›S¯D¼ÁÍx»{O¦˜º£‰Ê}­C“v¥e®_´oœVSˆVA„ˆ W‰³À Ú[{ÛÑAâ,Úör÷¢ü‚_ˆ"!ØdK7‰ĐKéŒ8_G*™íh! -Jă‰Px¢§ûZd'ƯUa&ä1ÅƯ#V^ªªEeóZª½KÙbíO₫¸q´í[ʪ½,¹DD»(pø‰Ăö+2NG£‘› ˆF,Ä€'̀¤‹₫¶c[²W2qÔPđ(jŸ:­ßy7\çY{Ă J\œCh¬›îH:/é!´/y¸hÆ nÄ/<û|̀ÁU‚¹[*ÂH‰Ó~;ă,&»#í;å“h¡‰ơ\V9]ƠĂÔdkY( ¯ bÀ œLJ§³·ø4Sà¤C—Ơcârªơ 2)ÑíˆKl @ó—́W"R•8ÖRsà0†t‹©’’zØÂ!ĂĂR³µ¬`Í,q"ăƒôæ³W²Úkv“Ó$P̃áyM¢„3„ª̃́q’ è°%”„/ !̉+-÷o¾kŸ¸“À%Ov’Ó“uîB†æĂ™”ñ~íĂÿϦƒí5…xE´cQbt ­V…“½̣ÉóY*™€ô¦X§L!=EGi9)¤@ă’È8AT4§s;”b€T,:ơpÏ»S?À@*1‰²DN¢ÀS¾±Äđ9å«Övd½Ç¯£(E± CÅÄ¢@±Ú›è‡Âƒ`hÀEw‘‚Fµ\—Â)N¹'¼(¦X„ÂM0ƒƒư±L¢à6á>€Ú5&™Â½W©[Å`/Gs$”ʬ@Ëé)ơ+·\!í M£\Q¼``'—+¹`¬•G̃<¡ÜÔ™₫T@ơHæäî´& T|rª®´]̣/đ wĂs?Cׂ£•,q â r[ [ÇÜQg‹t`A°2„ €§{ÈǸThzÖºYˆ Q€oD,90“®p̃Đô¦3"9TS¯Ï¥˜•ЧX":’ư XîÄùíi…>Ne:‰¼¤[8’¸zœwÈ™⻜ÓzƯôÍ\#!W9t@;)’IV$–m*®t‚,Đß§́äd±d'=J7Í äRYÂÔ3 \œ„3 Œî^z€ÔèˆB09óˆh”h^à´bêP’ÊŸó8ÁQBèÍÔơ¬–₫8ç« K”Ö¶c*ÂZŒI.D;\h̀ÉƯ¤êÙgÀ-YR?eº‰£¦ÄN]5”u?9lelÛKM"p¹3Q6jnñJ-üqà×L¦tR«CJ2ÆË¼¨4~æ1LѺ#pœÿ/\/%ĩù˜µ¨xr†̉ÖoRåÅ¢ëµ!2öEÙ¦nmúA#ăEÈlö:ŒÈÙlIPh£>È¿¤»/ñs*&;Sr+q…:ζ·:xø q—›«¯/ó¡Tö$,ÍjÑüËQ„®S¡î› Néñ {bL¾rDáaÎf¦4Z\x{Í̉‹[óa«‹>\=uJk¤´_ ÔÑ@‡hưȨœZåI´Öoqt¥e†‘ÎD…ª€psCÁ. Á}‚₫˜21…Éé,Y]Og µ­U%½˜ƒÄäéÅ̉ ‚ăϱà%+¨Ê„ằC”qB9§#J gˆ¥âÆOwàT£Ây‘́·b•̃ ̣  ê %ůPV¢IvŸ‹GÊ>²ñm#W.$D—&˜ăØd÷+eAèª̣n%î™ÊU¾ü«}œ̣§êr¢2`¼RÚˉYä69¼*VA…áƯƒÜB¹N)J‚ûˆA©iWÏ`yp™¶ªÂt`..· |'–ÓˆCwªÇRs7åÄ. ƒ(ZAü­ƒÎŒ ¯ UwO](̣;EŒ† ¢È%VHyT,D«¼ä̉"îœ U ĐÂD³Ç^g6µ Îû¶̣ÑXf@%Á8ŒÊ83Ù—Ë(… Å¥§jJ©’%G–DRñz`lp=¯K½•˜ÿÀr¶æXb ‚?JéZ öË¥$#w"é§z̃’OM…Z¬ g8Ø0“ÈW¢‰¶‹©Àm•cB.qø‰̣á»"®¿›µˆëÎF )~Đ́Đ$9»6»÷tXǸ«ê¨*"8¸R2LDe¬L™ =½û‚iwÈùŒKº½Ÿ¿¶âơ¦~¢5¼;bÿ̃Eq[QÚ1™Ñ Jª¨z¦Æ÷P/Ê#¦?&–ÍRï !àêúbÅY\¨ætH²¢ ¯…ƯVÀj¢âK€•Yb»H 9 ×â8Ÿä( •W °B`́z&GÑ—¬È cb*éWè™GIOeQW&Y|ºÀ¹> sa€fVù̉^ùÏ…ơNr“/taaÿüô%é‡TEj’M™¯#–ØŸÓ’ØßBæˆ~†Ùj"Å"˜:—ÛŸR$¸Jú¨œp9|â¡‚êÁ,ÈØẠ́á{ḤX"b?€£#X-yÖ‚o"X%”óI‡»¾âÆùàD ¬E)qÀ§R£\&OÅÑÆă¹¤}*¹ƠÓ1ty2mÄ<fD±®£ÆÏÑ…E 5Àđ,pMI<¹o[V´d…*₫ch~æÁ¶”­*”y?ÆÜU` : DmA­°¬Säj₫%ËâLÂq ó%zƠx£g Nè°@*gçnơ0VÅM‰…²©¢t’óµCHVä×Qå3Ë+§́x±ÅkR´¡¼&¬[ïYO‰a‰O³sTĐ£kɶZR ´£9V¯¹‰¥?üBÓÂaµ½.vg“);´́+¿YQj¨P ¨ú‰:~¥ˆ™²8­3…6“Z¦̣¢IÑhÄ û¥bÑ—í°eMwaê•rh.‰,ôàˆc₫¢^É| “ɘ†ĆRÁ† îÊwÆ®OÆàRÙ—JÏåÀWSi‹~dÆÅ>¦U;ï^ åqÊÛY'iN¸ÿÅ2Â¥Ïå\­µ’µ’ÖÄÍ‹¦ăÓÚ(B³zB=ÚvŸ$ ¬¡/R*M€¥f}L„ ç¢c£²‹I‚}i4B§ˆ®I¥é5PƠ"‹c{‘2I¦ơpBʲ%z¡²œ*>Ô5ÑVDsIaÙôƒ3—Eá Ơ<½*vD€³…)•/71f„…@=¶Çñ©½ßÖ1èÙ©~ÿ“¹ª¹‘.ÓÊÇ|µb'áhFœ£>|]66Q)=È2¸ŒR`Ù»ùæó•²?Tp§åŸT‘¯”jÅEÎX…<¡b>ÎÆ$€†#?\,×ÅkÊèK@9›!®r»ÉÿÉTÊÄ ÷½c¡Åø@q/¤₫úœ({„«—ÉÊnY½¹¹¢Rvp4pº ùđè*ÖBađ…LTÉ ê¤fRA$‹¨¢®E›/V ¦>]‰2/i‘K9¶tôX₫`NfÖ D¨T•—bü(KàŸ¢Ghm&Ư©¸Ñ:t°h™¦H 2Ẹ̈ÎÿUô+±Äâ²zªU“'%÷´<zÙª·ƒc&yDP`Ë­p₫Rp¹̃E(“äEù©>.ßĐvÉ ±ÑBg©:Ưi¨°‚FfŒ¤Øaư„"Áå54_eHû‡Bæ:n{KóKɦƒ~X™€;Ç#m# <M€™Uë‘«ÇjQ­'fAØq¾f1d¡1WHâ8äÇ̀„´PÅ›%ÈñBÈÊ aèp#­ÈS…R–(ç '\j÷l¡tˆ X`‘+«Áj¦con3T¡£¹Oåëç6.E<•¿Û3†Jpû!vn>nƯ^û”J‡ƒfñ3z£ Ă6c 8÷î•YÀ±Ä|~ØPuÏ8bzĺz"¡ĐŸ ÉÄ~nÀŧ¿ÅÖ4»ÔŒcB»L=cMTU] ƠC2kFq´”dO¸sÚ¾ŒÉ Ö‚{·jæª̣\›j´˜ºÇ¡|³Ä¹49*¾B#Ë·µ.-´dRÂ9ûơ+ÖsÀJÄ̉§̣ºóT¡„3WE¡Y²˜¢U©Ñc=pls0NÈ”Ñéåö: ôyUµwL‰²;¼]‰*1@Ø\^@2-&øˆÎ/0v§GŸSZ¬™†%ø¹hnÑ fxPM±}*_”Óÿ-vRuNPf*%‚Qj°ÅL=(¹IÑ S‡‡ª,‘¤nndùK{f́m*mẫ‰12­^Ûa/>dÇúcªJ¬ ½³¿×a&M‘íE WÓ |ù M@}{à́L2—‚×H’EP̀Æ.´ ̀:ÈG!‚”öŸh U„ÁÖéQË„¸ÛL)rÎÊ{¯¤íc t“VÑ(3́ k™°]ỤHK†üăTwwи)Năh‡ ̀U•s´U¸’̃V¬¯DèûIÁO'œ­TØhQ'å‡ ‰úè×u$́r§ÅƠñµ̀%bb¹PÏ­”ăªˆÆ1é$£hfÅWQô}O×çIÚUC̉u(béq$ £‡¸´HdiÙ½Îb%éÀÄÔ˜ºc%'å«¡tlvàbæ¼j¯§’ªœŸ¼ CQ9 ×$†¢­OµĐ!M<̣̀™;W± X—Ă!W„k)k1×Ä—'9æjØăiO Ă&Y¯§›‘å¯ hJD_”­±t]”¹‡i`ö!*̉d¬M[&ù¤Æl†<œă%yAq‡>‡ö´eŒpÀ×/‰É€s%ö9I”X7F‡ÖwVwv!9Eå¿'*>Œ̉Í„\§.nدlæ9:§Sqóḳèjå¾g G?‰¯n<`WÆ\đƠD—¶́—:% Æ™ög²ÊoÅ&¡Ñ£>Ö̃dMW k«R®€=Çx̀#qC¸vª= ¶kW‘S3Pë𗑸ƠưÉ¢±¸Âê|ª*ÔgêC~, ¥ɪâqù9ñB)¥X©0Ăª=äµ±PƒûK³­±ëù#ñ †¨r/ÎUQ=ù×3Œ«mZ‹ßƠ®Ơ`…δS >IÄu%TÎ_âO³ uUƒ' m,ÖVË{dU5•ĂÆœºyyPIÇ—©£ŸBH¥Eë[íqi±@‹‰ P)* qf¨W£tE¼Œ:ơU‘+ǺÇi晩-́X9#ˆ»S² S-öêbHºM>úOéưè@Çp±)¦5˜"ùŒ¾B¹)}~ïÓ” µœ‚-́×R;zRK¢Å5áw&WP¤¤ä€Q¬*×i…Ă{+Í,Å_åó‘Dç˜Ê(¦Æo®ÄE¾÷G­àÆ ;ư!WñĂ–tcI¦rTX² `/ë k̀®çhă1FGdLŒVóÓ0Béi>aaËëÂAù”̉V:87̣ÁÚơ{®=–m˜QY&‹úRp0׌‹7̉¯ª©sV¶b ₫*˜?•XÄr4Á—:6' #—`„U3?öu®µÊ×SÆ7T€_P%¼àAæN€ûK}|UƯ•ŒDiX÷¤`™R‡ƠO¸.Êp¶2?A~¨ Öă¥¨8•ö¥Ê¹:›^ÈçĐU/˜>­,.³™RNFZ¡¼b›s9……m‡m_ZĐ:ËtkG¼ËØÆ×ÖËᡆ1à.:H¦'†2ckQŸÖ „äüêV,‘S¸L›Œ&‘̣½( hïªÄÏ©ÂÏ6ÿØh–vtGÍ©§ AB'º5.€à´•- GC.H.ïZ6+fÇÁX₫b¯¡̃P…RĂ Ü`%°é‹ «|Ï&;âëLqx³c'XXÅíĂ(÷†%[$,©%ôŨOΛ‚Á DïµV‚sSƯ„ñ  ×É̉YTQơtľq\=ĂßÎoÎEÿV\^‰o§77§—ƒ?Äç«1øí\\ß\}¹9ưÚƒ+ü|₫¯Áùå@\Ÿß|íçŸÄÇ?œÓëë‹₫ÙéÇ‹sqqú ‹ưë́üz ¾ưv~)®ü·₫í¹¸œÂ ưKñí¦?è_~A€gW×Üô¿ü6p~»ºøt~ƒæ^]ƯĐ‹âúôfĐ?¿<~ï:·q̉½~nEÿV‘‡oưÁoWwGOäê³8½üCügỵ̈SOœ÷èù¿®oÎooÏ?‰«Ñÿz}Ñ?ÿÔư˳‹»OưË/=ññn .¯ÎEÿkp\ơpd~V- vơY|=¿9ûíôrpú±Ñü-̣>÷—ç··°Î)ÍấîâôF\ßƯ\_ƯÓ†å¼ôoÎÅMÿö?Åé­Zäÿº;U€œëó›ÏW7_O/ÏÎa,{₫ư[œ®øăêËoWwŸrÀ¢;ŸÎ?ŸŸ ú¿Ÿ÷àIqz{{÷ơœ×₫v€ tq!.ÏÏÎooOo₫·ç7¿÷ÏpnίOû7âêÆ9»º¹(W—¥³…qûÚks¡ÂĂY»¸„cu₫;»Ë X’›óÿºëßàÑù£ÛqúåæWÜ:(η₫Ån£>-‚NK_¹üĂ:-ˆo¿]‰¯WŸúŸaè49gW—¿Ÿÿq›[Ó[ëŸ~¼‚úx..úˆÏà — .§ӯ§_Îo{>"8æ—óËó›Ó‹¸½>?ëĂư˳₫§óËÁéàuvuy{₫_w°Ç§ ˆszÓ¿Wwµ¡w·çx/Ơ \áw6²/̀ØïÎåƠ@˜Ó).®nñ(~:œ Äxp*>ĂÓ7ç—ŸÎođâƯƯœ`0̃8¿·w·ƒÓ₫%í̀ï}ÿ擾y°Àâóiÿâî¦xÁ•¸º>Gx­ 'n_öpóEÿ³¸½;û·M¨ûíĐưvz+>Ÿ_ÓO¿÷ñ^̣8W··}^“+†ÀëX:†}ƠqEÅÛRÖx x9¨sàÉ w¤MƃæđeÓƠ“d§ ‚’”D§9rœ‰5e®qơM-å#Ù_3(2F†’x’û¨r ¬jQ̉.ä ư…Í6hMè“(€¢XO›Ú©Đï?ø…{…q„j­û©pÜ\Ö•ÉåÈ/„IO'e·°'°ƯyÅ‹ùrÇ‚>¤ç—Ÿö¯>ï/kGz~IǤFW̉¥Đ7']€ëoÑ#ÂÆícX̃>ææÂ—DY¼)÷yY…ưoÔR _âX¾Ê?€—Ä¥|Tk™¬Ï†,¡ör.TÇMów óˆæô”=]¼ó÷˜©›¤Ä/ùª?U.gºÇ®$¥^:A?ˆ¨kR’k&L".›œ­jù2̃ ApgeÔtTACT-t¤C¡Am@V hG:‹PÑ&ă*:5ÎtIq́ ZZ&ÏĐ›d— Tëá©9‹eá‘ưF’N!]ÂÛ;ùơ"Ùé‰7̃;MC¤¸>¢½Àÿ'ÁŒ>Æwûr ̃5W×c7ÉÁ¯¯ÜøDG7ä/Î^̉`P䑟-ư†#E*–rœ7̃VáF¹Ă÷³21期*»{¬ü´ÚG½T'r“œÊæ,S){Jk-Ù˜L8O,^¸©cek¿,+±å ›yé¾vp>©œ5e¥È9δA8,l#ÛW÷/:'JÔ e7Œéeæ(¶Ef±@d¾•R-§³È梜Zd06đNÙHGíç#Bï‘“«₫gÖŒ!a”B4†Lgq ˆó$Mg?¿zơøøxpfQ|ÿJE½Ú;Yö+Đg¼’±<ùơ•ç?¨œÈuË\=$(íCƯ)#̣9C¯ 0ÇQåà b‡;ƒH+×JÚÿ̀6RpB`Ûèzº+:÷araU㔋¥c„<-¦ßCEç«§RMb»̉6™ú¹KjĂ“aĐ2µùËCÜñpœ~¼½º¸œ_üa+ÓT ‹Ï#f¾‹hñø5q§35ü½w’À>>₫ú >°aä€,’%Ă‘AÊ`MỤ̀£Rl—Ö%´ ́—µ呱'Sq<Á´:™ÏÀđnvÓîu³9ăÜ6ÄŒ/9üæp¤Î°Ï•µ^àFâjŒ̉¸3Q}µJOfÇ êï(Kªwöå®oÈs£ô¢dh­SÛF•¢O-r…ñé˜ä\NgA4‡$ö™Æ1ªƠªŒ_bø&˜ˆ‚C­.Ñÿ 5̃́Ú‡êF-È.ÛfôIY}”>ëø—<ư›ŸkL &í‘‘JÙë $˜NWSW’ZÂvµ-–Bc…U`1¼Ïm>7gÀ“$SN@BQÚÊä²8© Q¤qq >Æ.ç¦:&©}Äe$†!†„ ˆöT„Bè°×7e‡;Ƹ²É‰xTG?äEñé¨å¿€Ñx±+*I¥ëUxZ?f©ƒI±€i£:·6×›Mü J¢Ùd₫êq2ߣt?¸Ÿ“tTîë²́­Ä S"²™I*“₫~Ú̀>ÅvÎÖ=ù×^₫…Đ}ØŸ¹¡ åœ8לªñ3L‘5­3ªË´ÇÑ‚ßåüŸ{³=rûç¤v́,>r€sOÜÍlxƒh–ƒ•1¬l¶w̉‡àeœđ£̃ÿ‡É́ñÍë·çgqøíHư4ÿÜ`pE¬đ/Sîü:<ùøë«á ̀ÆQÀ&@ÏèY»@?#ĐÏíư‚@¿´ ´@ûí½@ íư@¿¶ ô ^µ ô^· ỗ´ ỗ¶ t€@í½C wíư₫̃.Đoô[ĐW@ÿ^…|…$µ‚´JHúInœ!ưsï5̉â˜È(‚ÈDUŒ̃« ɈŸ8‡8j¦Âú-UÜ«ê56ûÓ+€´"¦€üsïxïÄ3/~db˜Vz,CS3ñÊŒhŸ₫…©Í÷N ¥¯±§ó₫]ẫËư«(%÷N¨Ó3~+Ô·ÄùVŒÂKaSg„6êlØQk 5 bOBA­½ưgƯ%ùrƯÿ¸wÿVO¹6’gX|ÿ3×qFé ë•ëoꢼ ävÖ; Ç₫}˯]6r“tï¤ü]ƯéÜ}º̃¿âtïäîÓµ€¿ºB_Ơưˆb óeƯ ÜbÙ }x¢i€0ÜâDg×ûgä9́ ήưưÓ8j}·˜̀EÓ ¿Ÿ`Ç­Nă îÛzm₫³>M"ư÷„ÿh—|̃Í£5₫1Fù̃ ư¿uœƒĐ‚»Ư Á₫ÑÙ̃Iÿè¬ô¢wíÆ`ÍöNÔ_Ư zÜQ¦ï¾~}ôÓ'(¡ åm<øøAÓû懗ƯLăMăi\÷÷Nn¯ûƯ ÷¶)z@µ«—hx÷ëû®é€^WOèw÷xßx·_ÏöNèÿnü©)’¿ÿ«x¸w‚ÿµb%“½üoËeAÄ9DdŸïÊ!úG- ß¹¸J¨·€jç")¡ú¦!ªÏGÆư·- ß©ÔŒØùá,KSü{gtyƒ²&&đÜ‘™ÎQÓy^’H9nc"Ï{)ˆçAvë†Îú4›Â6ÜĐQ+z̃[ÂS9ne*ÏwO¢™ ÷Nđ¿í3AVxú› ×•‘;jˆ\÷æDó¸!ÏM;poN¢#Ó"÷¶!rÏG̀ưw Ñ^†V‡Fèwjt@jˆb—&|p¼wÂl# ¼4Cñ¹ O䨭‰tnâa„#ü|§đ¦ñÈñ̃¶2…n u»w‚ÿm¬4A¯+‘;jˆ\÷%¢yÜÍç¦Ă8‰7íL¢sŒÈ¾mlG̉/"÷®!rÏÇư÷ Ñ>Æ€èÿÔúƯ3…ưMÑ́TH'Öđº!]JéÉÈ AHÇÿ··*Cè₫ÄŒ3ˆ‹Tß ư]]´7…̃ÎCÓ@ˆĐÁÿ·nÅ -g!Ø•Am‚h7Ö„Â_ öl¶„Â_¢̃¹e ¡đ׆hvnH(üµÏfH(üµ!êÚ™~Ü Ÿ7ÛO¬n·ˆ́ÍàvË‘-ÓÅí «3ï$™ùÛ‡–í©ƒÛX‡]¡I ø´…†u…$²ÁÇmLAÍ¡yz7zMío¶éÂđ¿­‹lNâWtèf^́ẫÇÁŸêÓ®̉jRóT&₫ÿªIñ§Ÿ”"wqĐÜmÇt¸¸?|l£ÀÿsOgæÆ~:§ùĐß;>!f[qĐŒmmÇd’4 }p¦À7êÓOJ§ĐÀ 3h¶dJJ ‰ƒ†bH+Ó©ëÁAk̉ÖXÏæ¨3đMm‘kbËœ™—9àăn6¡Tñä4¢yÀ_;; ’œàÓNưªihÉ ¾h(9=ûdXr‚»YW1ófàÄl-UZTqC4»¬ª˜%Ăt:Ú;¡ÿ·Åy§o¶·K¯…2S@úbk‹‡[+̣@ßt^´®üùû̃Éï-ÊŸƠEA7›n‡¥Ó₫̣4₫·­èÙ7”¾ØÖƠ]ºôyK«ædùf̉[Z÷Û̃É·¯å£Çn:ơWƯ)ŸE³9æÎđ-ï̉7?ô¢ÇÄ”?à/¶¡₫AưƠ§×è¨uE¬û́B½xƯM`CutƯ4¦êÎÑïÜŒª»4Fµs¤î °›z¢î°ƯƠ÷óÑq[‡¨™ôâÜÇúlù‰“tkJ0Öị̂ç5AÿiNvlu ûyÖÚº“M.dă e¯RwHx₫WCfû$v'ûă(ñÛ ³wÂbúÉdÓ™H£ŸÅ?Âa2ûEx°](ɦS734‘Cór₫ǽ“_‡'}5<é8 ¸Óè=kègú¹] _è—vöh¿] ô¢] _è×v^!Đ«v^#Đëṽ Đ›ṽ"ĐÛvè ] wô®] ¿#ĐßÛú ~«ªi«!­¯<ÿáÄê₫Ïqœ__ #oßL̉ipâü„?¯¬instrument-control-0.9.4/doc/instrument-control.qhc0000644000000000000000000027000014743226261017476 0ustar00SQLite format 3@ ##.v‰ ²¨†’$ º  w † ä h ó z ó H¾"¾fó| ¨b''tableVersionFilterVersionFilterCREATE TABLE VersionFilter (Version TEXT, FilterId INTEGER)n++tableComponentFilterComponentFilterCREATE TABLE ComponentFilter (ComponentName TEXT, FilterId INTEGER)u--tableComponentMappingComponentMappingCREATE TABLE ComponentMapping (ComponentId INTEGER, NamespaceId INTEGER)q))tableComponentTableComponentTableCREATE TABLE ComponentTable (ComponentId INTEGER PRIMARY KEY, Name TEXT)VtableFilterFilterCREATE TABLE Filter (FilterId INTEGER PRIMARY KEY, Name TEXT)b%%tableVersionTableVersionTableCREATE TABLE VersionTable (NamespaceId INTEGER, Version TEXT)))mtableTimeStampTableTimeStampTableCREATE TABLE TimeStampTable (NamespaceId INTEGER, FolderId INTEGER, FilePath TEXT, Size INTEGER, TimeStamp TEXT)551tableOptimizedFilterTableOptimizedFilterTableCREATE TABLE OptimizedFilterTable (NamespaceId INTEGER, FilterAttributeId INTEGER)(77otableFileAttributeSetTableFileAttributeSetTableCREATE TABLE FileAttributeSetTable (NamespaceId INTEGER, FilterAttributeSetId INTEGER, FilterAttributeId INTEGER) 33/tableContentsFilterTableContentsFilterTableCREATE TABLE ContentsFilterTable (FilterAttributeId INTEGER, ContentsId INTEGER )w --!tableIndexFilterTableIndexFilterTable CREATE TABLE IndexFilterTable (FilterAttributeId INTEGER, IndexId INTEGER)s ++tableFileFilterTableFileFilterTable CREATE TABLE FileFilterTable (FilterAttributeId INTEGER, FileId INTEGER)z ''3tableContentsTableContentsTable CREATE TABLE ContentsTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Data BLOB) !!‚ tableIndexTableIndexTable CREATE TABLE IndexTable (Id INTEGER PRIMARY KEY, Name TEXT, Identifier TEXT, NamespaceId INTEGER, FileId INTEGER, Anchor TEXT)''MtableFileNameTableFileNameTable CREATE TABLE FileNameTable (FolderId INTEGER, Name TEXT, FileId INTEGER PRIMARY KEY, Title TEXT)e'' tableSettingsTableSettingsTableCREATE TABLE SettingsTable (Key TEXT PRIMARY KEY, Value BLOB )9M'indexsqlite_autoindex_SettingsTable_1SettingsTableh##tableFilterTableFilterTableCREATE TABLE FilterTable (NameId INTEGER, FilterAttributeId INTEGER )l++tableFilterNameTableFilterNameTableCREATE TABLE FilterNameTable (Id INTEGER PRIMARY KEY, Name TEXT ){55tableFilterAttributeTableFilterAttributeTableCREATE TABLE FilterAttributeTable (Id INTEGER PRIMARY KEY, Name TEXT )u##1tableFolderTableFolderTableCREATE TABLE FolderTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Name TEXT )x))+tableNamespaceTableNamespaceTableCREATE TABLE NamespaceTable (Id INTEGER PRIMARY KEY, Name TEXT, FilePath TEXT ) ÁÁ=S9octave.community.instrument-controlinstrument-control.qch ÷÷ doc    #Ô¶{fS>#9FullTextSearchFallback%CreationTimeg,÷) HideAddressBar- EnableAddressBarA EnableDocumentationManager; HideFilterFunctionality? EnableFilterFunctionality*-;LastRegisterTime2025-01-19T11:48:55.091 ?Z~“Î?k²́9FullTextSearchFallback%CreationTime)HideAddressBar-EnableAddressBarAEnableDocumentationManager;HideFilterFunctionality?EnableFilterFunctionality- LastRegisterTime Á1 99instrument-control.cssinstrument-control.css= ;Oinstrument-control.htmlOctave Instrument Control Toolkit  nn ‚ .instrument-control.htmlPOctave Instrument Control Toolkit Manual      ̀̀2 93instrument-control.qchÀ2025-01-19T11:48:55 ûû  øødoc ûû  instrument-control-0.9.4/doc/instrument-control.texi0000644000000000000000000003365414743226261017710 0ustar00\input texinfo @c -*-texinfo-*- @c Copyright (c) 2019-2024, John Donoghue @c Octave Instrument Control Toolkit - Low level I/O functions for serial, i2c, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces. @c %*** Start of HEADER @setfilename instrument-control.info @settitle Octave Instrument Control Toolkit @afourpaper @paragraphindent 0 @finalout @set COPYRIGHT_DATE 2019-2025 @c @afourwide @c %*** End of the HEADER @include version.texi @include macros.texi @macro boxnote {args} @cartouche @strong{NOTE}: \args\ @end cartouche @end macro @c %*** Start of TITLEPAGE @titlepage @title Octave Instrument Control Toolkit @value{VERSION} @subtitle Low level instrumentation functions for @acronym{GNU} Octave. @author John Donoghue @page @vskip 0pt plus 1filll Copyright @copyright{} @value{COPYRIGHT_DATE} John Donoghue Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the same conditions as for modified versions. @page @heading Distribution The @acronym{GNU} Octave Instrument Control Toolkit is @dfn{free} software. Free software is a matter of the users' freedom to run, copy, distribute, study, change and improve the software. This means that everyone is free to use it and free to redistribute it on certain conditions. The @acronym{GNU} Octave Instrument Control toolkit is not, however, in the public domain. It is copyrighted and there are restrictions on its distribution, but the restrictions are designed to ensure that others will have the same freedom to use and redistribute Octave that you have. The precise conditions can be found in the @acronym{GNU} General Public License that comes with the @acronym{GNU} Octave Instrument Control toolkit and that also appears in @ref{Copying}. To download a copy of the @acronym{GNU} Octave Instrument Control Toolkit, please visit @url{http://octave.sourceforge.net/instrument-control/}. @end titlepage @c %*** End of TITLEPAGE @dircategory Math @direntry * Octave Intrument Control: (instrument-control). Instrument Control Toolkit for Octave @end direntry @c %*** Start of BODY @contents @ifnottex @node Top @top Introduction The Instrument Control toolkit is a set of low level I/O functions for serial, i2c, spi, modbus, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces @end ifnottex @menu * Installing and loading:: Installing and loading the toolkit * Basic Usage Overview:: Basic Usage Overview * Function Reference:: Instrument Control functions * Copying:: Copying * Index:: Index @end menu @c ------------------------------------------------------------------------- @node Installing and loading @chapter Installing and loading @cindex Installing and loading The Instrument Control toolkit must be installed and then loaded to be used. It can be installed in @acronym{GNU} Octave directly from octave-forge, or can be installed in an off-line mode via a downloaded tarball. The toolkit must be then be loaded once per each @acronym{GNU} Octave session in order to use its functionality. @section Requirements @cindex Requirements For GPIB support (Linux only), linux-gpib must be installed before installing instrument-control. GPIB support is also available for windows by following the information from the wiki: https://wiki.octave.org/Instrument_control_package#Requirements For VXI11 support, rpcgen, and libtirpc-devel must be installed before installing instrument-control. For MODBUS support, the libmodbus-devel must be installed before installing instrument-control. @section Windows install @cindex Windows install If using the @acronym{GNU} Octave installer in Windows, the toolkit will have already been installed, and does not need to be re-installed unless a newer version is available. Run the following command to verify if the toolkit is available: @example pkg list instrument-control @end example @section Online Direct install @cindex Online install With an internet connection available, toolkit can be installed from octave-forge using the following command within @acronym{GNU} Octave: @example pkg install -forge instrument-control @end example The latest released version of the toolkit will be downloaded, compiled and installed. @section Off-line install @cindex Off-line install With the toolkit package already downloaded, and in the current directory when running @acronym{GNU} Octave, the package can be installed using the following command within @acronym{GNU} Octave: @example pkg install instrument-control-@value{VERSION}.tar.gz @end example @section Loading @cindex Loading Regardless of the method of installing the toolkit, in order to use its functions, the toolkit must be loaded using the pkg load command: @example pkg load instrument-control @end example The toolkit must be loaded on each @acronym{GNU} Octave session. @c ------------------------------------------------------------------------- @node Basic Usage Overview @chapter Basic Usage Overview @cindex Basic Usage Overview @node Authors @section Authors The Instrument control package provides low level I/O functions for serial, i2c, spi, parallel, tcp, gpib, vxi11, udp and usbtmc interfaces. It was written mainly by the following developers: @itemize @item Andrius Sutas @item Stefan Mahr @item John Donoghue @end itemize @node Available Interface @section Available Interfaces The ability to use each interface is dependent on OS and what libraries were available during the toolkit install. To verify the available interfaces, run the following command in octave: @example instrhwinfo @end example The function will return information on the supported interfaces that are available, similar to below: @example ToolboxVersion = 0.7.0 ToolboxName = octave instrument control package SupportedInterfaces = @{ [1,1] = gpib [1,2] = i2c [1,3] = parallel [1,4] = serial [1,5] = serialport [1,6] = tcp [1,7] = tcpclient [1,8] = udp [1,9] = udpport [1,10] = usbtmc [1,11] = vxi11 @} @end example Most interfaces have two types of functions: @itemize @item somewhat compatible matlab functions such as fread, fwrite @item interface specific lower level functions such as udp_read, udp_write @end itemize @node Basic Serial @section Basic Serial @subsection Serial @boxnote{The serial object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the serialport object.} The serial port can be opened using the serial function: @example s = serial("/dev/ttyUSB1", 115200) @end example The first parameter is the device name and is OS specific. The second parameter is the baudrate. A list of available serial ports can be retrieved using the function: @example seriallist @end example After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. @example s = serial("/dev/ttyUSB1", 115200) br = get(s, "baudrate") # gets the baudrate br = s.baudrate # also gets the baudrate set(s, "baudrate", 9600) # set the baudrate s.baudrate = 9600 # also sets the baudrate @end example The device can be written and read from using fread, fwrite and srl_read and slr_write functions. @example srl_write(s, "hello world") # write hello world fprintf(s, "hello again") val = srl_read(s, 10) # attempt to read val = fread(s, 10) @end example The device can be closed using fclose or srl_close. @example fclose(s) @end example @subsection SerialPort The recommended method of accessing serial ports is through the serialport object. The serial port can be opened using the serialport function: @example s = serialport("/dev/ttyUSB1", 115200) @end example The first parameter is the device name and is OS specific. The second parameter is the baudrate. A list of available serial ports can be retrieved using the function: @example serialportlist @end example After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. @example s = serialport("/dev/ttyUSB1", 115200) br = get(s, "BaudRate") # gets the baudrate br = s.BaudRate # also gets the baudrate set(s, "BaudRate", 9600) # set the baudrate s.BaudRate = 9600 # also sets the baudrate @end example The device can be written and read from using read and write functions. @example write(s, "hello world") # write hello world val = read(s, 10) @end example The device can be closed by clearing the serialport object. @example clear s @end example @node Basic TCP @section Basic TCP @subsection TCP @boxnote{The TCP object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the tcpclient object.} A TCP connection can be opened using the tcp or tcpip function: @example s = tcp("127.0.0.1", 80) @end example The first parameter is the IP address to connect to. The second parameter is the port number. And optional timeout value can be also be provided. A more matlab compatible function is available as tcpip to also open a tcp port: @example s = tcpip("gnu.org", 80) @end example The first parameter is a hostname or ip address, the second the port number. Additional parameter/value pairs can be provided after the port. After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. @example s = tcp("127.0.0.1", 80) oldtimeout = get(s, "timeout") # get timeout set(s, "timeout", 10) # set the timeout s.timeout = oldtimeout # also sets the timeout @end example The device can be written and read from using fread, fwrite and tcp_read and tcp_write functions. @example tcp_write(s, "HEAD / HTTP/1.1\r\n\r\n") val = tcp_read(s, 100, 500) # attempt to read 100 bytes @end example The device can be closed using fclose or tcp_close. @example fclose(s) @end example @subsection TCP Client The recommended method of creating a tcp connection is through the tcpclient object. A TCP connection can be opened using the tcpclient function: @example s = tcpclient("127.0.0.1", 80) @end example The first parameter is the IP address or hostname to connect to. The second parameter is the port number. Additional parameter/value pairs can be provided after the port. After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. @example s = tcpclient("127.0.0.1", 80) oldtimeout = get(s, "Timeout") # get timeout set(s, "Timeout", 10) # set the timeout s.Timeout = oldtimeout # also sets the timeout @end example The device can be written and read from using read and write functions. @example write(s, "HEAD / HTTP/1.1\r\n\r\n") val = read(s, 100) # attempt to read 100 bytes @end example The device can be closed by clearing the object variable. @example clear s @end example @node Basic UDP @section Basic UDP @subsection UDP @boxnote{The UDP object has been deprecated and may not appear in newer versions of the instrument-control toolbox. Instead new code should use the udpport object.} A UDP connection can be opened using the udp function: @example s = udp("127.0.0.1", 80) @end example The first parameter is the IP address data will be to. The second parameter is the port number. If and ip address and port is not provides, it will default to "127.0.0.1" and 23. The address and port can be changed after creation using the remotehost and remoteport properties. @example s = udp() s.remotehost = "127.0.0.1"; s.remoteport = 100; @end example After creating the interface object, other properties of the device can be set or retrieved using get or set functions or as property access. @example s = udp("127.0.0.1", 80) oldtimeout = get(s, "timeout") # get timeout set(s, "timeout", 10) # set the timeout s.timeout = oldtimeout # also sets the timeout @end example The device can be written and read from using fread, fwrite and udp_read and udp_write functions. @example udp_write(s, "test") val = udp_read(s, 5) @end example The device can be closed using fclose or udp_close. @example fclose(s) @end example @subsection UDP Port The recommended method of creating a udp socket is through the udpport object. A udpport object can be created using the udpport function: @example s = udpport() @end example Additional parameter/value pairs can be provided during creation of the object. After creating the interface object, properties of the device can be set or retrieved using get or set functions or as property access. @example s = udpport() oldtimeout = get(s, "Timeout") # get timeout set(s, "Timeout", 10) # set the timeout s.Timeout = oldtimeout # also sets the timeout @end example The device can be written and read from using read and write functions. The destination address and port to send data to must be specified at least on the first time write is used. @example write(s, "test", "127.0.0.1", s.LocalPort) val = read(s) @end example The device can be closed by clearing the object variable. @example clear s @end example @c ------------------------------------------------------------------------- @node Function Reference @chapter Function Reference @cindex Function Reference The functions currently available in the toolkit are described below. @include functions.texi @c ------------------------------------------------------------------------- @include gpl.texi @c ------------------------------------------------------------------------- @node Index @unnumbered Index @printindex cp @bye instrument-control-0.9.4/doc/macros.texi0000644000000000000000000000624114743226261015276 0ustar00@c Copyright (C) 2012-2019 John W. Eaton @c @c This file is part of Octave. @c @c Octave is free software: you can redistribute it and/or modify it @c under the terms of the GNU General Public License as published by @c the Free Software Foundation, either version 3 of the License, or @c (at your option) any later version. @c @c Octave is distributed in the hope that it will be useful, but @c WITHOUT ANY WARRANTY; without even the implied warranty of @c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @c GNU General Public License for more details. @c @c You should have received a copy of the GNU General Public License @c along with Octave; see the file COPYING. If not, see @c . @c The following macro marks words that aspell should ignore during @c spellchecking. Within Texinfo it has no effect as it merely replaces @c the macro call with the argument itself. @macro nospell {arg} \arg\ @end macro @c The following macro works around the Info/plain text expansion of @code{XXX} @c which is `XXX'. This looks particularly bad when the macro body is @c single or double-quoted text, such as a property value `"position"' @ifinfo @macro qcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo @macro qcode{arg} @code{\arg\} @end macro @end ifnotinfo @c The following macro is used for the on-line help system, but we don't @c want lots of `See also: foo, bar, and baz' strings cluttering the @c printed manual (that information should be in the supporting text for @c each group of functions and variables). @c @c Implementation Note: @c For TeX, @vskip produces a nice separation. @c For Texinfo, '@sp 1' should work, but in practice produces ugly results @c for HTML. We use a simple blank line to produce the correct @c behavior. @c @c We use @xseealso now because Texinfo introduced its own @seealso @c command. But instead of modifying all source files, we'll have the @c munge-texi script convert @seealso to @xseealso. @macro xseealso {args} @iftex @vskip 2pt @end iftex @ifnottex @end ifnottex @ifnotinfo @noindent @strong{See also:} \args\. @end ifnotinfo @ifinfo @noindent See also: \args\. @end ifinfo @end macro @c The following macro works around a situation where the Info/plain text @c expansion of the @code{XXX} macro is `XXX'. The use of the apostrophe @c can be confusing if the code segment itself ends with a transpose operator. @ifinfo @macro tcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo @macro tcode{arg} @code{\arg\} @end macro @end ifnotinfo @c FIXME: someday, when Texinfo 5.X is standard, we might replace this with @c @backslashchar, which is a new addition to Texinfo. @macro xbackslashchar \\ @end macro @c These may be useful for all, not just for octave.texi. @tex \ifx\rgbDarkRed\thisisundefined \def\rgbDarkRed{0.50 0.09 0.12} \fi \ifx\linkcolor\thisisundefined \relax \else \global\def\linkcolor{\rgbDarkRed} \fi \ifx\urlcolor\thisisundefined \relax \else \global\def\urlcolor{\rgbDarkRed} \fi \ifx\urefurlonlylinktrue\thisisundefined \relax \else \global\urefurlonlylinktrue \fi @end tex @c Make the apostrophe in code examples cut-and-paste friendly. @codequoteundirected on instrument-control-0.9.4/doc/mkfuncdocs.py0000755000000000000000000002475614743226261015643 0ustar00#!/usr/bin/python3 ## Copyright 2018-2023 John Donoghue ## ## 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 ## . ## mkfuncdocs v1.0.7 ## mkfuncdocs.py will attempt to extract the help texts from functions in src ## dirs, extracting only those that are in the specifed INDEX file and output them ## to stdout in texi format ## ## It will extract from both .m and the help text for DEFUN_DLD help in .cc/.cpp ## files. ## ## It attempts to find the help text for each function in a file within the src search ## folders that match in order: [ functionname.m functionname.cc functionname.cpp ## functionname_withoutprefix.cc functionname_withoutprefix.cpp ] ## ## Usage: ## mkfundocs.py options INDEXfile ## Options can be 0 or more of: ## --verbose : Turn on verbose mode ## --src-dir=xxxxx : Add dir xxxxx to the dirs searched for the function file. ## If no directories are provided, it will default to looking in the ## 'inst' directory. ## --ignore=xxxxx : dont attempt to generate help for function xxxxx. ## --funcprefix=xxxxx : remove xxxxx from the function name when searching for matching ## source file. ## --allowscan : if can not find function, attemp to scan .cc,cpp,cxx files for match ## ## --standalone : generate a texinfo file expected to be used with being included in ## another document file. import sys import os import re import tempfile import shutil import fnmatch import subprocess import glob import calendar; import time; class Group: name = "Functions" functions = [] def __init__ (self, name=""): if name: self.name = name self.functions = [] class Index: name = "" groups = [] def texify_line(line): # convert any special chars in a line to texinfo format # currently just used for group formatting ? line = line.replace("@", "@@") line = line.replace("{", "@{") line = line.replace("}", "@}") line = line.replace(",", "@comma{}") return line def find_defun_line_in_file(filename, fnname): linecnt = 0 defun_line=re.compile(r"^DEFUN_DLD\s*\(\s*{}".format(fnname)) with open(filename, 'rt') as f: for line in f: if re.match(defun_line, line): return linecnt linecnt = linecnt + 1 return -1 def read_m_file(filename, skip=0): help = [] inhelp = False havehelp = False; with open(filename, 'rt') as f: for line in f: line = line.lstrip() if skip > 0: skip = skip - 1 elif not havehelp: if havehelp == False and inhelp == False and line.startswith('##'): if "texinfo" in line: inhelp = True elif inhelp == True: if not line.startswith('##'): inhelp = False havehelp = True else: if line.startswith("## @"): line = line[3:] else: line = line[2:] help.append (line.rstrip()); return help def read_cc_file(filename, skip=0): help = [] inhelp = False havehelp = False; with open(filename, 'rt') as f: for line in f: line = line.lstrip() if skip > 0: skip = skip - 1 elif not havehelp: if havehelp == False and inhelp == False: if "texinfo" in line: inhelp = True elif inhelp == True: line = line.rstrip() if len(line) > 0 and line[-1] == '\\': line = line[:-1] line = line.rstrip() line = line.replace("\\n", "\n") line = line.replace("\\\"", "\"") if len(line) > 0 and line[-1] == '\n': line = line[:-1] # endif a texinfo line elif line.endswith('")'): line = line[:-2] if line.startswith('{'): inhelp = False havehelp = True else: help.append (line); return help def read_help (filename, skip=0): help = [] if filename[-2:] == ".m": help = read_m_file(filename, skip) else: help = read_cc_file(filename, skip) return help def read_index (filename, ignore): index = Index () with open(filename, 'rt') as f: lines = f.read().splitlines() #print ("read", lines) first = True category = Group() for l in lines: if l.startswith("#"): pass elif first: index.name = l; first = False elif l.startswith(" "): l = l.strip() # may be multiple functions here funcs = l.split() for f in funcs: if f not in ignore: category.functions.append(f); else: # new category name if len(category.functions) > 0: index.groups.append(category) category = Group(l.strip()) # left over category ? if len(category.functions) > 0: index.groups.append(category) return index; def find_func_file(fname, paths, prefix, scanfiles=False): for f in paths: name = f + "/" + fname + ".m" if os.path.isfile(name): return name, 0 # class constructor ? name = f + "/@" + fname + "/" + fname + ".m" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cc" name = f + "/" + fname + ".cc" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cpp" if os.path.isfile(name): return name, 0 # if have a prefix, remove and try if prefix and fname.startswith(prefix): fname = fname[len(prefix):] name = f + "/" + fname + ".cc" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cpp" if os.path.isfile(name): return name, 0 # if here, we still dont have a file match # if allowed to scan files, do that if scanfiles: #sys.stderr.write("Warning: Scaning for {}\n".format(fname)) for f in paths: files = list(f + "/" + a for a in os.listdir(f)) cc_files = fnmatch.filter(files, "*.cc") cpp_files = fnmatch.filter(files, "*.cpp") cxx_files = fnmatch.filter(files, "*.cxx") for fn in cc_files + cpp_files + cxx_files: line = find_defun_line_in_file(fn, fname) if line >= 0: #sys.stderr.write("Warning: Found function for {} in {} at {}\n".format(fname, fn, line)) return fn, line return None, -1 def display_standalone_header(): # make a file that doesnt need to be included in a texinfo file to # be valid print("@c mkfuncdocs output for a standalone function list") print("@include macros.texi") print("@ifnottex") print("@node Top") print("@top Function Documentation") print("Function documentation extracted from texinfo source in octave source files.") print("@contents") print("@end ifnottex") print("@node Function Reference") print("@chapter Function Reference") print("@cindex Function Reference") def display_standalone_footer(): print("@bye") def display_func(name, ref, help): print ("@c -----------------------------------------") print ("@subsection {}".format(name)) print ("@cindex {}".format(ref)) for l in help: print ("{}".format(l)) def process (args): options = { "verbose": False, "srcdir": [], "funcprefix": "", "ignore": [], "standalone": False, "allowscan": False } indexfile = "" for a in args: #print ("{}".format(a)) c=a.split("=") key=c[0] if len(c) > 1: val=c[1] else: val="" if key == "--verbose": options["verbose"] = True; if key == "--standalone": options["standalone"] = True; elif key == "--allowscan": options["allowscan"] = True; elif key == "--src-dir": if val: options["srcdir"].append(val); elif key == "--ignore": if val: options["ignore"].append(val); elif key == "--func-prefix": if val: options["funcprefix"] = val; elif val == "": if indexfile == "": indexfile = key if indexfile == "": raise Exception("No index filename") if len(options["srcdir"]) == 0: options["srcdir"].append("inst") #print "options=", options if options['standalone']: display_standalone_header() idx = read_index(indexfile, options["ignore"]) for g in idx.groups: #print ("************ {}".format(g.name)) g_name = texify_line(g.name) print ("@c ---------------------------------------------------") print ("@node {}".format(g_name)) print ("@section {}".format(g_name)) print ("@cindex {}".format(g_name)) for f in sorted(g.functions): print ("@c {} {}".format(g_name, f)) h = "" filename = "" path = "" if "@" in f: #print ("class func") path = f name = "@" + f ref = f.split("/")[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) elif "." in f: parts = f.split('.') cnt = 0 path = "" for p in parts: if cnt < len(parts)-1: path = path + "/+" else: path = path + "/" path = path + p cnt = cnt + 1 name = f; ref = parts[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) elif "/" in f: path = f name = f ref = f.split("/")[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) else: path = f name = f ref = f filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"], options['allowscan']) if not filename: sys.stderr.write("Warning: Cant find source file for {}\n".format(path)) else: h = read_help (filename, lineno) if h: display_func (name, ref, h) if options['standalone']: display_standalone_footer() def show_usage(): print (sys.argv[0], "[options] indexfile") if __name__ == "__main__": if len(sys.argv) > 1: status = process(sys.argv[1:]) sys.exit(status) else: show_usage() instrument-control-0.9.4/doc/mkqhcp.py0000755000000000000000000001212114743226261014751 0ustar00#!/usr/bin/python3 ## mkqhcp.py ## Version 1.0.3 ## Copyright 2022-2023 John Donoghue ## ## 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 ## . import sys import os import re def process(name): with open(name + ".qhcp", 'wt') as f: f.write ('\n') f.write ('\n') f.write (' \n') f.write (' \n') f.write (' \n') f.write (' {0}.qhp\n'.format(name)) f.write (' {0}.qch\n'.format(name)) f.write (' \n') f.write (' \n') f.write (' \n') f.write (' {0}.qch\n'.format(name)) f.write (' \n') f.write (' \n') f.write ('\n') title = name pat_match = re.compile(r".*(?P<title>[^<]+).*") with open(name + ".html", 'rt') as fin: # find html for line in fin: line = line.strip() e = pat_match.match(line) if e: title = e.group("title") break h2_match = re.compile(r'.*

]*>(?P[^<]+)</h2>.*') h3_match = re.compile(r'.*<h3 class="section"[^>]*>(?P<title>[^<]+)</h3>.*') h4_match = re.compile(r'.*<h4 class="subsection"[^>]*>(?P<title>[^<]+)</h4>.*') tag_match1 = re.compile(r'.*<span id="(?P<tag>[^"]+)"[^>]*></span>.*') #tag_match2 = re.compile(r'.*<div class="[sub]*section" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match2 = re.compile(r'.*<div class="[sub]*section[^"]*" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match3 = re.compile(r'.*<div class="chapter-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') index_match = re.compile(r'.*<h4 class="subsection"[^>]*>[\d\.\s]*(?P<name>[^<]+)</h4>.*') tag = "top" has_h2 = False has_h3 = False #pat_match = re.compile(r'.*<span id="(?P<tag>[^"])"></span>(?P<title>[.]+)$') with open(name + ".html", 'rt') as fin: with open(name + ".qhp", 'wt') as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write('<QtHelpProject version="1.0">\n') f.write(' <namespace>octave.community.{}</namespace>\n'.format(name)) f.write(' <virtualFolder>doc</virtualFolder>\n') f.write(' <filterSection>\n') f.write(' <toc>\n') f.write(' <section title="{} Manual" ref="{}.html">\n'.format(title, name)) # chapters here for line in fin: line = line.strip() e = tag_match1.match(line) if not e: e = tag_match2.match(line) if not e: e = tag_match3.match(line) if e: tag = e.group("tag") e = h2_match.match(line) if e: if has_h3: f.write(' </section>\n') has_h3 = False if has_h2: f.write(' </section>\n') has_h2 = True f.write(' <section title="{}" ref="{}.html#{}">\n'.format(e.group("title"), name, tag)) e = h3_match.match(line) if e: if has_h3: f.write(' </section>\n') has_h3 = True f.write(' <section title="{}" ref="{}.html#{}">\n'.format(e.group("title"), name, tag)) e = h4_match.match(line) if e: f.write(' <section title="{}" ref="{}.html#{}"></section>\n'.format(e.group("title"), name, tag)) if has_h3: f.write(' </section>\n') if has_h2: f.write(' </section>\n') f.write(' </section>\n') f.write(' </toc>\n') f.write(' <keywords>\n') fin.seek(0) for line in fin: line = line.strip() e = tag_match1.match(line) if not e: e = tag_match2.match(line) if e: tag = e.group("tag") e = index_match.match(line) if e: f.write(' <keyword name="{}" ref="{}.html#{}"></keyword>\n'.format(e.group("name"), name, tag)) f.write(' </keywords>\n') f.write(' <files>\n') f.write(' <file>{}.html</file>\n'.format(name)) f.write(' <file>{}.css</file>\n'.format(name)) f.write(' </files>\n') f.write(' </filterSection>\n') f.write('</QtHelpProject>\n') def show_usage(): print (sys.argv[0], "projname") if __name__ == "__main__": if len(sys.argv) > 1: status = process(sys.argv[1]) sys.exit(status) else: show_usage() �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/doc/version.texi�����������������������������������������������������������0000644�0000000�0000000�00000000147�14743226261�015476� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@c autogenerated from Makefile @set VERSION 0.9.4 @set PACKAGE instrument-control @set DATE 2025-01-19 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/����������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013324� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_gpib/���������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015706� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_gpib/fclose.m�������������������������������������������������0000644�0000000�0000000�00000001602�14743226261�017336� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes connection to GPIB device @var{obj} ## @end deftypefn ## TODO: function fclose(fd) gpib_close(fd); end ������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_gpib/fopen.m��������������������������������������������������0000644�0000000�0000000�00000001730�14743226261�017174� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens connection to GPIB device @var{obj} ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ����������������������������������������instrument-control-0.9.4/inst/@octave_gpib/fprintf.m������������������������������������������������0000644�0000000�0000000�00000003530�14743226261�017535� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013-2019 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} fprintf (@var{obj}, @var{cmd}) ## @deftypefnx {Function File} {} fprintf (@var{obj}, @var{format}, @var{cmd}) ## @deftypefnx {Function File} {} fprintf (@var{obj}, @var{cmd}, @var{mode}) ## @deftypefnx {Function File} {} fprintf (@var{obj}, @var{format}, @var{cmd}, @var{mode}) ## Writes string @var{cmd} to GPIB instrument ## ## @var{obj} is a GPIB object ## ## @var{cmd} String ## @var{format} Format specifier ## @var{mode} sync ## ## @end deftypefn ## TODO: function fprintf (obj, format, cmd, mode) defaultformat = '%s\n'; defaultmode = 'sync'; if ((nargin < 2) || (nargin > 4)) print_usage (); elseif (nargin < 3) format = defaultformat; mode = defaultmode; elseif (nargin < 4) %% decide for syntax if (!isempty (find (format == '%'))) %% detected: fprintf (obj, format, cmd)) mode = defaultmode; else %% fprintf (obj, cmd, mode) mode = cmd; cmd = format; format = defaultformat; end end if (! ( ischar (format) && ischar (mode) )) print_usage (); end if (strcmp (mode, 'async')) error ("async mode not supported yet"); end gpib_write (obj, sprintf (format, cmd)) end ������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_gpib/fread.m��������������������������������������������������0000644�0000000�0000000�00000006232�14743226261�017150� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2015-2021 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from GPIB instrument ## ## @var{obj} is a GPIB object ## ## @var{size} Number of values to read. (Default: 100) ## @var{precision} precision of data ## ## @var{count} values read ## @var{errmsg} read operation error message ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; end if (nargin < 3) precision = 'uchar'; end if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) [tmp1,wasread,eoi] = gpib_read (obj, toread); %% if successful tmp is never negative (uint8) count = count + wasread; toread = toread - wasread; if ((eoi) || (tmp1 < 0)) break; endif tmp = [tmp tmp1]; endwhile ## TODO: omit warning messages (if any) and output warning text to errmsg instead errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_gpib/fscanf.m�������������������������������������������������0000644�0000000�0000000�00000003533�14743226261�017330� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fscanf (@var{obj}) ## @deftypefnx {Function File} {@var{res} =} fscanf (@var{obj}, @var{format}) ## @deftypefnx {Function File} {@var{res} =} fscanf (@var{obj}, @var{format}, @var{size}) ## @deftypefnx {Function File} {[@var{res},@var{count}] =} fscanf (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{res},@var{count},@var{errmsg}] =} fscanf (@var{obj}, ...) ## Reads data @var{res} from GPIB instrument ## ## @var{obj} is a GPIB object ## ## @var{format} Format specifier ## @var{size} number of values ## ## @var{count} values read ## @var{errmsg} read operation error message ## ## @end deftypefn ## TODO: function [res, count, errmsg] = fscanf (obj, format, size) if (nargin < 1) print_usage (); end if (nargin < 2) format = '%c'; end % TODO: use a max buffer property? buffersize = 1e6; eoi=0; tmp = []; while (!eoi) [tmp1,~,eoi] = gpib_read (obj, buffersize); %% if successful tmp is never negative (uint8) if ((!eoi) || (tmp < 0)) break; end tmp = [tmp tmp1]; end if (nargin < 3) [res,count,errmsg]=sscanf (tmp,format); else [res,count,errmsg]=sscanf (tmp,format,size); end end ���������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_gpib/fwrite.m�������������������������������������������������0000644�0000000�0000000�00000004510�14743226261�017364� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {} fwrite (@var{obj}, @var{data}, @var{precision}) ## @deftypefnx {Function File} {} fwrite (@var{obj}, @var{data}, @var{mode}) ## @deftypefnx {Function File} {} fwrite (@var{obj}, @var{data}, @var{precision}, @var{mode}) ## Writes @var{data} to GPIB instrument ## ## @var{obj} is a GPIB object ## ## @var{data} data to write ## @var{precision} precision of data ## @var{mode} sync ## ## @end deftypefn ## TODO: function fwrite(obj, data, precision, mode) defaultmode = "sync"; if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; mode = defaultmode; elseif (nargin < 4) %% is 3rd argument precision or mode if (strcmp (precision,'sync') || strcmp (precision,'async')) mode = precision; precision = []; else mode = "sync"; end end if (strcmp (mode,'async')) error ("async mode not supported yet"); end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? gpib_write (obj, typecast(data,'uint8')); end ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_i2c/����������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015442� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_i2c/fclose.m��������������������������������������������������0000644�0000000�0000000�00000001566�14743226261�017103� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes I2C connection @var{obj} ## @end deftypefn ## TODO: function fclose(fd) i2c_close(fd); end ������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_i2c/fopen.m���������������������������������������������������0000644�0000000�0000000�00000001720�14743226261�016727� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens I2C connection @var{obj} ## ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ������������������������������������������������instrument-control-0.9.4/inst/@octave_i2c/fread.m���������������������������������������������������0000644�0000000�0000000�00000005752�14743226261�016712� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from I2C instrument ## ## @subsubheading Inputs ## @var{obj} is a I2C object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} data values.@* ## @var{count} number of values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; end if (nargin < 3) precision = 'uchar'; end if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); end eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = i2c_read (obj, toread); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; end tmp = [tmp tmp1]; end errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); end endfunction ����������������������instrument-control-0.9.4/inst/@octave_i2c/fwrite.m��������������������������������������������������0000644�0000000�0000000�00000003733�14743226261�017126� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to I2C instrument ## ## @subsubheading Inputs ## @var{obj} is a I2C object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? numbytes = i2c_write (obj, typecast(data,'uint8')); end �������������������������������������instrument-control-0.9.4/inst/@octave_i2c/get.m�����������������������������������������������������0000644�0000000�0000000�00000004065�14743226261�016404� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{i2c}) ## @deftypefnx {Function File} {@var{field} = } get (@var{i2c}, @var{property}) ## Get the properties of i2c object. ## ## @subsubheading Inputs ## @var{i2c} - instance of @var{octave_i2c} class.@* ## ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_i2c/set} ## @end deftypefn function retval = get (i2c, property) properties = {'name', 'remoteaddress', 'status', ... 'port'}; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); end if !iscell (property) property = {property}; end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("i2c:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); end property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __i2c_properties__ (i2c, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); end end ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_i2c/set.m�����������������������������������������������������0000644�0000000�0000000�00000005132�14743226261�016414� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of i2c object. ## ## @subsubheading Inputs ## @var{obj} - instance of @var{octave_i2c} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'name' ## Set the name for the i2c socket. ## ## @item 'remoteaddress' ## Set the remote address for the i2c socket. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_i2c/get} ## @end deftypefn function set (i2c, varargin) properties = {'remoteaddress', 'name' }; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; end if numel (property) != numel (value) error ('i2c:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("i2c:set:InvalidArgument", ... "Property '%s' not found in i2c object.\n",x); cellfun (msg, not_found); end property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __i2c_properties__ (i2c, property{i}, value{i}); end end ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_modbus/�������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�016256� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_modbus/get.m��������������������������������������������������0000644�0000000�0000000�00000004703�14743226261�017217� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John D <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{dev}) ## @deftypefnx {Function File} {@var{field} = } get (@var{dev}, @var{property}) ## Get the properties of modbus object. ## ## @subsubheading Inputs ## @var{dev} - instance of @var{octave_modbus} class.@* ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_modbus/set} ## @end deftypefn function retval = get (dev, property) if strcmp( __modbus_properties__ (dev, "Transport"), "tcpip") properties = {'Type', 'WordOrder', 'ByteOrder', 'Name', ... 'Timeout', 'UserData', 'Transport', 'Port', ... 'DeviceAddress', 'NumRetries' }; else properties = {'Type', 'WordOrder', 'ByteOrder', 'Name', ... 'Timeout', 'UserData', 'Transport', 'Port', ... 'BaudRate', 'DataBits', 'Parity', 'StopBits', ... 'NumRetries'}; endif if (nargin == 1) property = properties; elseif (nargin > 2) # TODO: multi properties ? error ("Too many arguments.\n"); endif if !iscell (property) property = {property}; endif valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("modbus:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __modbus_properties__ (dev, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); endif endfunction �������������������������������������������������������������instrument-control-0.9.4/inst/@octave_modbus/maskWrite.m��������������������������������������������0000644�0000000�0000000�00000004331�14743226261�020403� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} maskWrite (@var{dev}, @var{address}, @var{andmask}, @var{ormask}) ## @deftypefnx {} {@var{data} =} maskWrite (@var{dev}, @var{address}, @var{andmask}, @var{ormask}, @var{serverid}) ## Read holding register at @var{address} from modbus device @var{dev} apply masking and write the change data. ## ## writeregister value = (readregister value AND andMask) OR (orMask AND (NOT andMask)) ## ## @subsubheading Inputs ## @var{dev} - connected modbus device ## ## @var{address} - address to read from. ## ## @var{andmask} - AND mask to apply to the register ## ## @var{ormask} - OR mask to apply to the register ## ## @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. ## ## @subsubheading Outputs ## @var{data} - data read from the device ## ## @seealso{modbus} ## @end deftypefn function data = maskWrite (dev, address, andmask, ormask, serverid) if nargin < 4 print_usage(); endif if nargin < 5 serverid = 1; endif if ! isnumeric(address) || address < 0 error ("Expected address to be a number."); endif if ! isnumeric(ormask) error ("Expected ormask to be a number."); endif if ! isnumeric(andmask) error ("Expected andmask to be a number."); endif if ! isnumeric(serverid) || serverid < 0 || serverid > 247 error ("Expected serverId to be a number between 0 .. 247"); endif data = read(dev, "holdingregs", address, 1, serverid); # manipulate for if !isempty(data) value = data(1); value = bitand(value, andmask); value = bitor(value, ormask); data(1) = value; endif write(dev, "holdingregs", address, data, serverid); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_modbus/read.m�������������������������������������������������0000644�0000000�0000000�00000007565�14743226261�017364� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} read (@var{dev}, @var{target}, @var{address}) ## @deftypefnx {} {@var{data} =} read (@var{dev}, @var{target}, @var{address}, @var{count}) ## @deftypefnx {} {@var{data} =} read (@var{dev}, @var{target}, @var{address}, @var{count}, @var{serverId}, @var{precision}) ## Read data from modbus device @var{dev} target @var{target} starting at address @var{address}. ## ## @subsubheading Inputs ## @var{dev} - connected modbus device ## ## @var{target} - target type to read. One of 'coils', 'inputs', 'inputregs' or 'holdingregs' ## ## @var{address} - address to start reading from. ## ## @var{count} - number of elements to read. If not provided, count is 1. ## ## @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. ## ## @var{precision} - Optional precision for how to interpret the read data. ## Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. ## ## @subsubheading Outputs ## @var{data} - data read from the device ## ## @seealso{modbus} ## @end deftypefn function data = read (dev, target, address, count, serverid, precision) if nargin < 3 print_usage(); endif if nargin < 4 count = 1; endif if nargin < 5 serverid = 1; endif if nargin < 6 precision = "uint16"; endif if ! isnumeric(address) || address < 0 error ("Expected address to be a number."); endif if ! isnumeric(count) || count < 1 error ("Expected count to be a positive number."); endif if ! isnumeric(serverid) || serverid < 0 || serverid > 247 error ("Expected serverId to be a number between 0 .. 247"); endif if !ischar(precision) error ("Expected precision to be a character type"); endif # precision only used for inputregs and holdingregs switch (precision) case {"int16" "short"} toclass = "int16"; tosize = 1; case {"uint16" "ushort"} toclass = "uint16"; tosize = 1; case {"int32" "int"} toclass = "int32"; tosize = 2; case {"uint32" "uint"} toclass = "uint32"; tosize = 2; case {"long" "int64"} toclass = "int64"; tosize = 4; case {"ulong" "uint64"} toclass = "uint64"; tosize = 4; case {"single" "float" "float32"} toclass = "single"; tosize = 2; case {"double" "float64"} toclass = "double"; tosize = 4; otherwise error ("precision not supported"); endswitch switch (target) case "coils" # single bit output bits (count = 1 .. 2000) case "inputs" # single bit input regs case "inputregs" # 16 bit input read regs (count = 1 ... 125) case "holdingregs" # 16 bit read/write reg otherwise error ("Invalid target type"); endswitch # number of actual regs to read toread = count * tosize; data = __modbus_read__(dev, target, address, toread, serverid); # Check Word Endian settings, swap word order if required mbwordendian = get(dev,"WordOrder"); # Modbus word endian [a,b,cowordendian] = computer(); # machine endian if ( tosize>1 && ( strcmp(mbwordendian,"big-endian") && strcmp(cowordendian,"L") || ... strcmp(mbwordendian,"littler-endian") && strcmp(cowordendian,"B") ) ) # swap word order data = reshape( flip( reshape( data, tosize, count ) ), 1, toread ) end # type conversion data = typecast( data, toclass ); endfunction �������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_modbus/set.m��������������������������������������������������0000644�0000000�0000000�00000005573�14743226261�017241� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of modbus object. ## ## @subsubheading Inputs ## @var{obj} - instance of @var{octave_modbus} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'Name' ## Set the stored string name of the object. ## ## @item 'Timeout' ## Set the timeout value. ## ## @item 'Numretries' ## Set the numretries value. ## ## @item 'ByteOrder' ## Set the byteorder value ## ## @item 'WordOrder' ## Set the wordorder value ## ## @item 'UserData' ## Set the userdata value ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_modbus/get} ## @end deftypefn function set (dev, varargin) properties = {'Name', 'Timeout', 'ByteOrder', 'WordOrder', ... 'UserData', 'NumRetries'}; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; endif if numel (property) != numel (value) error ('modbus:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); endif property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("modbus:set:InvalidArgument", ... "Property '%s' not found in serial object.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __modbus_properties__ (dev, property{i}, value{i}); endfor endfunction �������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_modbus/write.m������������������������������������������������0000644�0000000�0000000�00000005733�14743226261�017576� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} write (@var{dev}, @var{target}, @var{address}, @var{values}) ## @deftypefnx {} {} read (@var{dev}, @var{target}, @var{address}, @var{values}, @var{serverId}, @var{precision}) ## Write data @var{data} to modbus device @var{dev} target @var{target} starting at address @var{address}. ## ## @subsubheading Inputs ## @var{dev} - connected modbus device ## ## @var{target} - target type to read. One of 'coils' or 'holdingregs' ## ## @var{address} - address to start reading from. ## ## @var{data} - data to write. ## ## @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. ## ## @var{precision} - Optional precision for how to interpret the write data. ## Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. ## ## @subsubheading Outputs ## None ## ## @seealso{modbus} ## @end deftypefn function write (dev, target, address, data, serverid, precision) if nargin < 4 print_usage(); endif if nargin < 5 serverid = 1; endif if nargin < 6 precision = "uint16"; endif if ! isnumeric(address) || address < 0 error ("Expected address to be a number."); endif if ! isnumeric(serverid) || serverid < 0 || serverid > 247 error ("Expected serverId to be a number between 0 .. 247"); endif if !ischar(precision) error ("Expected precision to be a character type"); endif # precision only used for holdingregs switch (precision) case {"int16" "short"} toclass = "int16"; tosize = 2; case {"uint16" "ushort"} toclass = "uint16"; tosize = 2; case {"int32" "int"} toclass = "int32"; tosize = 4; case {"uint32" "uint"} toclass = "uint32"; tosize = 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; tosize = 4; case {"double" "float64"} toclass = "double"; tosize = 8; otherwise error ("precision not supported"); endswitch switch (target) case "coils" # single bit output bits (count = 1 .. 2000) data = uint8(data); case "holdingregs" # 16 bit read/write reg data = uint16(data); otherwise error ("Invalid target type"); endswitch #data = typecast(tmp,toclass); numbytes = __modbus_write__(dev, target, address, data, serverid); endfunction �������������������������������������instrument-control-0.9.4/inst/@octave_modbus/writeRead.m��������������������������������������������0000644�0000000�0000000�00000010223�14743226261�020360� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} writeRead (@var{dev}, @var{writeAddress}, @var{values}, @var{readAddress}, @var{readcount}) ## @deftypefnx {} {@var{data} =} writeRead (@var{dev}, @var{writeAddress}, @var{values}, @var{readAddress}, @var{readcount}, @var{serverId}) ## @deftypefnx {} {@var{data} =} writeRead (@var{dev}, @var{writeAddress}, @var{values}, @var{writePrecision}, @var{readAddress}, @var{readCount}, @var{readPrecision}) ## Write data @var{values} to the modbus device @var{dev} holding registers starting at address @var{writeAddress} ## and then read @var{readCount} register values starting at address @var{readAddress}. ## ## @subsubheading Inputs ## @var{dev} - connected modbus device ## ## @var{writeAddress} - address to start writing to. ## ## @var{values} - data to write to the device. ## ## @var{readAddress} - address to start reading from. ## ## @var{readCount} - number of elements to read. ## ## @var{serverId} - address to send to (0-247). Default of 1 is used if not specified. ## ## @var{precision} - Optional precision for how to interpret the read data. ## Currently known precision values are uint16 (default), int16, uint32, int32, uint64, uint64, single, double. ## ## @subsubheading Outputs ## @var{data} - data read from the device ## ## @seealso{modbus} ## @end deftypefn function data = writeRead (varargin) # num args should be 5, 6 or 7 if nargin < 5 || nargin > 7 print_usage(); endif dev = varargin{1}; writeAddress = varargin{2}; values = varargin{3}; if nargin == 7 writePrecision = varargin{4}; readAddress = varargin{5}; readCount = varargin{6}; readPrecision = varargin{7}; serverId = 1; else writePrecision = "uint16"; readPrecision = "uint16"; readAddress = varargin{4}; readCount = varargin{5}; if nargin == 6 serverId = varargin{6} else serverId = 1; endif endif if ! isnumeric(writeAddress) || writeAddress < 0 error ("Expected writeAddress to be a number."); endif if ! isnumeric(readAddress) || readAddress < 0 error ("Expected readAddress to be a number."); endif if ! isnumeric(readCount) || readCount < 1 error ("Expected readCount to be a positive number."); endif if ! isnumeric(serverId) || serverId < 0 || serverId > 247 error ("Expected serverId to be a number between 0 .. 247"); endif if !ischar(readPrecision) error ("Expected readPrecision to be a character type"); endif if !ischar(writePrecision) error ("Expected writePrecision to be a character type"); endif toread = readCount; # precision only used for inputregs and holdingregs # TODO: current doesnt use the precision switch (readPrecision) case {"int16" "short"} toclass = "int16"; tosize = 2; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; tosize = 2; toread = toread * 2; case {"int32" "int"} toclass = "int32"; tosize = 4; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; tosize = 4; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; tosize = 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; tosize = 8; case {"single" "float" "float32"} toclass = "single"; tosize = 4; toread = toread * 4; case {"double" "float64"} toclass = "double"; tosize = 8; toread = toread * 8; otherwise error ("readPrecision not supported"); endswitch data = uint16(values) data = __modbus_write_read__(dev, writeAddress, data, readAddress, readCount, serverId); endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_parallel/�����������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�016561� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_parallel/fclose.m���������������������������������������������0000644�0000000�0000000�00000001665�14743226261�020222� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes parallel connection @var{obj} ## @end deftypefn function fclose(pp) if (nargin == 1) pp_close (pp); else print_usage(); end end ���������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_parallel/fopen.m����������������������������������������������0000644�0000000�0000000�00000001740�14743226261�020050� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens parallel interface @var{obj} ## ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ��������������������������������instrument-control-0.9.4/inst/@octave_parallel/fread.m����������������������������������������������0000644�0000000�0000000�00000006003�14743226261�020017� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from parallel instrument ## ## @subsubheading Inputs ## @var{obj} is a parallel object.@* ## @var{size} Number of values to read. (Default: 1).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} The read data.@* ## @var{count} values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) size = 1; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) [tmp1,tmpc] = pp_data (obj); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_parallel/fwrite.m���������������������������������������������0000644�0000000�0000000�00000003743�14743226261�020246� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to parallel instrument ## ## @subsubheading Inputs ## @var{obj} is a parallel object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? numbytes = pp_data (obj, typecast(data,'uint8')); end �����������������������������instrument-control-0.9.4/inst/@octave_serial/�������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�016244� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/fclose.m�����������������������������������������������0000644�0000000�0000000�00000001714�14743226261�017700� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes SERIAL connection @var{obj} ## @end deftypefn ## TODO: function fclose(serial) if (nargin == 1) __srl_properties__ (serial, 'close'); else print_usage(); end end ����������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/flushinput.m�������������������������������������������0000644�0000000�0000000�00000002133�14743226261�020622� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} flushinput (@var{serial}) ## ## Flush the pending input, which will also make the BytesAvailable property be 0. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class. ## ## @subsubheading Outputs ## None ## ## @seealso{srl_flush, flushoutput} ## @end deftypefn function flushinput (serial, q) __srl_properties__ (serial, 'flush', 1); end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/flushoutput.m������������������������������������������0000644�0000000�0000000�00000002045�14743226261�021025� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} flushoutput (@var{serial}) ## ## Flush the output buffer. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class. ## ## @subsubheading Outputs ## None ## ## @seealso{srl_flush, flushinput} ## @end deftypefn function flushoutput (serial, q) __srl_properties__ (serial, 'flush', 0); end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/fopen.m������������������������������������������������0000644�0000000�0000000�00000001722�14743226261�017533� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens SERIAL interface @var{obj} ## ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ����������������������������������������������instrument-control-0.9.4/inst/@octave_serial/fprintf.m����������������������������������������������0000644�0000000�0000000�00000003000�14743226261�020063� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) ## Writes formatted string @var{template} using optional parameters to ## serial instrument ## ## @subsubheading Inputs ## @var{obj} is a serial object.@* ## @var{template} Format template string ## ## @subsubheading Outputs ## @var{numbytes} - number of bytes written to the serial device. ## ## @end deftypefn function numbytes = fprintf (varargin) defaultformat = '%s\n'; if (nargin < 2) print_usage (); elseif (nargin < 3) formargs = varargin(2); format = defaultformat; else formargs = varargin(3:nargin); format = varargin{2}; endif if (! ( ischar (format))) print_usage (); endif numbytes = srl_write (varargin{1}, sprintf (format, formargs{:})); endfunction instrument-control-0.9.4/inst/@octave_serial/fread.m������������������������������������������������0000644�0000000�0000000�00000006231�14743226261�017505� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from serial instrument ## ## @subsubheading Inputs ## @var{obj} is a serial object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} The read data.@* ## @var{count} values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = srl_read (obj, toread); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/fwrite.m�����������������������������������������������0000644�0000000�0000000�00000003741�14743226261�017727� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to serial instrument ## ## @subsubheading Inputs ## @var{obj} is a serial object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? numbytes = srl_write (obj, typecast(data,'uint8')); end �������������������������������instrument-control-0.9.4/inst/@octave_serial/get.m��������������������������������������������������0000644�0000000�0000000�00000004407�14743226261�017206� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John D <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{serial}) ## @deftypefnx {Function File} {@var{field} = } get (@var{serial}, @var{property}) ## Get the properties of serial object. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_serial/set} ## @end deftypefn function retval = get (serial, property) properties = {'name', 'type', 'status', 'baudrate', 'bytesize', 'parity', ... 'stopbits', 'timeout', 'requesttosend', ... 'dataterminalready', 'pinstatus', 'bytesavailable', ... 'port'}; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); end if !iscell (property) property = {property}; end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("serial:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); end property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __srl_properties__ (serial, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); end end ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/serialbreak.m������������������������������������������0000644�0000000�0000000�00000002430�14743226261�020705� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} serialbreak (@var{serial}) ## @deftypefnx {Function File} {} serialbreak (@var{serial}, @var{time}) ## Send a break to the serial port ## ## @subsubheading Inputs ## @var{serial} - serial object@* ## @var{time} - number of milliseconds to break for. If not specified a value of 10 will be used. ## ## @subsubheading Outputs ## None ## ## @seealso{serial} ## @end deftypefn function serialbreak (serial, mstime) if (nargin == 1) mstime = 10; elseif (nargin > 2) error ("Too many arguments.\n"); end __srl_properties__ (serial, 'break', mstime); end ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/set.m��������������������������������������������������0000644�0000000�0000000�00000007142�14743226261�017221� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of serial object. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'baudrate' ## Set the baudrate of serial port. Supported values by instrument-control: ## 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, ## 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your ## serial port may be different. ## ## @item 'bytesize' ## Set the bytesize. Supported values: 5, 6, 7 and 8. ## ## @item 'name' ## Set the stored string name of the serial object. ## ## @item 'parity' ## Set the parity value. Supported values: Even/Odd/None. This Parameter ## must be of type string. It is case insensitive and can be abbreviated ## to the first letter only ## ## @item 'stopbits' ## Set the number of stopbits. Supported values: 1, 2. ## ## @item 'timeout' ## Set the timeout value in tenths of a second. Value of -1 means a ## blocking call. Maximum value of 255 (i.e. 25.5 seconds). ## ## @item 'requesttosend' ## Set the requesttosend (RTS) line. ## ## @item 'dataterminalready' ## Set the dataterminalready (DTR) line. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_serial/get} ## @end deftypefn function set (serial, varargin) properties = {'name', 'baudrate','bytesize','parity','stopbits','timeout', ... 'requesttosend','dataterminalready'}; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; end if numel (property) != numel (value) error ('serial:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("serial:set:InvalidArgument", ... "Property '%s' not found in serial object.\n",x); cellfun (msg, not_found); end property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __srl_properties__ (serial, property{i}, value{i}); end end ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_baudrate.m�����������������������������������������0000644�0000000�0000000�00000003441�14743226261�021073� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_baudrate (@var{serial}, @var{baudrate})\ ## @deftypefnx {Loadable Function} {@var{br} = } srl_baudrate (@var{serial}) ## ## Set new or get existing serial interface baudrate parameter. Only standard values are supported. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{baudrate} - the baudrate value used. Supported values: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600 19200, 38400, 57600, 115200 and 230400.@* ## ## If @var{baudrate} parameter is omitted, the srl_baudrate() shall return current baudrate value as the result @var{br}. ## ## @subsubheading Outputs ## @var{br} - The currently set baudrate ## ## This function is obsolete. Use get and set method instead. ## ## @end deftypefn function retval = srl_baudrate (serial, baudrate) try if (nargin>1) __srl_properties__ (serial, 'baudrate', baudrate); else retval = __srl_properties__ (serial, 'baudrate'); end catch print_usage(); end end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_bytesize.m�����������������������������������������0000644�0000000�0000000�00000003275�14743226261�021147� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_bytesize (@var{serial}, @var{bsize}) ## @deftypefnx {Loadable Function} {@var{bs} = } srl_bytesize (@var{serial}) ## ## Set new or get existing serial interface byte size parameter. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{bsize} - byte size of type Integer. Supported values: 5/6/7/8.@* ## ## If @var{bsize} parameter is omitted, the srl_bytesize() shall return current byte size value ## or in case of unsupported setting -1, as the result @var{bs}. ## ## This function is obsolete. Use get and set method instead. ## ## @subsubheading Outputs ## @var{bs} -the currently set byte size. ## ## @end deftypefn function retval = srl_bytesize (serial, bytesize) try if (nargin>1) __srl_properties__ (serial, 'bytesize', bytesize); else retval = __srl_properties__ (serial, 'bytesize'); end catch print_usage(); end end �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_close.m��������������������������������������������0000644�0000000�0000000�00000002300�14743226261�020402� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_close (@var{serial}) ## ## Close the interface and release a file descriptor. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class. ## ## This function is obsolete. Use fclose() method instead. ## ## @subsubheading Outputs ## None ## ## @end deftypefn function srl_close (serial) try __srl_properties__ (serial, 'close'); catch print_usage(); end end ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_flush.m��������������������������������������������0000644�0000000�0000000�00000003040�14743226261�020420� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_flush (@var{serial}, [@var{q}]) ## ##Flush the pending input/output. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{q} - queue selector of type Integer. Supported values:@* ## @table @asis ## @item 0 ## flush untransmitted output ## @item 1 ## flush pending input ## @item 2 ## flush both pending input and untransmitted output. ## @end table ## ## If @var{q} parameter is omitted, the srl_flush() shall flush both, input and output buffers. ## ## @subsubheading Outputs ## None ## ## @end deftypefn function srl_flush (serial, q) try if (nargin>1) __srl_properties__ (serial, 'flush', q); else __srl_properties__ (serial, 'flush'); end catch print_usage(); end end ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_parity.m�������������������������������������������0000644�0000000�0000000�00000003350�14743226261�020613� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_parity (@var{serial}, @var{parity}) ## @deftypefnx {Loadable Function} {@var{p} = } srl_parity (@var{serial}) ## ## Set new or get existing serial interface parity parameter. Even/Odd/None values are supported. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{parity} - parity value of type String. Supported values: ## Even/Odd/None (case insensitive, can be abbreviated to the first letter only)@* ## ## If @var{parity} parameter is omitted, the srl_parity() shall return current parity value as the result @var{p}. ## ## This function is obsolete. Use get and set method instead. ## ## @subsubheading Outputs ## @var{p} - The currently set parity ## ## @end deftypefn function retval = srl_parity (serial, parity) try if (nargin>1) __srl_properties__ (serial, 'parity', parity); else retval = __srl_properties__ (serial, 'parity'); end catch print_usage(); end end ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_stopbits.m�����������������������������������������0000644�0000000�0000000�00000003207�14743226261�021153� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_stopbits (@var{serial}, @var{stopb}) ## @deftypefnx {Loadable Function} {@var{sb} = } srl_stopbits (@var{serial}) ## ## Set new or get existing serial interface stop bits parameter. Only 1 or 2 stop bits are supported. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{stopb} - number of stop bits used. Supported values: 1, 2.@* ## ## @subsubheading Outputs ## If @var{stopb} parameter is omitted, the srl_stopbits() shall return current stop bits value as the result @var{sb}. ## ## This function is obsolete. Use get and set method instead. ## ## @end deftypefn function retval = srl_stopbits (serial, stopbits) try if (nargin>1) __srl_properties__ (serial, 'stopbits', stopbits); else retval = __srl_properties__ (serial, 'stopbits'); end catch print_usage(); end end �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serial/srl_timeout.m������������������������������������������0000644�0000000�0000000�00000003375�14743226261�021000� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> ## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} srl_timeout (@var{serial}, @var{timeout}) ## @deftypefnx {Loadable Function} {@var{t} = } srl_timeout (@var{serial}) ## ## Set new or get existing serial interface timeout parameter used for srl_read() requests. The timeout value is specified in tenths of a second. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serial} class.@* ## @var{timeout} - srl_read() timeout value in tenths of a second. ## A value of -1 means a blocking call. Maximum value of 255 (i.e. 25.5 seconds).@* ## ## @subsubheading Outputs ## If @var{timeout} parameter is omitted, the srl_timeout() shall return current timeout value as the result @var{t}. ## ## This function is obsolete. Use get and set method instead. ## ## @end deftypefn function retval = srl_timeout (serial, timeout) try if (nargin>1) __srl_properties__ (serial, 'timeout', timeout); else retval = __srl_properties__ (serial, 'timeout'); end catch print_usage(); end end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/���������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�017151� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/configureTerminator.m������������������������������0000644�0000000�0000000�00000003260�14743226261�023356� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} configureTerminator (@var{serial}, @var{term}) ## @deftypefnx {Function File} {} configureTerminator (@var{serial}, @var{readterm}, @var{writeterm}) ## Set terminator for ASCII string manipulation ## ## @subsubheading Inputs ## @var{serial} - serialport object@* ## @var{term} - terminal value for both read and write@* ## @var{readterm} = terminal value type for read data@* ## @var{writeterm} = terminal value for written data@* ## ## The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. ## ## @subsubheading Outputs ## None ## ## @seealso{serialport} ## @end deftypefn function configureTerminator (serial, readterm, writeterm) if nargin < 2 error ("Expected terminal"); elseif nargin == 2 __srlp_properties__ (serial, 'terminator', readterm); elseif nargin == 3 __srlp_properties__ (serial, 'terminator', readterm, writeterm); else error ("Expected read and write terminal only"); endif endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/flush.m��������������������������������������������0000644�0000000�0000000�00000003051�14743226261�020447� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the serial port buffers ## ## @subsubheading Inputs ## @var{dev} - connected serialport device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{serialport} ## @end deftypefn function flush (dev, flushdir) if nargin < 2 __srlp_properties__ (dev, '__flush__', 0); __srlp_properties__ (dev, '__flush__', 1); else if !ischar (flushdir) error("flush: expected flushdir to be a string"); endif if strcmp(flushdir, "output") __srlp_properties__ (dev, '__flush__', 0); elseif strcmp(flushdir, "input") __srlp_properties__ (dev, '__flush__', 1); else error("flush: invalid flushdir '%s'", flushdir); endif endif endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/fprintf.m������������������������������������������0000644�0000000�0000000�00000003015�14743226261�020776� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) ## Writes formatted string @var{template} using optional parameters to ## serialport instrument ## ## @subsubheading Inputs ## @var{obj} is a serialport object.@* ## @var{template} Format template string ## ## @subsubheading Outputs ## @var{numbytes} - number of bytes written to the serial device. ## ## @end deftypefn function numbytes = fprintf (varargin) defaultformat = '%s\n'; if (nargin < 2) print_usage (); elseif (nargin < 3) formargs = varargin(2); format = defaultformat; else formargs = varargin(3:nargin); format = varargin{2}; endif if (! ( ischar (format))) print_usage (); endif numbytes = __srlp_write__ (varargin{1}, sprintf (format, formargs{:})); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/fread.m��������������������������������������������0000644�0000000�0000000�00000003335�14743226261�020414� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from serial port instrument ## ## @subsubheading Inputs ## @var{obj} is a serialport object.@* ## @var{size} Number of values to read.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} The read data.@* ## @var{count} number of values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) size = get(obj, 'NumBytesAvailable'); end if (nargin < 3) precision = 'uchar'; end data = read(obj,size, precision); errmsg = ''; count = numel(data); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/fwrite.m�������������������������������������������0000644�0000000�0000000�00000002534�14743226261�020633� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to serial port instrument ## ## @subsubheading Inputs ## @var{obj} is a serial port object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; endif numbytes = write (obj, data, precision); endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/get.m����������������������������������������������0000644�0000000�0000000�00000004320�14743226261�020105� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John D <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{serial}) ## @deftypefnx {Function File} {@var{field} = } get (@var{serial}, @var{property}) ## Get the properties of serialport object. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serialport} class.@* ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_serial/set} ## @end deftypefn function retval = get (serial, property) properties = {'Port', 'BaudRate', 'NumBytesAvailable', 'NumBytesWritten', ... 'ByteOrder', 'DataBits', 'StopBits', 'Parity', 'FlowControl', ... 'Timeout', 'Terminator', 'UserData'}; if (nargin == 1) property = properties; elseif (nargin > 2) # TODO: multi properties ? error ("Too many arguments.\n"); end if !iscell (property) property = {property}; end valid = ismember (tolower(property), tolower(properties)); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("serialport:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); end property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __srlp_properties__ (serial, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); end end ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/getpinstatus.m�������������������������������������0000644�0000000�0000000�00000002220�14743226261�022055� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{status}} getpinstatus (@var{serial}) ## Get status of serial pins ## ## @subsubheading Inputs ## @var{serial} - serial object@* ## ## @subsubheading Outputs ## @var{status} - a structure with the logic names of ClearToSend, DataSetReady, CarrierDetect, and RingIndicator ## ## @seealso{serialport} ## @end deftypefn function status = getpinstatus (serial) status = __srlp_properties__ (serial, '__pinstatus__'); endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/read.m���������������������������������������������0000644�0000000�0000000�00000005414�14743226261�020246� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} read (@var{dev}, @var{count}) ## @deftypefnx {} {@var{data} =} read (@var{dev}, @var{count}, @var{precision}) ## Read a specified number of values from a serialport ## using optional precision for valuesize. ## ## @subsubheading Inputs ## @var{dev} - connected serialport device ## ## @var{count} - number of elements to read ## ## @var{precision} - Optional precision for the output data read data. ## Currently known precision values are uint8 (default), int8, uint16, int16, uint32, int32, uint64, uint64 ## ## @subsubheading Outputs ## @var{data} - data read from the device ## ## @seealso{serialport} ## @end deftypefn function data = read (dev, count, precision) if nargin < 2 print_usage(); endif if nargin < 3 precision = "uint8"; endif if !ischar(precision) error ("Expected precision to be a character type"); endif toread = count; switch (precision) case {"string"} toclass = "char"; tosize = 1; case {"char" "schar" "int8"} toclass = "int8"; tosize = 1; case {"uchar" "uint8"} toclass = "uint8"; tosize = 1; case {"int16" "short"} toclass = "int16"; tosize = 2; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; tosize = 2; toread = toread * 2; case {"int32" "int"} toclass = "int32"; tosize = 4; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; tosize = 4; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; tosize = 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; tosize = 8; case {"single" "float" "float32"} toclass = "single"; tosize = 4; toread = toread * 4; case {"double" "float64"} toclass = "double"; tosize = 8; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = __srlp_read__ (dev, toread); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile data = typecast(tmp,toclass); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/serialbreak.m��������������������������������������0000644�0000000�0000000�00000002441�14743226261�021614� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} serialbreak (@var{serial}) ## @deftypefnx {Function File} {} serialbreak (@var{serial}, @var{time}) ## Send a break to the serial port ## ## @subsubheading Inputs ## @var{serial} - serialport object@* ## @var{time} - number of milliseconds to break for. If not specified a value of 10 will be used. ## ## @subsubheading Outputs ## None ## ## @seealso{serial} ## @end deftypefn function serialbreak (serial, mstime) if (nargin == 1) mstime = 10; elseif (nargin > 2) error ("Too many arguments.\n"); end __srlp_properties__ (serial, '__break__', mstime); end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/set.m����������������������������������������������0000644�0000000�0000000�00000007057�14743226261�020133� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of serialport object. ## ## @subsubheading Inputs ## @var{serial} - instance of @var{octave_serialport} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'baudrate' ## Set the baudrate of serial port. Supported values by instrument-control: ## 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, ## 19200, 38400, 57600, 115200 and 230400. The supported baudrate of your ## serial port may be different. ## ## @item 'bytesize' ## Set the bytesize. Supported values: 5, 6, 7 and 8. ## ## @item 'name' ## Set the stored string name of the serial object. ## ## @item 'parity' ## Set the parity value. Supported values: Even/Odd/None. This Parameter ## must be of type string. It is case insensitive and can be abbreviated ## to the first letter only ## ## @item 'stopbits' ## Set the number of stopbits. Supported values: 1, 2. ## ## @item 'timeout' ## Set the timeout value in tenths of a second. Value of -1 means a ## blocking call. Maximum value of 255 (i.e. 25.5 seconds). ## ## @item 'requesttosend' ## Set the requesttosend (RTS) line. ## ## @item 'dataterminalready' ## Set the dataterminalready (DTR) line. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_serialport/-get} ## @end deftypefn function set (serial, varargin) properties = {'name', 'baudrate','databits','parity','stopbits','timeout', ... 'flowcontrol', 'userdata'}; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; end if numel (property) != numel (value) error ('serial:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("serial:set:InvalidArgument", ... "Property '%s' not found in serial object.\n",x); cellfun (msg, not_found); end property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __srlp_properties__ (serial, property{i}, value{i}); end end ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/setDTR.m�������������������������������������������0000644�0000000�0000000�00000002215�14743226261�020474� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} setDTR (@var{dev}, @var{true_false}) ## Set the state of the DTR line ## ## @subsubheading Inputs ## @var{dev} - connected serial device.@* ## @var{true_false} - state to set the line.@* ## ## @subsubheading Outputs ## None ## ## @seealso{serialport, getpinstatus, setRTS} ## @end deftypefn function setDTR (dev, tf) if nargin < 2 print_usage(); else if !islogical (tf) && !isnumeric(tf) error("setDTR expected pin state to be true or false"); endif __srlp_properties__ (dev, "__dataterminalready__", tf); endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/setRTS.m�������������������������������������������0000644�0000000�0000000�00000002201�14743226261�020506� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} setRTS (@var{dev}, @var{true_false}) ## Set the state of the RTS line ## ## @subsubheading Inputs ## @var{dev} - connected serial device.@* ## @var{true_false} - state to set the line.@* ## ## @subsubheading Outputs ## None ## ## @seealso{serialport, getpinstatus} ## @end deftypefn function setRTS (dev, tf) if nargin < 2 print_usage(); else if !islogical (tf) && !isnumeric(tf) error("setRTS expected pin state to be true or false"); endif __srlp_properties__ (dev, "__requesttosend__", tf); endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_serialport/write.m��������������������������������������������0000644�0000000�0000000�00000004073�14743226261�020465� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to serialport instrument ## ## @subsubheading Inputs ## @var{obj} is a serialport object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; endif switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); endswitch %% should we handle endianess ? numbytes = __srlp_write__ (obj, typecast(data,'uint8')); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/����������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015560� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/fclose.m��������������������������������������������������0000644�0000000�0000000�00000001600�14743226261�017206� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes SPI connection @var{obj} ## @end deftypefn function fclose(fd) spi_close(fd); endfunction ��������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/fopen.m���������������������������������������������������0000644�0000000�0000000�00000001744�14743226261�017053� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens SPI connection @var{obj} ## ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility endfunction ����������������������������instrument-control-0.9.4/inst/@octave_spi/fread.m���������������������������������������������������0000644�0000000�0000000�00000006230�14743226261�017020� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from a SPI instrument ## ## @subsubheading Inputs ## @var{obj} is a SPI object.@* ## @var{size} Number of values to read. (Default: 10).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} data values.@* ## @var{count} number of values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 10 as default"); size = 10; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = spi_read (obj, toread); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; end tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/fwrite.m��������������������������������������������������0000644�0000000�0000000�00000003753�14743226261�017246� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to SPI instrument ## ## @subsubheading Inputs ## @var{obj} is a SPI object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; endif switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); endswitch %% should we handle endianess ? numbytes = spi_write (obj, typecast(data,'uint8')); endfunction ���������������������instrument-control-0.9.4/inst/@octave_spi/get.m�����������������������������������������������������0000644�0000000�0000000�00000005054�14743226261�016521� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{spi}) ## @deftypefnx {Function File} {@var{field} = } get (@var{spi}, @var{property}) ## Get the properties of spi object. ## ## @subsubheading Inputs ## @var{spi} - instance of @var{octave_spi} class.@* ## ## @var{property} - name of property.@* ## ## @subsubheading Properties ## @table @var ## @item 'name' ## Name for the spi socket. ## ## @item 'bitrate' ## The bitrate for the spi object. ## ## @item 'clockpolarity' ## The clock polarity for the spi object of 'idlehigh' or 'idlelow'. ## ## @item 'clockphase' ## The clock phase for the spi object of 'firstedge' or 'secondedge'. ## ## @item 'port' ## The device port name. ## ## @item 'status' ## The device status of 'open' or 'closed' ## @end table ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_spi/set} ## @end deftypefn function retval = get (spi, property) properties = {'name', 'bitrate', 'status', ... 'port', 'clockpolarity', 'clockphase'}; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); endif if !iscell (property) property = {property}; endif property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("spi:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __spi_properties__ (spi, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); endif endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/read.m����������������������������������������������������0000644�0000000�0000000�00000002332�14743226261�016651� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} read (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) ## Reads @var{data} from SPI instrument ## ## @subsubheading Inputs ## @var{obj} is a SPI object.@* ## @var{size} Number of values to read. (Default: 10).@* ## ## @subsubheading Outputs ## @var{data} data values.@* ## ## @end deftypefn function data = read (obj, size) if (nargin < 2) error("read: Size expected"); endif data = spi_read (obj, size); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/set.m�����������������������������������������������������0000644�0000000�0000000�00000005477�14743226261�016546� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of spi object. ## ## @subsubheading Inputs ## @var{obj} - instance of @var{octave_spi} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'name' ## Set the name for the spi socket. ## ## @item 'bitrate' ## Set the bitrate for the spi object. ## ## @item 'clockpolarity' ## Set the clock polarity for the spi object of 'idlehigh' or 'idlelow'. ## ## @item 'clockphase' ## Set the clock phase for the spi object of 'firstedge' or 'secondedge'. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_spi/get} ## @end deftypefn function set (spi, varargin) properties = {'bitrate', 'name', 'clockpolarity', 'clockphase' }; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; endif if numel (property) != numel (value) error ('spi:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); endif property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("spi:set:InvalidArgument", ... "Property '%s' not found in spi object.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __spi_properties__ (spi, property{i}, value{i}); endfor endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/write.m���������������������������������������������������0000644�0000000�0000000�00000002214�14743226261�017067� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## Writes @var{data} to SPI instrument ## ## @subsubheading Inputs ## @var{obj} is a SPI object.@* ## @var{data} data to write.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data) if (nargin < 2) print_usage (); endif numbytes = spi_write (obj, uint8(data)); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_spi/writeAndRead.m��������������������������������������������0000644�0000000�0000000�00000002262�14743226261�020311� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} writeAndRead (@var{obj}, @var{wrdata}) ## Writes and reads @var{data} from SPI instrument ## ## @subsubheading Inputs ## @var{obj} is a SPI object.@* ## @var{wrdata} Data to write.@* ## ## @subsubheading Outputs ## @var{data} data values read.@* ## ## @end deftypefn function data = writeAndRead (obj, wrdata) if (nargin < 2) error("expected data to write"); endif data = spi_writeAndRead(obj, uint8(wrdata)); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/����������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015553� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/fclose.m��������������������������������������������������0000644�0000000�0000000�00000001566�14743226261�017214� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes TCP connection @var{obj} ## @end deftypefn ## TODO: function fclose(fd) tcp_close(fd); end ������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/flush.m���������������������������������������������������0000644�0000000�0000000�00000003015�14743226261�017051� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the tcp socket buffers ## ## @subsubheading Inputs ## @var{dev} - connected tcp device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{serialport} ## @end deftypefn function flush (dev, flushdir) if nargin < 2 __tcp_properties__ (dev, 'flush', 0); __tcp_properties__ (dev, 'flush', 1); else if !ischar (flushdir) error("flush: expected flushdir to be a string"); endif if strcmp(flushdir, "output") __tcp_properties__ (dev, 'flush', 0); elseif strcmp(flushdir, "input") __tcp_properties__ (dev, 'flush', 1); else error("flush: invalid flushdir '%s'", flushdir); endif endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/flushinput.m����������������������������������������������0000644�0000000�0000000�00000002075�14743226261�020136� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} flushinput (@var{tcp}) ## ## Flush the pending input, which will also make the BytesAvailable property be 0. ## ## @subsubheading Inputs ## @var{tcp} - instance of @var{octave_tcp} class. ## ## @subsubheading Outputs ## None. ## ## @seealso{flushoutput} ## @end deftypefn function flushinput (tcp, q) __tcp_properties__ (tcp, 'flush', 1); end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/flushoutput.m���������������������������������������������0000644�0000000�0000000�00000002004�14743226261�020327� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} flushoutput (@var{tcp}) ## ## Flush the output buffer. ## ## @subsubheading Inputs ## @var{tcp} - instance of @var{octave_tcp} class. ## ## @subsubheading Outputs ## None. ## ## @seealso{flushinput} ## @end deftypefn function flushoutput (tcp) __tcp_properties__ (tcp, 'flush', 0); end ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/fopen.m���������������������������������������������������0000644�0000000�0000000�00000001720�14743226261�017040� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens TCP connection @var{obj} ## ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/fprintf.m�������������������������������������������������0000644�0000000�0000000�00000002730�14743226261�017403� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) ## Writes formatted string @var{template} using optional parameters to ## TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP object.@* ## @var{template} Format template string ## ## @subsubheading Outputs ## Number of characters written ## ## @end deftypefn function numbytes = fprintf (varargin) defaultformat = '%s\n'; if (nargin < 2) print_usage (); elseif (nargin < 3) formargs = varargin(2); format = defaultformat; else formargs = varargin(3:nargin); format = varargin{2}; endif if (! ( ischar (format))) print_usage (); endif numbytes = tcp_write (varargin{1}, sprintf (format, formargs{:})); endfunction ����������������������������������������instrument-control-0.9.4/inst/@octave_tcp/fread.m���������������������������������������������������0000644�0000000�0000000�00000006251�14743226261�017016� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} data read.@* ## @var{count} values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = tcp_read (obj, toread, get(obj, 'timeout')*1000); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/fwrite.m��������������������������������������������������0000644�0000000�0000000�00000003733�14743226261�017237� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? numbytes = tcp_write (obj, typecast(data,'uint8')); end �������������������������������������instrument-control-0.9.4/inst/@octave_tcp/get.m�����������������������������������������������������0000644�0000000�0000000�00000004173�14743226261�016515� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{tcp}) ## @deftypefnx {Function File} {@var{field} = } get (@var{tcp}, @var{property}) ## Get the properties of tcp object. ## ## @subsubheading Inputs ## @var{tcp} - instance of @var{octave_tcp} class.@* ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_tcp/set} ## @end deftypefn function retval = get (tcp, property) properties = {'name', 'remoteport', 'remotehost', ... 'localport', 'type', ... 'status', 'timeout', 'bytesavailable'}; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); end if !iscell (property) property = {property}; end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("tcp:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); end property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __tcp_properties__ (tcp, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); end end �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/read.m����������������������������������������������������0000644�0000000�0000000�00000004416�14743226261�016651� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} read (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) ## Reads @var{data} from TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{datatype} datatype of data.@* ## ## @subsubheading Outputs ## @var{data} data read.@* ## ## @end deftypefn function data = read (obj, cnt, datatype) if (nargin < 3) datatype = 'uint8'; endif switch (datatype) case {"char" "schar" "int8"} toclass = "int8"; tosize=1; case {"uchar" "uint8"} toclass = "uint8"; tosize=1; case {"int16" "short"} toclass = "int16"; tosize=2; case {"uint16" "ushort"} toclass = "uint16"; tosize=2; case {"int32" "int"} toclass = "int32"; tosize=4; case {"uint32" "uint"} toclass = "uint32"; tosize=4; case {"long" "int64"} toclass = "int64"; tosize=8; case {"ulong" "uint64"} toclass = "uint64"; tosize=8; case {"single" "float" "float32"} toclass = "single"; tosize=4; case {"double" "float64"} toclass = "double"; tosize=8; otherwise error ("precision not supported"); endswitch if (nargin < 2) cnt = int32(obj.bytesavailable/tosize); else cnt = cnt*tosize; endif tmp = tcp_read (obj, cnt, get(obj, 'timeout')*1000); data = typecast(tmp,toclass); endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/set.m�����������������������������������������������������0000644�0000000�0000000�00000005235�14743226261�016531� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of tcp object. ## ## @subsubheading Inputs ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'name' ## Set the name for the tcp socket. ## ## @item 'remotehost' ## Set the remote host name for the tcp socket. ## ## @item 'remoteport' ## Set the remote port for the tcp socket. ## ## @item 'timeout' ## Set the timeout value in seconds. Value of -1 means a ## blocking call. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_tcp/get} ## @end deftypefn function set (tcp, varargin) properties = {'timeout', 'name' }; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; end if numel (property) != numel (value) error ('tcp:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("tcp:set:InvalidArgument", ... "Property '%s' not found in tcp object.\n",x); cellfun (msg, not_found); end property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __tcp_properties__ (tcp, property{i}, value{i}); end end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcp/write.m���������������������������������������������������0000644�0000000�0000000�00000004012�14743226261�017060� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) ## Writes @var{data} to TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP object.@* ## @var{data} data to write.@* ## @var{datatype} datatype of data. If not specified, it defaults to "uint8".@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data, datatype) if (nargin < 2) print_usage (); elseif (nargin < 3) datatype = "uint8"; endif switch (datatype) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); otherwise error ("precision not supported"); endswitch numbytes = tcp_write (obj, typecast(data,'uint8')); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/����������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�016752� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/configureTerminator.m�������������������������������0000644�0000000�0000000�00000003272�14743226261�023162� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} configureTerminator (@var{tcp}, @var{term}) ## @deftypefnx {Function File} {} configureTerminator (@var{tcp}, @var{readterm}, @var{writeterm}) ## Set terminator on a tcpclient object for ASCII string manipulation ## ## @subsubheading Inputs ## @var{tcp} - tcpclient object@* ## @var{term} - terminal value for both read and write@* ## @var{readterm} = terminal value type for read data@* ## @var{writeterm} = terminal value for written data@* ## ## The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. ## ## @subsubheading Outputs ## None ## ## @seealso{tcpport} ## @end deftypefn function configureTerminator (tcp, readterm, writeterm) if nargin < 2 error ("Expected terminal"); elseif nargin == 2 __tcpclient_properties__ (tcp, 'terminator', readterm); elseif nargin == 3 __tcpclient_properties__ (tcp, 'terminator', readterm, writeterm); else error ("Expected read and write terminal only"); endif endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/flush.m���������������������������������������������0000644�0000000�0000000�00000003061�14743226261�020251� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the tcpclient socket buffers ## ## @subsubheading Inputs ## @var{dev} - connected tcpclient device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{serialport} ## @end deftypefn function flush (dev, flushdir) if nargin < 2 __tcpclient_properties__ (dev, 'flush', 0); __tcpclient_properties__ (dev, 'flush', 1); else if !ischar (flushdir) error("flush: expected flushdir to be a string"); endif if strcmp(flushdir, "output") __tcpclient_properties__ (dev, 'flush', 0); elseif strcmp(flushdir, "input") __tcpclient_properties__ (dev, 'flush', 1); else error("flush: invalid flushdir '%s'", flushdir); endif endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/get.m�����������������������������������������������0000644�0000000�0000000�00000004301�14743226261�017705� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{tcpclient}) ## @deftypefnx {Function File} {@var{field} = } get (@var{tcpclient}, @var{property}) ## Get the properties of tcpclient object. ## ## @subsubheading Inputs ## @var{tcpclient} - instance of @var{octave_tcpclient} class.@* ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_tcpclient/set} ## @end deftypefn function retval = get (tcpclient, property) properties = {'Name', 'Address', 'Port', ... 'Type', 'Status', 'Timeout', 'UserData', ... 'NumBytesAvailable', 'NumBytesWritten', ... 'Terminator', 'EnableTransferDelay' }; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); end if !iscell (property) property = {property}; end valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("tcpclient:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); end property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __tcpclient_properties__ (tcpclient, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); end end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/read.m����������������������������������������������0000644�0000000�0000000�00000004611�14743226261�020045� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} read (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) ## Reads @var{data} from TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP object.@* ## @var{size} Number of values to read. (Default: NumBytesAvailable).@* ## @var{datatype} datatype of data.@* ## ## @subsubheading Outputs ## @var{data} data read.@* ## ## @end deftypefn function data = read (obj, cnt, datatype) if (nargin < 3) datatype = 'uint8'; endif switch (datatype) case {"string"} toclass = "char"; tosize=1; case {"char" "schar" "int8"} toclass = "int8"; tosize=1; case {"uchar" "uint8"} toclass = "uint8"; tosize=1; case {"int16" "short"} toclass = "int16"; tosize=2; case {"uint16" "ushort"} toclass = "uint16"; tosize=2; case {"int32" "int"} toclass = "int32"; tosize=4; case {"uint32" "uint"} toclass = "uint32"; tosize=4; case {"long" "int64"} toclass = "int64"; tosize=8; case {"ulong" "uint64"} toclass = "uint64"; tosize=8; case {"single" "float" "float32"} toclass = "single"; tosize=4; case {"double" "float64"} toclass = "double"; tosize=8; otherwise error ("precision not supported"); endswitch if (nargin < 2) cnt = int32(obj.NumBytesAvailable/tosize); endif cnt = cnt*tosize; if cnt > 0 tmp = __tcpclient_read__ (obj, cnt, get(obj, 'Timeout')*1000); else tmp = []; endif data = typecast(tmp,toclass); endfunction �����������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/set.m�����������������������������������������������0000644�0000000�0000000�00000005200�14743226261�017720� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of tcpclient object. ## ## @subsubheading Inputs ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'Name' ## Set the name for the tcpclient socket. ## ## @item 'UserData' ## Set user data for the tcpclient socket. ## ## @item 'Timeout' ## Set the timeout value in seconds. Value of -1 means a ## blocking call. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_tcpclient/get} ## @end deftypefn function set (tcpclient, varargin) properties = {'Timeout', 'Name', 'UserData' }; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; endif if numel (property) != numel (value) error ('tcpclient:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); endif valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("tcpclient:set:InvalidArgument", ... "Property '%s' not found in tcpclient object.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __tcpclient_properties__ (tcpclient, property{i}, value{i}); endfor endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpclient/write.m���������������������������������������������0000644�0000000�0000000�00000004111�14743226261�020257� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) ## Writes @var{data} to TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCPclient object.@* ## @var{data} data to write.@* ## @var{datatype} datatype of data. If not specified, it defaults to "uint8".@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data, datatype) if (nargin < 2) print_usage (); elseif (nargin < 3) datatype = "uint8"; endif switch (datatype) case {"string"} data = int8 (data); case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); otherwise error ("precision not supported"); endswitch numbytes = __tcpclient_write__ (obj, typecast(data,'uint8')); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/����������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�017002� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/configureTerminator.m�������������������������������0000644�0000000�0000000�00000003272�14743226261�023212� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} configureTerminator (@var{tcp}, @var{term}) ## @deftypefnx {Function File} {} configureTerminator (@var{tcp}, @var{readterm}, @var{writeterm}) ## Set terminator on a tcpserver object for ASCII string manipulation ## ## @subsubheading Inputs ## @var{tcp} - tcpserver object@* ## @var{term} - terminal value for both read and write@* ## @var{readterm} = terminal value type for read data@* ## @var{writeterm} = terminal value for written data@* ## ## The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. ## ## @subsubheading Outputs ## None ## ## @seealso{tcpport} ## @end deftypefn function configureTerminator (tcp, readterm, writeterm) if nargin < 2 error ("Expected terminal"); elseif nargin == 2 __tcpserver_properties__ (tcp, 'terminator', readterm); elseif nargin == 3 __tcpserver_properties__ (tcp, 'terminator', readterm, writeterm); else error ("Expected read and write terminal only"); endif endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/flush.m���������������������������������������������0000644�0000000�0000000�00000003061�14743226261�020301� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the tcpserver socket buffers ## ## @subsubheading Inputs ## @var{dev} - connected tcpserver device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{serialport} ## @end deftypefn function flush (dev, flushdir) if nargin < 2 __tcpserver_properties__ (dev, 'flush', 0); __tcpserver_properties__ (dev, 'flush', 1); else if !ischar (flushdir) error("flush: expected flushdir to be a string"); endif if strcmp(flushdir, "output") __tcpserver_properties__ (dev, 'flush', 0); elseif strcmp(flushdir, "input") __tcpserver_properties__ (dev, 'flush', 1); else error("flush: invalid flushdir '%s'", flushdir); endif endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/get.m�����������������������������������������������0000644�0000000�0000000�00000004406�14743226261�017743� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{tcpserver}) ## @deftypefnx {Function File} {@var{field} = } get (@var{tcpserver}, @var{property}) ## Get the properties of tcpserver object. ## ## @subsubheading Inputs ## @var{tcpserver} - instance of @var{octave_tcpserver} class.@* ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_tcpserver/set} ## @end deftypefn function retval = get (tcpserver, property) properties = {'Name', 'ServerAddress', 'ServerPort', ... 'ClientAddress', 'ClientPort', ... 'Type', 'Status', 'Timeout', 'UserData', ... 'NumBytesAvailable', 'NumBytesWritten', ... 'Terminator', 'Connected' }; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); endif if !iscell (property) property = {property}; endif valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("tcpserver:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __tcpserver_properties__ (tcpserver, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); endif endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/read.m����������������������������������������������0000644�0000000�0000000�00000004620�14743226261�020075� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} read (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) ## Reads @var{data} from TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCP Server object.@* ## @var{size} Number of values to read. (Default: NumBytesAvailable).@* ## @var{datatype} datatype of data.@* ## ## @subsubheading Outputs ## @var{data} data read.@* ## ## @end deftypefn function data = read (obj, cnt, datatype) if (nargin < 3) datatype = 'uint8'; endif switch (datatype) case {"string"} toclass = "char"; tosize=1; case {"char" "schar" "int8"} toclass = "int8"; tosize=1; case {"uchar" "uint8"} toclass = "uint8"; tosize=1; case {"int16" "short"} toclass = "int16"; tosize=2; case {"uint16" "ushort"} toclass = "uint16"; tosize=2; case {"int32" "int"} toclass = "int32"; tosize=4; case {"uint32" "uint"} toclass = "uint32"; tosize=4; case {"long" "int64"} toclass = "int64"; tosize=8; case {"ulong" "uint64"} toclass = "uint64"; tosize=8; case {"single" "float" "float32"} toclass = "single"; tosize=4; case {"double" "float64"} toclass = "double"; tosize=8; otherwise error ("precision not supported"); endswitch if (nargin < 2) cnt = int32(obj.NumBytesAvailable/tosize); endif cnt = cnt*tosize; if cnt > 0 tmp = __tcpserver_read__ (obj, cnt, get(obj, 'Timeout')*1000); else tmp = []; endif data = typecast(tmp,toclass); endfunction ����������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/set.m�����������������������������������������������0000644�0000000�0000000�00000005240�14743226261�017754� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of tcpserver object. ## ## @subsubheading Inputs ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'Name' ## Set the name for the tcpserver socket. ## ## @item 'UserData' ## Set user data for the tcpserver socket. ## ## @item 'Timeout' ## Set the timeout value in seconds. Value of -1 means a ## blocking call. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_tcpserver/get} ## @end deftypefn function set (tcpserver, varargin) properties = {'Timeout', 'Name', 'UserData', ... 'ByteOrder'}; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; endif if numel (property) != numel (value) error ('tcpserver:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); endif valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("tcpserver:set:InvalidArgument", ... "Property '%s' not found in tcpserver object.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __tcpserver_properties__ (tcpserver, property{i}, value{i}); endfor endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_tcpserver/write.m���������������������������������������������0000644�0000000�0000000�00000004110�14743226261�020306� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) ## Writes @var{data} to TCP instrument ## ## @subsubheading Inputs ## @var{obj} is a TCPServer object.@* ## @var{data} data to write.@* ## @var{datatype} datatype of data. If not specified, it defaults to "uint8".@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data, datatype) if (nargin < 2) print_usage (); elseif (nargin < 3) datatype = "uint8"; endif switch (datatype) case {"string"} data = int8 (data); case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); otherwise error ("precision not supported"); endswitch numbytes = __tcpserver_write__ (obj, typecast(data,'uint8')); endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/����������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015555� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/fclose.m��������������������������������������������������0000644�0000000�0000000�00000001567�14743226261�017217� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes UDP connection @var{obj} ## @end deftypefn function fclose(fd) udp_close(fd); end �����������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/flush.m���������������������������������������������������0000644�0000000�0000000�00000003001�14743226261�017046� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the udp socket buffers ## ## @subsubheading Inputs ## @var{dev} - open udp device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{udp} ## @end deftypefn function flush (dev, flushdir) if nargin < 2 __udp_properties__ (dev, 'flush', 0); __udp_properties__ (dev, 'flush', 1); else if !ischar (flushdir) error("flush: expected flushdir to be a string"); endif if strcmp(flushdir, "output") __udp_properties__ (dev, 'flush', 0); elseif strcmp(flushdir, "input") __udp_properties__ (dev, 'flush', 1); else error("flush: invalid flushdir '%s'", flushdir); endif endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/flushinput.m����������������������������������������������0000644�0000000�0000000�00000002074�14743226261�020137� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} flushinput (@var{udp}) ## ## Flush the pending input, which will also make the BytesAvailable property be 0. ## ## @subsubheading Inputs ## @var{udp} - instance of @var{octave_udp} class. ## ## @subsubheading Outputs ## None ## ## @seealso{flushoutput} ## @end deftypefn function flushinput (udp, q) __udp_properties__ (udp, 'flush', 1); end ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/flushoutput.m���������������������������������������������0000644�0000000�0000000�00000002003�14743226261�020330� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} flushoutput (@var{udp}) ## ## Flush the output buffer. ## ## @subsubheading Inputs ## @var{udp} - instance of @var{octave_udp} class. ## ## @subsubheading Outputs ## None ## ## @seealso{flushinput} ## @end deftypefn function flushoutput (udp) __udp_properties__ (udp, 'flush', 0); end �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/fopen.m���������������������������������������������������0000644�0000000�0000000�00000001730�14743226261�017043� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens UDP connection @var{obj} ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ����������������������������������������instrument-control-0.9.4/inst/@octave_udp/fprintf.m�������������������������������������������������0000644�0000000�0000000�00000002766�14743226261�017416� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) ## Writes formatted string @var{template} using optional parameters to ## UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP object.@* ## @var{template} Format template string.@* ## ## @subsubheading Outputs ## @var{numbytes} is the number of bytes written to the device ## @end deftypefn function numbytes = fprintf (varargin) defaultformat = '%s\n'; if (nargin < 2) print_usage (); elseif (nargin < 3) formargs = varargin(2); format = defaultformat; else formargs = varargin(3:nargin); format = varargin{2}; endif if (! ( ischar (format))) print_usage (); endif numbytes = udp_write (varargin{1}, sprintf (format, formargs{:})); endfunction ����������instrument-control-0.9.4/inst/@octave_udp/fread.m���������������������������������������������������0000644�0000000�0000000�00000006317�14743226261�017023� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} data values.@* ## @var{count} number of values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; % this line was missing case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = udp_read (obj, toread, get(obj, 'timeout')*1000); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/fwrite.m��������������������������������������������������0000644�0000000�0000000�00000003740�14743226261�017237� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? numbytes = udp_write (obj, typecast(data,'uint8')); end ��������������������������������instrument-control-0.9.4/inst/@octave_udp/get.m�����������������������������������������������������0000644�0000000�0000000�00000004220�14743226261�016510� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{udp}) ## @deftypefnx {Function File} {@var{field} = } get (@var{udp}, @var{property}) ## Get the properties of udp object. ## ## @subsubheading Inputs ## @var{udp} - instance of @var{octave_udp} class.@* ## ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_udp/set} ## @end deftypefn function retval = get (udp, property) properties = {'name', 'remoteport', 'remotehost', ... 'localport', 'localhost', 'type', ... 'status', 'timeout', 'bytesavailable'}; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); end if !iscell (property) property = {property}; end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("udp:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); end property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __udp_properties__ (udp, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); end end ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/read.m����������������������������������������������������0000644�0000000�0000000�00000004431�14743226261�016650� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} read (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) ## Reads @var{data} from UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP object.@* ## @var{size} Number of values to read. (Default: BytesAvailable).@* ## @var{datatype} datatype of data.@* ## ## @subsubheading Outputs ## @var{data} data read.@* ## ## @end deftypefn function data = read (obj, cnt, datatype) if (nargin < 3) datatype = 'uint8'; endif switch (datatype) case {"char" "schar" "int8"} toclass = "int8"; tosize=1; case {"uchar" "uint8"} toclass = "uint8"; tosize=1; case {"int16" "short"} toclass = "int16"; tosize=2; case {"uint16" "ushort"} toclass = "uint16"; tosize=2; case {"int32" "int"} toclass = "int32"; tosize=4; case {"uint32" "uint"} toclass = "uint32"; tosize=4; case {"long" "int64"} toclass = "int64"; tosize=8; case {"ulong" "uint64"} toclass = "uint64"; tosize=8; case {"single" "float" "float32"} toclass = "single"; tosize=4; case {"double" "float64"} toclass = "double"; tosize=8; otherwise error ("precision not supported"); endswitch if (nargin < 2) cnt = int32(obj.bytesavailable/tosize); else cnt = cnt*tosize; endif tmp = udp_read (obj, cnt, get(obj, 'timeout')*1000); data = typecast(tmp,toclass); endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/set.m�����������������������������������������������������0000644�0000000�0000000�00000005420�14743226261�016527� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of udp object. ## ## @subsubheading Inputs ## @var{obj} - instance of @var{octave_udp} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'name' ## Set the name for the udp socket. ## ## @item 'remotehost' ## Set the remote host name for the udp socket. ## ## @item 'remoteport' ## Set the remote port for the udp socket. ## ## @item 'timeout' ## Set the timeout value in seconds. Value of -1 means a ## blocking call. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_udp/get} ## @end deftypefn function set (udp, varargin) properties = {'remotehost','remoteport','timeout', 'name' }; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; end if numel (property) != numel (value) error ('udp:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); end property = tolower(property); valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("udp:set:InvalidArgument", ... "Property '%s' not found in udp object.\n",x); cellfun (msg, not_found); end property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __udp_properties__ (udp, property{i}, value{i}); end end ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udp/write.m���������������������������������������������������0000644�0000000�0000000�00000006061�14743226261�017070� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}, @var{destinationAddress}, @var{destinationPort})) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}, @var{destinationAddress}, @var{destinationPort}) ## Writes @var{data} to UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP object.@* ## @var{data} data to write.@* ## @var{datatype} datatype of data. If not specified defaults to uint8.@* ## @var{destinationAddress} ipaddress to send to. If not specified, use the remote address.@* ## @var{destinationPort} port to send to. If not specified, use the remote port.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data, varargin) if (nargin < 2) print_usage (); endif datatype = "uint8"; destinationAddress = obj.remotehost; destinationPort = obj.remoteport; if (nargin == 3) datatype = varargin{1}; elseif (nargin == 4) destinationAddress = varargin{1}; destinationPort = varargin{2}; elseif (nargin == 5) datatype = varargin{1}; destinationAddress = varargin{2}; destinationPort = varargin{3}; elseif nargin > 5 print_usage (); endif switch (datatype) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); otherwise error ("datatype not supported"); endswitch oldaddr = obj.remotehost; oldport = obj.remoteport; try obj.remotehost = destinationAddress; obj.remoteport = destinationPort; catch obj.remotehost = oldaddr; obj.remoteport = oldport; rethrow (lasterror) end_try_catch numbytes = udp_write (obj, typecast(data,'uint8')); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�016462� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/configureMulticast.m����������������������������������0000644�0000000�0000000�00000003072�14743226261�022511� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} configureMulticast((@var{dev}, @var{address}) ## @deftypefnx {} {@var{data} =} configureMulticast((@var{dev}, @var{"off"}) ## Configure udpport device to receive multicast data ## ## @subsubheading Inputs ## @var{dev} - open udpport device ## ## If @var{address} is 'off' disable udp multicast. Otherwise it is the multicast address to use. ## ## @subsubheading Outputs ## None ## ## @seealso{udpport} ## @end deftypefn function configureMulticast(dev, address, loopback) if nargin < 2 error("configureMulticast: expected udp object and address"); endif if nargin < 3 loopback = 1; endif if !ischar (address) error("configureMulticast: expected address to be a string"); endif if !islogical(loopback) && !isscalar(loopback) error("configureMulticast: expected loopback to be a boolean"); endif __udpport_properties__ (dev, 'multicastgroup', address); __udpport_properties__ (dev, 'enablemulticastloopback', loopback); endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/configureTerminator.m���������������������������������0000644�0000000�0000000�00000003236�14743226261�022672� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} configureTerminator (@var{udp}, @var{term}) ## @deftypefnx {Function File} {} configureTerminator (@var{udp}, @var{readterm}, @var{writeterm}) ## Set terminator for ASCII string manipulation ## ## @subsubheading Inputs ## @var{udp} - udpport object@* ## @var{term} - terminal value for both read and write@* ## @var{readterm} = terminal value type for read data@* ## @var{writeterm} = terminal value for written data@* ## ## The terminal can be either strings "cr", "lf" (default), "lf/cr" or an integer between 0 to 255. ## ## @subsubheading Outputs ## None ## ## @seealso{udpport} ## @end deftypefn function configureTerminator (udp, readterm, writeterm) if nargin < 2 error ("Expected terminal"); elseif nargin == 2 __udpport_properties__ (udp, 'terminator', readterm); elseif nargin == 3 __udpport_properties__ (udp, 'terminator', readterm, writeterm); else error ("Expected read and write terminal only"); endif endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/flush.m�����������������������������������������������0000644�0000000�0000000�00000003035�14743226261�017762� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} flush (@var{dev}) ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "input") ## @deftypefnx {} {@var{data} =} flush (@var{dev}, "output") ## Flush the udpport socket buffers ## ## @subsubheading Inputs ## @var{dev} - open udpport device ## ## If an additional parameter is provided of "input" or "output", ## then only the input or output buffer will be flushed ## ## @subsubheading Outputs ## None ## ## @seealso{udpport} ## @end deftypefn function flush (dev, flushdir) if nargin < 2 __udpport_properties__ (dev, 'flush', 0); __udpport_properties__ (dev, 'flush', 1); else if !ischar (flushdir) error("flush: expected flushdir to be a string"); endif if strcmp(flushdir, "output") __udpport_properties__ (dev, 'flush', 0); elseif strcmp(flushdir, "input") __udpport_properties__ (dev, 'flush', 1); else error("flush: invalid flushdir '%s'", flushdir); endif endif endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/fprintf.m���������������������������������������������0000644�0000000�0000000�00000002775�14743226261�020323� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} =} fprintf (@var{obj}, @var{template} ...) ## Writes formatted string @var{template} using optional parameters to ## UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDPPort object.@* ## @var{template} Format template string.@* ## ## @subsubheading Outputs ## @var{numbytes} is the number of bytes written to the device ## @end deftypefn function numbytes = fprintf (varargin) defaultformat = '%s\n'; if (nargin < 2) print_usage (); elseif (nargin < 3) formargs = varargin(2); format = defaultformat; else formargs = varargin(3:nargin); format = varargin{2}; endif if (! ( ischar (format))) print_usage (); endif numbytes = __udpport_write__ (varargin{1}, sprintf (format, formargs{:})); endfunction ���instrument-control-0.9.4/inst/@octave_udpport/fread.m�����������������������������������������������0000644�0000000�0000000�00000006273�14743226261�017731� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP port object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} data values.@* ## @var{count} number of values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = __udpport_read__ (obj, toread, get(obj, 'Timeout')*1000); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/fwrite.m����������������������������������������������0000644�0000000�0000000�00000004030�14743226261�020135� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP port object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; endif switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); endswitch numbytes = __udpport_write__ (obj, typecast(data,'uint8')); endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/get.m�������������������������������������������������0000644�0000000�0000000�00000004514�14743226261�017423� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{struct} = } get (@var{udpport}) ## @deftypefnx {Function File} {@var{field} = } get (@var{udpport}, @var{property}) ## Get the properties of udpport object. ## ## @subsubheading Inputs ## @var{udpport} - instance of @var{octave_udpport} class.@* ## ## @var{property} - name of property.@* ## ## @subsubheading Outputs ## When @var{property} was specified, return the value of that property.@* ## otherwise return the values of all properties as a structure.@* ## ## @seealso{@@octave_udpport/set} ## @end deftypefn function retval = get (udpport, property) properties = {'Name', 'UserData', "IPAddressVersion", ... 'LocalPort', 'LocalHost', 'Type', 'Terminator', ... 'Status', 'Timeout', 'NumBytesAvailable', 'NumBytesWritten', ... 'MulticastGroup', 'EnableMulticast', 'EnableMulticastLoopback', ... 'EnablePortSharing', 'EnableBroadcast', 'ByteOrder'}; if (nargin == 1) property = properties; elseif (nargin > 2) error ("Too many arguments.\n"); endif if !iscell (property) property = {property}; endif valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error("udpport:get:InvalidArgument", ... "Unknown property '%s'.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; retval = {}; for i=1:length(property) retval{end+1} = __udpport_properties__ (udpport, property{i}); endfor if numel(property) == 1 retval = retval{1}; elseif (nargin == 1) retval = cell2struct (retval',properties); endif endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/read.m������������������������������������������������0000644�0000000�0000000�00000004604�14743226261�017557� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} read (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} read (@var{obj}, @var{size}, @var{datatype}) ## Reads @var{data} from UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDP object.@* ## @var{size} Number of values to read. (Default: BytesAvailable).@* ## @var{datatype} datatype of data.@* ## ## @subsubheading Outputs ## @var{data} data read.@* ## ## @end deftypefn function data = read (obj, cnt, datatype) if (nargin < 3) datatype = 'uint8'; endif switch (datatype) case {"string"} toclass = "char"; tosize=1; case {"char" "schar" "int8"} toclass = "int8"; tosize=1; case {"uchar" "uint8"} toclass = "uint8"; tosize=1; case {"int16" "short"} toclass = "int16"; tosize=2; case {"uint16" "ushort"} toclass = "uint16"; tosize=2; case {"int32" "int"} toclass = "int32"; tosize=4; case {"uint32" "uint"} toclass = "uint32"; tosize=4; case {"long" "int64"} toclass = "int64"; tosize=8; case {"ulong" "uint64"} toclass = "uint64"; tosize=8; case {"single" "float" "float32"} toclass = "single"; tosize=4; case {"double" "float64"} toclass = "double"; tosize=8; otherwise error ("precision not supported"); endswitch if (nargin < 2) cnt = int32(obj.NumBytesAvailable/tosize); endif cnt = cnt*tosize; if cnt > 0 tmp = __udpport_read__ (obj, cnt, get(obj, 'Timeout')*1000); else tmp = []; endif data = typecast(tmp,toclass); endfunction ����������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/set.m�������������������������������������������������0000644�0000000�0000000�00000005333�14743226261�017437� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue#ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} set (@var{obj}, @var{property},@var{value}) ## @deftypefnx {Function File} set (@var{obj}, @var{property},@var{value},@dots{}) ## Set the properties of udpport object. ## ## @subsubheading Inputs ## @var{obj} - instance of @var{octave_udpport} class.@* ## @var{property} - name of property.@* ## ## If @var{property} is a cell so must be @var{value}, it sets the values of ## all matching properties. ## ## The function also accepts property-value pairs. ## ## @subsubheading Properties ## @table @var ## @item 'Name' ## Set the name for the udpport socket. ## ## @item 'UserData' ## Set the user data of the object. ## ## @item 'Timeout' ## Set the timeout value in seconds. Value of -1 means a ## blocking call. ## ## @end table ## ## @subsubheading Outputs ## None ## ## @seealso{@@octave_udpport/get} ## @end deftypefn function set (udpport, varargin) properties = {'UserData','Timeout', 'Name', 'EnableBroadcast' }; if numel (varargin) == 1 && isstruct (varargin{1}) property = fieldnames (varargin{1}); func = @(x) getfield (varargin{1}, x); value = cellfun (func, property, 'UniformOutput', false); elseif numel (varargin) == 2 && iscell (varargin{1}) && iscell (varargin{2}) %% The arguments are two cells, expecting fields and values. property = varargin{1}; value = varargin{2}; else property = {varargin{1:2:end}}; value = {varargin{2:2:end}}; endif if numel (property) != numel (value) error ('udpport:set:InvalidArgument', ... 'PROPERIES and VALUES must have the same number of elements.'); endif valid = ismember (property, properties); not_found = {property{!valid}}; if !isempty (not_found) msg = @(x) error ("udpport:set:InvalidArgument", ... "Property '%s' not found in udpport object.\n",x); cellfun (msg, not_found); endif property = {property{valid}}; value = {value{valid}}; for i=1:length(property) __udpport_properties__ (udpport, property{i}, value{i}); endfor endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/write.m�����������������������������������������������0000644�0000000�0000000�00000006067�14743226261�020003� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} = } write (@var{obj}, @var{data}, @var{destinationAddress}, @var{destinationPort})) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}) ## @deftypefnx {Function File} {@var{numbytes} =} write (@var{obj}, @var{data}, @var{datatype}, @var{destinationAddress}, @var{destinationPort}) ## Writes @var{data} to UDP instrument ## ## @subsubheading Inputs ## @var{obj} is a UDPPort object.@* ## @var{data} data to write.@* ## @var{datatype} datatype of data. If not specified defaults to uint8.@* ## @var{destinationAddress} ipaddress to send to. If not specified, use the previously used remote address.@* ## @var{destinationPort} port to send to. If not specified, use the remote port.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = write(obj, data, varargin) if (nargin < 2) print_usage (); endif datatype = "uint8"; destinationAddress = ""; destinationPort = 0; if (nargin == 3) datatype = varargin{1}; elseif (nargin == 4) destinationAddress = varargin{1}; destinationPort = varargin{2}; elseif (nargin == 5) datatype = varargin{1}; destinationAddress = varargin{2}; destinationPort = varargin{3}; elseif nargin > 5 print_usage (); endif switch (datatype) case {"char" "schar" "int8", "string"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); otherwise error ("datatype not supported"); endswitch if !isempty(destinationAddress) if !ischar(destinationAddress) error ("Expected address as a string"); endif numbytes = __udpport_write__ (obj, typecast(data,'uint8'), destinationAddress, destinationPort); else numbytes = __udpport_write__ (obj, typecast(data,'uint8')); endif endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_udpport/writeline.m�������������������������������������������0000644�0000000�0000000�00000004204�14743226261�020642� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writeline (@var{dev}, @var{data}) ## @deftypefnx {} {} writeline (@var{dev}, @var{data}, @var{destaddr}, @var{destport}) ## Write data to a udpport including terminator value ## ## @subsubheading Inputs ## @var{dev} - connected device ## ## @var{data} - ASCII data to write ## ## @var{destaddr} - Destination address ## ## @var{destport} - Destination port ## ## Where the address and port is not specified, the previously used address and port is used. ## ## @subsubheading Outputs ## None ## ## @seealso{flushoutput} ## @end deftypefn function writeline (dev, data, varargin) if nargin != 2 && nargin != 4 error ('expected instrument control device and data'); endif type = typeinfo(dev); if !strncmp(type, "octave_", 7) error ('expected instrument control device'); endif if !ischar(data) error ("Expected data to be characters"); endif terminator = dev.Terminator; if iscell(terminator) && length(terminator) > 1 terminator = terminator{2}; endif if ! ischar (terminator) terminator = char(terminator); else if strcmpi (terminator, "lf") terminator = "\n"; elseif strcmpi (terminator, "cr") terminator = "\r"; elseif strcmpi (terminator, "cr/lf") terminator = "\r\n"; endif endif if nargin == 4 write (dev, [data terminator], varargin{1}, varargin{2}); else write (dev, [data terminator]); endif endfunction %!error writeline %!error writeline (1) %!test %! a = udpport (); %! writeline(a, "hello", '127.0.0.1', a.LocalPort); %! writeline(a, "hello2"); %! clear a ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_usbtmc/�������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�016262� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_usbtmc/fclose.m�����������������������������������������������0000644�0000000�0000000�00000001661�14743226261�017717� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes USBTMC connection @var{obj} ## ## @subsubheading Inputs ## @var{obj} is a usbtmc object.@* ## @end deftypefn function fclose(fd) usbtmc_close(fd); end �������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_usbtmc/fopen.m������������������������������������������������0000644�0000000�0000000�00000001720�14743226261�017547� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens USBTMC connection @var{obj} ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end ������������������������������������������������instrument-control-0.9.4/inst/@octave_usbtmc/fread.m������������������������������������������������0000644�0000000�0000000�00000006234�14743226261�017526� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from usbtmc instrument ## ## @subsubheading Inputs ## @var{obj} is a usbtmc object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} The read data.@* ## @var{count} values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = usbtmc_read (obj, toread); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_usbtmc/fwrite.m�����������������������������������������������0000644�0000000�0000000�00000004070�14743226261�017741� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to an usbtmc instrument ## ## @subsubheading Inputs ## @var{obj} is a usbtmc object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; endif switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); endswitch %% should we handle endianess ? numbytes = vxi11_write (obj, typecast(data,'uint8')); endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_vxi11/��������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015735� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_vxi11/fclose.m������������������������������������������������0000644�0000000�0000000�00000001572�14743226261�017373� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fclose (@var{obj}) ## Closes VXI11 connection @var{obj} ## @end deftypefn ## TODO: function fclose(fd) vxi11_close(fd); end ��������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_vxi11/fopen.m�������������������������������������������������0000644�0000000�0000000�00000001717�14743226261�017230� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} =} fopen (@var{obj}) (dummy) ## Opens VXI11 connection @var{obj} ## This currently is a dummy function to improve compatibility to MATLAB ## ## @end deftypefn function fopen(fd) % dummy for matlab compatibility end �������������������������������������������������instrument-control-0.9.4/inst/@octave_vxi11/fread.m�������������������������������������������������0000644�0000000�0000000�00000006231�14743226261�017176� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-2021 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{data} =} fread (@var{obj}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}) ## @deftypefnx {Function File} {@var{data} =} fread (@var{obj}, @var{size}, @var{precision}) ## @deftypefnx {Function File} {[@var{data},@var{count}] =} fread (@var{obj}, ...) ## @deftypefnx {Function File} {[@var{data},@var{count},@var{errmsg}] =} fread (@var{obj}, ...) ## Reads @var{data} from vxi11 instrument ## ## @subsubheading Inputs ## @var{obj} is a vxi11 object.@* ## @var{size} Number of values to read. (Default: 100).@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## @var{data} The read data.@* ## @var{count} values read.@* ## @var{errmsg} read operation error message.@* ## ## @end deftypefn function [data, count, errmsg] = fread (obj, size, precision) if (nargin < 2) ## TODO: InputBufferSize property not implemented yet warning("fread: InputBufferSize property not implemented yet, using 100 as default"); size = 100; endif if (nargin < 3) precision = 'uchar'; endif if ((rows(size) == 1) && (columns(size) == 2)) toread = size(1) * size(2); elseif (numel(size) == 1) toread = size; else print_usage(); endif switch (precision) case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; toread = toread * 2; case {"uint16" "ushort"} toclass = "uint16"; toread = toread * 2; case {"int32" "int"} toclass = "int32"; toread = toread * 4; case {"uint32" "uint"} toclass = "uint32"; toread = toread * 4; case {"long" "int64"} toclass = "int64"; toread = toread * 8; case {"ulong" "uint64"} toclass = "uint64"; toread = toread * 8; case {"single" "float" "float32"} toclass = "single"; toread = toread * 4; case {"double" "float64"} toclass = "double"; toread = toread * 8; otherwise error ("precision not supported"); endswitch eoi=0; tmp=[]; count=0; while ((!eoi) && (toread > 0)) tmp1 = vxi11_read (obj, toread); if !isempty(tmp1) wasread = numel(tmp1); count = count + wasread; toread = toread - wasread; else break; endif tmp = [tmp tmp1]; endwhile errmsg = ''; data = typecast(tmp,toclass); if (numel(size) > 1) data = reshape(data,size); endif endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/@octave_vxi11/fwrite.m������������������������������������������������0000644�0000000�0000000�00000003741�14743226261�017420� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{numbytes} = } fwrite (@var{obj}, @var{data}) ## @deftypefnx {Function File} {@var{numbytes} =} fwrite (@var{obj}, @var{data}, @var{precision}) ## Writes @var{data} to vxi11 instrument ## ## @subsubheading Inputs ## @var{obj} is a vxi11 object.@* ## @var{data} data to write.@* ## @var{precision} precision of data.@* ## ## @subsubheading Outputs ## returns number of bytes written. ## @end deftypefn function numbytes = fwrite(obj, data, precision) if (nargin < 2) print_usage (); elseif (nargin < 3) precision = []; end switch (precision) case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); case [] %% use data as it is otherwise error ("precision not supported"); end %% should we handle endianess ? numbytes = vxi11_write (obj, typecast(data,'uint8')); end �������������������������������instrument-control-0.9.4/inst/__instrument_control__.m����������������������������������������������0000644�0000000�0000000�00000004536�14743226261�020256� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019-202 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @subsubheading Overview ## The Instrument control package provides low level I/O functions for serial, i2c, parallel, spi, tcp, gpib, ## vxi11, udp and usbtmc interfaces. ## ## It attempts to provide the same function calls as the Matlab toolkit, as well as additional functionality. ## ## @subsubheading Interfaces ## The following interfaces have been implemented: ## @table @asis ## @item serial (deprecated) ## serial port functionality. It has been deprecated in favor of the serialport interface. ## @item serialport ## serial port functionality. ## @item spi ## spi device functionality. ## @item tcp / tcpip ## tcp socket functionality ## @item udp ## udp socket functionality ## @item i2c ## i2c device functionality ## @item usbtmc ## usbtmc device functionality ## @item vxi11 ## vxi11 device functionality ## @item parallel ## parallel port functionality ## @item gpip ## gpip device functionality ## @end table ## ## Use of the actual devices depend on whether teh functionality was enabled during package installation. ## ## To verify the available interfaces, run the following command in octave: ## ## @example ## instrhwinfo ## @end example ## ## The function will return information on the supported interfaces that are available, similar to below: ## ## @example ## ToolboxVersion = 0.4.0 ## ToolboxName = octave instrument control package ## SupportedInterfaces = ## @{ ## [1,1] = gpib ## [1,2] = i2c ## [1,3] = parallel ## [1,4] = serial ## [1,5] = tcp ## [1,6] = udp ## [1,7] = usbtmc ## [1,8] = vxi11 ## @} ## @end example ## ## Information on each device type can be obtained using: ## ## @example ## instrhelp <theclassname>. ## @end example function __instrument_control__ () # do nothing endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/__load_instrument_control__.m�����������������������������������������0000644�0000000�0000000�00000002731�14743226261�021250� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue ## ## 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 ## <http:##www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} __load_cfitsio__ () ## Undocumented internal function of instrument control package. ## @end deftypefn ## PKG_ADD: __load_instrument_control__ () function __load_instrument_control__ () # on package load, attempt to load docs try pkg_dir = fileparts (fullfile (mfilename ("fullpath"))); doc_file = fullfile (pkg_dir, "doc", "instrument-control.qch"); doc_file = strrep (doc_file, '\', '/'); if exist(doc_file, "file") if exist("__event_manager_register_documentation__") __event_manager_register_documentation__ (doc_file); elseif exist("__event_manager_register_doc__") __event_manager_register_doc__ (doc_file); endif endif catch # do nothing end_try_catch endfunction ���������������������������������������instrument-control-0.9.4/inst/__unload_instrument_control__.m���������������������������������������0000644�0000000�0000000�00000002766�14743226261�021623� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2023 John Donoghue ## ## 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 ## <http:##www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} __unload_instrument_control__ () ## Undocumented internal function of instrument control package. ## @end deftypefn ## PKG_DEL: __unload_instrument_control__ () function __unload_instrument_control__ () # on package unload, attempt to unload docs try pkg_dir = fileparts (fullfile (mfilename ("fullpath"))); doc_file = fullfile (pkg_dir, "doc", "instrument-control.qch"); doc_file = strrep (doc_file, '\', '/'); if exist(doc_file, "file") if exist("__event_manager_unregister_documentation__") __event_manager_unregister_documentation__ (doc_file); elseif exist("__event_manager_unregister_doc__") __event_manager_unregister_doc__ (doc_file); endif endif catch # do nothing end_try_catch endfunction ����������instrument-control-0.9.4/inst/clrdevice.m�����������������������������������������������������������0000644�0000000�0000000�00000002045�14743226261�015443� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} clrdevice (@var{obj}) ## Send clear command to Clear GPIB instrument. ## ## @var{obj} is a GPIB object ## ## @end deftypefn ## TODO: function clrdevice (obj) # if (nargin < 1) print_usage(); end if (!isa (obj,'octave_gpib')) error ('clrdevice: need octave_gpib object'); end __gpib_clrdevice__ (obj); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/flushinput.m����������������������������������������������������������0000644�0000000�0000000�00000004055�14743226261�015707� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} flushinput (@var{dev}) ## Flush the instruments input buffers ## ## @subsubheading Inputs ## @var{dev} - connected device or array of devices ## ## @subsubheading Outputs ## None ## ## @seealso{flushoutput} ## @end deftypefn function flushinput (dev) if nargin < 1 error ('expected instrument control device'); endif if iscell(dev) for i=1:length(dev) flushinput(dev{i}); endfor else if !strncmp(typeinfo(dev), "octave_", 7) error ('expected instrument control device'); endif # handle instruments we have a valid way of flushing input if (isa (dev,'octave_serialport')) flush(dev, "input"); elseif (isa (dev,'octave_serial')) __srl_properties__ (dev, 'flush', 1); elseif (isa (dev,'octave_udp')) __udp_properties__ (dev, 'flush', 1); elseif (isa (dev,'octave_udpport')) __udpport_properties__ (dev, 'flush', 1); elseif (isa (dev,'octave_tcp')) __tcp_properties__ (dev, 'flush', 1); elseif (isa (dev,'octave_tcpclient')) __tcpclient_properties__ (dev, 'flush', 1); elseif (isa (dev,'octave_gpib')) __gpib_clrdevice__ (obj); else # anything not handled specifically data = [1]; while (~isempty(data)) data = fread(obj,100); endwhile endif endif endfunction %!error flushinput %!error flushinput (1) %!test %! a = udp (); %! flushinput(a); %! clear a %!test %! a = udp (); %! b = udp (); %! flushinput({a b}); %! clear a b �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/flushoutput.m���������������������������������������������������������0000644�0000000�0000000�00000003645�14743226261�016114� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} flushoutput (@var{dev}) ## Flush the instruments output buffers ## ## @subsubheading Inputs ## @var{dev} - connected device or array of devices ## ## @subsubheading Outputs ## None ## ## @seealso{flushinput} ## @end deftypefn function flushoutput (dev) if nargin < 1 error ('expected instrument control device'); endif if iscell(dev) for i=1:length(dev) flushoutput(dev{i}); endfor else if !strncmp(typeinfo(dev), "octave_", 7) error ('expected instrument control device'); endif # handle instruments we have a valid way of flushing input if (isa (dev,'octave_serialport')) flush(dev, "output"); elseif (isa (dev,'octave_serial')) __srl_properties__ (dev, 'flush', 0); elseif (isa (dev,'octave_udp')) __udp_properties__ (dev, 'flush', 0); elseif (isa (dev,'octave_udpport')) __udpport_properties__ (dev, 'flush', 0); elseif (isa (dev,'octave_tcp')) __tcp_properties__ (dev, 'flush', 0); elseif (isa (dev,'octave_tcpclient')) __tcpclient_properties__ (dev, 'flush', 0); elseif (isa (dev,'octave_gpib')) __gpib_clrdevice__ (obj); endif endif endfunction %!error flushoutput %!error flushoutput (1) %!test %! a = udp (); %! flushoutput(a); %! clear a %!test %! a = udp (); %! b = udp (); %! flushoutput({a b}); %! clear a b �������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/instrhelp.m�����������������������������������������������������������0000644�0000000�0000000�00000003003�14743226261�015506� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} instrhelp () ## @deftypefnx {} {} instrhelp (@var{funcname}) ## @deftypefnx {} {} instrhelp (@var{obj}) ## Display instrument help ## ## @subsubheading Inputs ## @var{funcname} - function to display help about.@* ## @var{obj} - object to display help about.@* ## ## If no input is provided, the function will display and overview ## of the package functionality. ## ## @subsubheading Outputs ## None ## ## @end deftypefn function out = instrhelp (varargin) if nargin < 1 v = "__instrument_control__"; else v = varargin{1}; if !ischar(v) v = typeinfo(v); if !strncmp(v, "octave_", 7) error ('expected instrument control device'); endif v = strrep(v, "octave_", ""); endif endif if nargout > 0 out = help(v); else help(v); endif endfunction %!assert (! isempty (strfind (help ("instrhelp"), "Display instrument help"))) %!error instrhelp (1) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/instrhwinfo.m���������������������������������������������������������0000644�0000000�0000000�00000011271�14743226261�016056� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> ## Copyright (C) 2016 Andreas Weber <andy.weber.aw@gmail.com> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{list}] =} instrhwinfo () ## @deftypefnx {Function File} {@var{list} =} instrhwinfo (@var{interface}) ## Query available hardware for instrument-control ## ## When run without any input parameters, instrhwinfo will provide the toolbox ## information and a list of supported interfaces. ## ## @subsubheading Inputs ## @var{interface} is the instrument interface to query. When provided, instrhwinfo ## will provide information on the specified interface. ## ## Currently only interface "serialport","i2c" and "spi" and is supported, which will provide a list of ## available serial ports or i2c ports. ## ## @subsubheading Outputs ## If an output variable is provided, the function will store the information ## to the variable, otherwise it will be displayed to the screen. ## ## @subsubheading Example ## @example ## instrhwinfo ## scalar structure containing the fields: ## ## ToolboxVersion = 0.4.0 ## ToolboxName = octave instrument control package ## SupportedInterfaces = ## @{ ## [1,1] = i2c ## [1,2] = parallel ## [1,3] = serialport ## [1,4] = tcp ## [1,5] = udp ## [1,6] = usbtmc ## [1,7] = vxi11 ## @} ## ## @end example ## ## @end deftypefn function out = instrhwinfo (interface) if (nargin == 0) a = __instr_hwinfo__(); if (nargout == 0) disp(a); else out = a; endif elseif (nargin != 1) print_usage (); elseif (strcmpi (interface, "serial")) if (ispc ()) # windoze try Skey = 'HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM'; ## Find connected serial devices and clean up the output [~, list] = dos(['REG QUERY ' Skey ' 2>nul']); [~, ~, ~, out]=regexp (list, "COM[0-9]+"); catch out = []; end_try_catch elseif (ismac ()) tmp = glob ("/dev/tty.*"); out = strrep (tmp, "/dev/", ""); elseif (isunix ()) # GNU/Linux, BSD... ## only devices with device/driver tmp = glob ("/sys/class/tty/*/device/driver"); tmp = strrep (tmp, "/sys/class/tty/", ""); out = strrep (tmp, "/device/driver", ""); endif elseif (strcmpi (interface, "serialport")) if (ispc ()) # windoze try Skey = 'HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM'; ## Find connected serial devices and clean up the output [~, list] = dos(['REG QUERY ' Skey ' 2>nul']); [~, ~, ~, out]=regexp (list, "COM[0-9]+"); catch out = []; end_try_catch elseif (ismac ()) out = glob ("/dev/tty.*"); elseif (isunix ()) # GNU/Linux, BSD... ## only devices with device/driver #/sys/class/tty/ttyS0/device/driver tmp = glob ("/sys/class/tty/*/device/driver"); tmp = strrep (tmp, "/sys/class/tty", "/dev"); out = strrep (tmp, "/device/driver", ""); endif elseif (strcmpi (interface, "i2c")) if (isunix ()) # GNU/Linux, BSD... ## only devices with device/driver tmp = glob ("/sys/class/i2c-adapter/*/device/driver"); tmp = strrep (tmp, "/sys/class/i2c-adapter/", ""); out = strrep (tmp, "/device/driver", ""); else out = []; endif elseif (strcmpi (interface, "spi")) if (isunix ()) # GNU/Linux, BSD... ## only devices with device/driver tmp = glob ("/sys/class/spidev/*/device/driver"); tmp = strrep (tmp, "/sys/class/spidev/", ""); out = strrep (tmp, "/device/driver", ""); else out = []; endif else error ("Interface '%s' not yet implemented...", interface); endif endfunction %!test %! a = instrhwinfo(); %! assert(! isempty (a)) %!xtest %! # could fail if no serial ports? %! assert(!isempty(instrhwinfo("serial"))) %!error instrhwinfo("serial", "2ndarg") %!xtest %! # could fail if no i2c ports or not configured %! assert(!isempty(instrhwinfo("i2c"))) %!test %! p = pkg('describe', 'instrument-control'); %! hw = instrhwinfo (); %! assert (hw.ToolboxVersion, p{1}.version) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/readbinblock.m��������������������������������������������������������0000644�0000000�0000000�00000007237�14743226261�016132� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} readbinblock (@var{dev}) ## @deftypefnx {} {@var{data} =} readbinblock (@var{dev}, @var{datatype}) ## read a binblock of data from a instrument device ## ## @subsubheading Inputs ## @var{dev} - connected device ## ## @var{datatype} - optional data type to read data as (default 'uint8') ## ## @subsubheading Outputs ## @var{data} - data read ## ## @seealso{flushoutput} ## @end deftypefn function data = readbinblock (dev, varargin) if nargin < 1 error ('expected instrument control device'); endif type = typeinfo(dev); if !strncmp(type, "octave_", 7) error ('expected instrument control device'); endif if nargin > 1 switch (varargin{1}) case {"string"} toclass = "char"; case {"char" "schar" "int8"} toclass = "int8"; case {"uchar" "uint8"} toclass = "uint8"; case {"int16" "short"} toclass = "int16"; case {"uint16" "ushort"} toclass = "uint16"; case {"int32" "int"} toclass = "int32"; case {"uint32" "uint"} toclass = "uint32"; case {"long" "int64"} toclass = "int64"; case {"ulong" "uint64"} toclass = "uint64"; case {"single" "float" "float32"} toclass = "single"; case {"double" "float64"} toclass = "double"; otherwise error ("datatype not supported"); endswitch else toclass = "uint8"; endif # read and numbytesavailable types_with_read = { "octave_udpport", "octave_serialport", ... "octave_tcpclient", "octave_tcpserver", "octave_udpport" }; if sum(strcmp(type, types_with_read)) > 0 has_read = 1; else has_read = 0; endif data = uint8([]); sz = -1; # need read ?????? # D <dsizenumn> <data...> \n if has_read len = dev.NumBytesAvailable; if(len == 0) len = 100; endif tdata = read (dev, len); else tdata = fread(dev, 100); endif while !isempty (tdata) # getting hdr part if sz < 0 data = [data tdata]; idx = index (char(data), "#"); if (idx > 1) data = data(1:idx-1); elseif (idx == 0) data = ""; # if == 0, keep all data endif if numel(data) > 2 len = str2num(char(data(2))); if (numel(data) > 2+len) sz = str2num(char(data(3:3+len-1))); data = uint8(data(3+len:end)); endif endif endif # reading body if sz >= 0 if numel(data) >= sz data = data(1:sz); break; endif endif if has_read tdata = read (dev); else tdata = fread(dev, 100); endif endwhile if !strcmp(toclass, 'uint8') data = typecast(data,toclass); endif endfunction %!error readbinblock %!error readbinblock (1) %!test %! a = udp (); %! a.remoteport = a.localport; %! a.remotehost = '127.0.0.1'; %! a.timeout = 1; %! %! writebinblock(a, "hello", "char"); %! x = read(a); %! assert(char(x), "#15hello\n"); %! %! writebinblock(a, "hello", "char"); %! assert(readbinblock(a), uint8("hello")); %! %! x = [1 2 3 4]; %! writebinblock(a, x, "double"); %! assert(readbinblock(a, "double"), x); %! clear a �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/readline.m������������������������������������������������������������0000644�0000000�0000000�00000006517�14743226261�015276� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} readline (@var{dev}) ## read data from a instrument device excluding terminator value ## ## @subsubheading Inputs ## @var{dev} - connected device ## ## @subsubheading Outputs ## @var{data} - ASCII data read ## ## @seealso{flushoutput} ## @end deftypefn function data = readline (dev) if nargin < 1 error ('expected instrument control device'); endif type = typeinfo(dev); if !strncmp(type, "octave_", 7) error ('expected instrument control device'); endif types_with_confterminator = { "octave_udpport", "octave_serialport", ... "octave_tcpclient", "octave_tcpserver", "octave_udpport" }; if sum(strcmp(type, types_with_confterminator)) > 0 terminator = dev.Terminator; if iscell(terminator) && length(terminator) > 1 # user read terminator terminator = terminator{1}; endif if ! ischar (terminator) terminator = char(terminator); else if strcmpi(terminator, "lf") terminator = "\n"; elseif strcmpi(terminator, "cr") terminator = "\r"; elseif strcmpi(terminator, "cr/lf") terminator = "\r\n"; endif endif data = ""; idx = 0; len = length(terminator); tdata = read (dev, len); while !isempty (tdata) && idx == 0 data = [data char(tdata)]; idx = index (data, terminator); if (idx > 0) if (idx > 1) data = data(1:idx-1); else data = ""; endif else # read more data tdata = read (dev, 1); endif endwhile else terminator = "\n"; data = ""; idx = 0; tdata = fread(dev, 1); while !isempty(tdata) && idx == 0 data = [data char(tdata)]; idx = index(data, terminator); if (idx > 0) if (idx > 1) data = data(1:idx-1); else data = ""; endif else tdata = fread(dev, 1); endif endwhile endif endfunction %!error readline %!error readline (1) %!test %! a = udp (); %! a.remoteport = a.localport; %! a.remotehost = '127.0.0.1'; %! a.timeout = 1; %! %! writeline(a, "hello"); %! assert(readline(a), "hello"); %! # no more data %! assert(readline(a), ""); %! clear a %!test %! # new interface %! a = udpport (); %! a.Timeout = 1; %! writeline(a, "hello", '127.0.0.1', a.LocalPort) %! %! assert(readline(a), "hello"); %! # no more data %! assert(readline(a), ""); %! clear a %!test %! s = tcpserver(0); %! c = tcpclient("127.0.0.1", s.ServerPort, 'Timeout', 1); %! st = s.Connected; % NOTE: currently need look at status to ensure opened %! writeline(s, "hello"); %! assert(readline(c), "hello"); %! # no more data %! assert(readline(c), ""); %! %! writeline(c, "hello1"); %! assert(readline(s), "hello1"); %! clear a ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/seriallist.m����������������������������������������������������������0000644�0000000�0000000�00000002306�14743226261�015656� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{list} = } seriallist () ## Returns a list of all serial ports detected in the system. ## ## @subsubheading Inputs ## None ## ## @subsubheading Outputs ## @var{list} is a string cell array of serial ports names detected ## in the system. ## ## @seealso{instrhwinfo("serial")} ## @end deftypefn function out = seriallist () if nargin != 0 print_usage (); endif out = instrhwinfo("serial"); endfunction %!assert(seriallist, instrhwinfo("serial")) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/serialportlist.m������������������������������������������������������0000644�0000000�0000000�00000003626�14743226261�016571� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{list} = } serialportlist () ## @deftypefnx {Function File} {@var{list} = } serialportlist ("all") ## @deftypefnx {Function File} {@var{list} = } serialportlist ("available") ## Returns a list of all serial ports detected in the system. ## ## @subsubheading Inputs ## 'all' - show all serial ports (same as providing no arguments) ## 'available' - show only serial ports that are available for use ## ## @subsubheading Outputs ## @var{list} is a string cell array of serial ports names detected ## in the system. ## ## @seealso{instrhwinfo("serialport")} ## @end deftypefn function out = serialportlist (listtype) if nargin > 1 print_usage (); endif if nargin < 1 listtype = "all"; endif ports = instrhwinfo("serialport"); if strcmpi(listtype, "available") tmp = {}; for i=1:numel(ports) try portname = ports{i}; s = serialport (portname, 9600); clear s; tmp{end+1} = portname; catch err # no nothing here end_try_catch endfor out = tmp; else out = ports; endif endfunction %!assert(serialportlist, instrhwinfo("serialport")) %!assert(serialportlist("all"), instrhwinfo("serialport")) ����������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/spoll.m���������������������������������������������������������������0000644�0000000�0000000�00000003337�14743226261�014641� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{out} =} spoll (@var{obj}) ## @deftypefnx {Function File} {[@var{out},@var{statusByte}] =} spoll (@var{obj}) ## Serial polls GPIB instruments. ## ## @var{obj} is a GPIB object or a cell array of GPIB objects ## ## @var{out} GPIB objects ready for service ## @var{statusByte} status Byte ## ## @end deftypefn ## TODO: function [out,statusByte] = spoll (obj) # if (nargin < 1) print_usage (); end if iscell (obj) && numel (obj) > 0 if ~all (cellfun (@(x) isa (x,'octave_gpib'),obj)) error ("obj contains wrong elements"); end out = {}; statusByte = []; for i = 1:numel (obj) tmp_status = uint8 (__gpib_spoll__ (obj{i})); if (bitget (tmp_status,7) == 0) out{end+1} = obj{i}; statusByte(end+1) = tmp_status; end end return elseif (!isa (obj,'octave_gpib')) error ('spoll: need octave_gpib object'); end out = []; statusByte = []; tmp_status = uint8 (__gpib_spoll__ (obj)); if (bitget (tmp_status,7) == 0) out = obj; statusByte = tmp_status; end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/tcpip.m���������������������������������������������������������������0000644�0000000�0000000�00000004605�14743226261�014626� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{tcp} = } tcpip (@var{host}, [@var{port}], [@var{PropertyName}, @var{PropertyValue}...]) ## Matlab compatible wrapper to the tcp interface. ## ## NOTE: tcpip has been deprecated. Use tcpclient instead ## ## @subsubheading Inputs ## @var{host} - the host name or ip.@* ## @var{port} - the port number to connect. If omitted defaults to 80.@* ## @var{PropertyName}, @var{PropertyValue} - Optional property name, value pairs to set on the tcp object.@* ## ## @subsubheading Properties ## Currently the only known properties are "timeout" and "name". ## ## @subsubheading Outputs ## tcpip will return an instance of @var{octave_tcp} class as the result. ## @end deftypefn function out = tcpip (varargin) persistent warned = false; if (! warned) warned = true; warning ("Octave:deprecated-function", "tcpip is obsolete and will be removed from a future version of instrument-control, please use 'tcpclient' instead"); endif if nargin == 0 || (nargin > 1 && !isnumeric(varargin{2})) print_usage (); endif host = varargin{1}; if nargin > 1 port = varargin{2}; else port = 80; endif if nargin > 2 if mod(nargin, 2) != 0 error ("tcpip: expected property name, value pairs"); endif if !iscellstr (varargin(3:2:nargin)) error ("tcpip: expected property names to be strings"); endif endif out = tcp (resolvehost(host, "address"), port); for i = 3:2:nargin propname = tolower(varargin{i}); propvalue = varargin{i+1}; __tcp_properties__ (out, propname, propvalue); endfor endfunction %!test %! a = tcpip ("octave.org", 80); %! assert(isa(a, "octave_tcp")); %! fclose(a); ���������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/trigger.m�������������������������������������������������������������0000644�0000000�0000000�00000002012�14743226261�015140� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {} trigger (@var{obj}) ## Triggers GPIB instrument. ## ## @var{obj} is a GPIB object ## ## @end deftypefn ## TODO: function trigger (obj) # if (nargin < 1) print_usage(); end if (!isa (obj,'octave_gpib')) error ('trigger: need octave_gpib object'); end __gpib_trigger__ (obj); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/udp_demo.m������������������������������������������������������������0000644�0000000�0000000�00000004303�14743226261�015276� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2016 John Donoghue ## ## 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 <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{result} =} udp_demo () ## Run test SNTP demonstration for udp class ## ## @seealso{udp} ## @end deftypefn ## Author: john donoghue <john.donoghue@ieee.org> ## Created: 2016-11-23 function result = udp_demo () result = false; server = 'pool.ntp.org'; fprintf ('getting time from %s\n', server); # query time using SNTP s = udp (server, 123); # send request packet data = [uint8(0x1b) uint8(zeros (1,47))]; res = udp_write (s, data); # recieve packet data = udp_read (s,48, 4000); # should have 48 bytes reply if length (data) == 48 # convert uint8s to integer32 dataL = typecast (data, 'uint32'); # convert to little endian if we are on a little endian machine if typecast (uint8([1 0]), 'uint16') == 1 dataL = swapbytes (dataL); endif # network time ntimeval = dataL(11) - 2208988800; # get system time ltimeval = uint32 (time()); fprintf ('network time=%lu local time=%lu\n', ... ntimeval, ltimeval); result = true; endif fclose (s); endfunction %!test % assert(udp_demo) %!test % s = udp('127.0.0.1', 80); % assert(!isempty(s)); % assert(get(s,'name'), 'UDP-127.0.0.1'); % assert(get(s,'remoteport'), 80); % assert(get(s,'remotehost','127.0.0.1'); % assert(get(s,'localport')) % set(s,'name', 'test'); % assert(get(s,'name'), 'test'); % udp_close(s); %!test % s = udp('127.0.0.1', 80); % assert(get(s,'status'), 'open'); % fclose(s); % assert(get(s,'status'), 'closed'); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/writebinblock.m�������������������������������������������������������0000644�0000000�0000000�00000005452�14743226261�016346� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writebinblock (@var{dev}, @var{data}, @var{datatype}) ## Write a IEEE 488.2 binblock of data to a instrument device ## ## binblock formatted data is defined as: ## ## #<A><B><C> ## ## where: ## <A> ASCII number containing the length of part <B> ## ## <B> ASCII number containing the number of bytes of <C> ## ## <C> Binary data block ## ## @subsubheading Inputs ## @var{dev} - connected device ## ## @var{data} - binary data to send ## ## @var{datatype} - datatype to send data as ## ## @subsubheading Outputs ## None ## ## @seealso{flushoutput} ## @end deftypefn function writebinblock (dev, data, datatype) if nargin < 3 error ('expected instrument control device, data and datatype'); endif type = typeinfo(dev); if !strncmp(type, "octave_", 7) error ('expected instrument control device'); endif switch (datatype) case {"string"} data = char (data); case {"char" "schar" "int8"} data = int8 (data); case {"uchar" "uint8"} data = uint8 (data); case {"int16" "short"} data = int16 (data); case {"uint16" "ushort"} data = uint16 (data); case {"int32" "int"} data = int32 (data); case {"uint32" "uint"} data = uint32 (data); case {"long" "int64"} data = int64 (data); case {"ulong" "uint64"} data = uint64 (data); case {"single" "float" "float32"} data = single (data); case {"double" "float64"} data = double (data); otherwise error ("datatype not supported"); endswitch # make byte stream data = typecast(data,'uint8'); # hdr part hdr = sprintf("#X%d", numel(data)); # fix the hdr for X = num digits for the %d size hdr(2) = num2str(numel(hdr)-2); types_with_write = { "octave_udpport", "octave_serialport", ... "octave_tcpclient", "octave_tcpserver", "octave_udpport" }; if sum(strcmp(type, types_with_write)) > 0 write (dev, [uint8(hdr) data uint8("\n")]); else fwrite (dev, [uint8(hdr) data uint8("\n")]); endif endfunction %!error writebinblock %!error writebinblock (1) %!test %! a = udp (); %! a.remoteport = a.localport; %! a.remotehost = '127.0.0.1'; %! a.timeout = 1; %! %! writebinblock(a, "hello", "uint16"); %! clear a ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/writeline.m�����������������������������������������������������������0000644�0000000�0000000�00000004212�14743226261�015503� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {} writeline (@var{dev}, @var{data}) ## Write data to a instrument device including terminator value ## ## @subsubheading Inputs ## @var{dev} - connected device ## ## @var{data} - ASCII data to write ## ## @subsubheading Outputs ## None ## ## @seealso{flushoutput} ## @end deftypefn function writeline (dev, data) if nargin < 2 error ('expected instrument control device and data'); endif type = typeinfo(dev); if !strncmp(type, "octave_", 7) error ('expected instrument control device'); endif if !ischar(data) error ("Expected data to be characters"); endif types_with_confterminator = { "octave_udpport", "octave_serialport", ... "octave_tcpclient", "octave_tcpserver", "octave_udpport" }; if sum(strcmp(type, types_with_confterminator)) > 0 terminator = dev.Terminator; if iscell(terminator) && length(terminator) > 1 # use write terminator terminator = terminator{2}; endif if ! ischar (terminator) terminator = char(terminator); else if strcmpi (terminator, "lf") terminator = "\n"; elseif strcmpi (terminator, "cr") terminator = "\r"; elseif strcmpi (terminator, "cr/lf") terminator = "\r\n"; endif endif write (dev, [data terminator]); else terminator = "\n"; fwrite (dev, [data terminator]); endif endfunction %!error writeline %!error writeline (1) %!test %! a = udp (); %! a.remoteport = a.localport; %! a.remotehost = '127.0.0.1'; %! a.timeout = 1; %! %! writeline(a, "hello"); %! clear a ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/inst/writeread.m�����������������������������������������������������������0000644�0000000�0000000�00000002337�14743226261�015475� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> ## ## 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. ## -*- texinfo -*- ## @deftypefn {} {@var{data} =} writeread (@var{dev}, @var{command}) ## write a ASCII command and read data from a instrument device. ## ## @subsubheading Inputs ## @var{dev} - connected device ## ## @var{command} - ASCII command ## ## @subsubheading Outputs ## @var{data} - ASCII data read ## ## @seealso{readline, writeline} ## @end deftypefn function data = writeread (dev, cmd) writeline(dev, cmd); data = readline(dev); endfunction %!error writeread %!error writeread (1) %!test %! a = udp (); %! a.remoteport = a.localport; %! a.remotehost = '127.0.0.1'; %! a.timeout = 1; %! %! data = writeread(a, "hello"); %! assert(data, "hello"); %! clear a �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/�����������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013136� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/Makefile.in������������������������������������������������������������0000644�0000000�0000000�00000002306�14743226261�015204� 0����������������������������������������������������������������������������������������������������ustar�00������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� SUBDIRS = serial parallel i2c spi usbtmc tcp tcpclient tcpserver udp udpport gpib vxi11 resolvehost hwinfo serialport modbus MKOCTFILE ?= mkoctfile GREP ?= grep .PHONY: clean .PHONY: realclean .PHONY: distclean .PHONY: $(SUBDIRS) .PHONY: make-pkg-add_file all: $(SUBDIRS) make-pkg-add-file.cc $(SUBDIRS): $(MAKE) -C $@ # pkg install doesnt look in subdirs of src to make pkgadd/del so we # make a source file that it will see CC_SOURCES = $(wildcard */*.cc) make-pkg-add-file.cc: $(CC_SOURCES) @echo "Generating pkg add/del $@ ..." @( echo "// Generated file for PKG_ADD/DEL inclusion"; \ $(GREP) -h '// PKG_' $^) > "$@" CLEANDIRS = $(SUBDIRS:%=clean-%) DISTCLEANDIRS = $(SUBDIRS:%=distclean-%) .PHONY: $(CLEANDIRS) .PHONY: $(DISTCLEANDIRS) $(CLEANDIRS): $(MAKE) -C $(@:clean-%=%) clean $(DISTCLEANDIRS): $(MAKE) -C $(@:distclean-%=%) distclean clean: $(CLEANDIRS) realclean: -rm -f *.oct -rm -f make-pkg-add-file.cc distclean: realclean $(DISTCLEANDIRS) -rm -rf autom4te.cache -rm -f common.mk oct-alt-includes.h -rm -f Makefile config.status config.log config.h maintainer-clean: distclean -rm -f configure # and prebuild stuff we need do prebuild: $(MAKE) -C vxi11 prebuild ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/aclocal.m4�������������������������������������������������������������0000644�0000000�0000000�00000032173�14743226261�015004� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 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_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) # pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. 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 ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl 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]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. 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 ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. 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 ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl 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 $2]) _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 <http://pkg-config.freedesktop.org/>.])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------ dnl dnl Prepare a "--with-" configure option using the lowercase dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and dnl PKG_CHECK_MODULES in a single macro. AC_DEFUN([PKG_WITH_MODULES], [ m4_pushdef([with_arg], m4_tolower([$1])) m4_pushdef([description], [m4_default([$5], [build with ]with_arg[ support])]) m4_pushdef([def_arg], [m4_default([$6], [auto])]) m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) m4_case(def_arg, [yes],[m4_pushdef([with_without], [--without-]with_arg)], [m4_pushdef([with_without],[--with-]with_arg)]) AC_ARG_WITH(with_arg, AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, [AS_TR_SH([with_]with_arg)=def_arg]) AS_CASE([$AS_TR_SH([with_]with_arg)], [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], [auto],[PKG_CHECK_MODULES([$1],[$2], [m4_n([def_action_if_found]) $3], [m4_n([def_action_if_not_found]) $4])]) m4_popdef([with_arg]) m4_popdef([description]) m4_popdef([def_arg]) ])dnl PKG_WITH_MODULES dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ----------------------------------------------- dnl dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES dnl check._[VARIABLE-PREFIX] is exported as make variable. AC_DEFUN([PKG_HAVE_WITH_MODULES], [ PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) AM_CONDITIONAL([HAVE_][$1], [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ])dnl PKG_HAVE_WITH_MODULES dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------------------ dnl dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make dnl and preprocessor variable. AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], [ PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES m4_include([m4/octave-forge.m4]) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/bootstrap��������������������������������������������������������������0000755�0000000�0000000�00000000317�14743226261�015102� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash ## Octave-Forge: video package bootstrap script ## Run this to generate the configure script set -e # halt if unhandled error aclocal autoconf # generate configure script autoheader -f �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/common.mk.in�����������������������������������������������������������0000644�0000000�0000000�00000001725�14743226261�015371� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCTAVE_CONFIG ?= octave-config MKOCTFILE ?= mkoctfile GREP ?= @GREP@ all: $(OCT) archtests ARCHDIR := "$(shell $(OCTAVE_CONFIG) -p CANONICAL_HOST_TYPE)-$(shell $(OCTAVE_CONFIG) -p API_VERSION)" CC_SOURCES := $(wildcard *.cc) CC_TST_SOURCES := $(shell $(GREP) --files-with-matches '^%!' $(CC_SOURCES)) TST_SOURCES := $(patsubst %.cc,../../inst/$(ARCHDIR)/%.cc-tst,$(CC_TST_SOURCES)) $(TST_SOURCES): ../../inst/$(ARCHDIR)/%.cc-tst: %.cc | ../../inst/$(ARCHDIR) @echo "Extracting tests from $< ..." @$(RM) -f "$@" "$@-t" @( echo "## Generated from $<"; \ $(GREP) '^%!' "$<") > "$@" PHONY: archtests archtests: $(TST_SOURCES) PHONY: cleanarchtests cleanarchtests: rm -f $(TST_SOURCES) ../../inst/$(ARCHDIR): @mkdir -p "$@" %.o: %.c $(MKOCTFILE) $(CFLAGS) -c $^ %.o: %.cc $(MKOCTFILE) $(CFLAGS) -c $^ %.oct: $(OBJ) $(MKOCTFILE) $^ $(LFLAGS) $(TCPLIBS) -o $@ clean: cleanarchtests rm -f $(OCT) *.o distclean: clean rm Makefile .PHONY: all clean �������������������������������������������instrument-control-0.9.4/src/config.guess�����������������������������������������������������������0000755�0000000�0000000�00000123672�14743226261�015471� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # 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 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 <http://www.gnu.org/licenses/>. # # 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches to <config-patches@gnu.org>. 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 <config-patches@gnu.org>." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2015 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 case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include <features.h> #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # 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 tuples: *-*-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 -q __ELF__ 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 ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_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'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; 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 ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; 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:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-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 <stdio.h> /* 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 <sys/systemcfg.h> 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:*:[4567]) 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/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` 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 <stdlib.h> #include <unistd.h> 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 -q __LP64__ 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 <unistd.h> 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:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) 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 ;; 8664:Windows_NT:*) echo x86_64-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-${LIBC}`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/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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 -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #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-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${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-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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.[02]*:*) 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' </usr/options/cb.name` echo ${UNAME_MACHINE}-pc-isc$UNAME_REL elif /bin/uname -X 2>/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 i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-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; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' 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; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; 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.[02]*:*) 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 <Richard.M.Bartel@ccMail.Census.GOV> echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes <hewes@openmarket.com>. # 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 ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku 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 eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi 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 ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} 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 ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 <<EOF $0: unable to guess system type This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be pertinent to <config-patches@gnu.org> 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: ����������������������������������������������������������������������instrument-control-0.9.4/src/config.h.in������������������������������������������������������������0000644�0000000�0000000�00000011027�14743226261�015162� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* config.h.in. Generated from configure.ac by autoheader. */ #include "undef-ah-octave.h" /* build GPIB interface functions */ #undef BUILD_GPIB /* build I2C interface functions */ #undef BUILD_I2C /* build MODBUS interface functions */ #undef BUILD_MODBUS /* build PARALLEL interface functions */ #undef BUILD_PARALLEL /* build resolvehost function */ #undef BUILD_RESOLVEHOST /* build SERIAL interface functions */ #undef BUILD_SERIAL /* build SPI interface functions */ #undef BUILD_SPI /* build TCP interface functions */ #undef BUILD_TCP /* build UDP interface functions */ #undef BUILD_UDP /* build USBTMC interface functions */ #undef BUILD_USBTMC /* build VISA interface functions */ #undef BUILD_VISA /* build VXI11 interface functions */ #undef BUILD_VXI11 /* clnt allows const inputs */ #undef CONST_CLNT_SUPPORT /* Define to 1 if you have the <dev/iicbus/iic.h> header file. */ #undef HAVE_DEV_IICBUS_IIC_H /* Define to 1 if you have the <dev/ppbus/ppbconf.h> header file. */ #undef HAVE_DEV_PPBUS_PPBCONF_H /* Define to 1 if you have the <dev/ppbus/ppi.h> header file. */ #undef HAVE_DEV_PPBUS_PPI_H /* Define to 1 if you have the <gpib/ib.h> header file. */ #undef HAVE_GPIB_IB_H /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the <linux/i2c-dev.h> header file. */ #undef HAVE_LINUX_I2C_DEV_H /* Define to 1 if you have the <linux/parport.h> header file. */ #undef HAVE_LINUX_PARPORT_H /* Define to 1 if you have the <linux/ppdev.h> header file. */ #undef HAVE_LINUX_PPDEV_H /* Define to 1 if you have the <linux/spi/spidev.h> header file. */ #undef HAVE_LINUX_SPI_SPIDEV_H /* Define to 1 if you have the <modbus/modbus.h> header file. */ #undef HAVE_MODBUS_MODBUS_H /* Defined if have modbus_set_response_timeout(modbus_t*,uint32,uint32) */ #undef HAVE_MODBUS_SET_RESPONSE_TIMEOUT2 /* Define to 1 if you have the <octave/interpreter.h> header file. */ #undef HAVE_OCTAVE_INTERPRETER_H /* Define to 1 if you have the <octave/lo-sysdep.h> header file. */ #undef HAVE_OCTAVE_LO_SYSDEP_H /* Have for octave::sys::u8_to_wstring */ #undef HAVE_OCTAVE_U8_TO_WSTRING /* Define to 1 if you have the <rpc/rpc.h> header file. */ #undef HAVE_RPC_RPC_H /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the <stdio.h> header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the <sys/socket.h> header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the <termios.h> header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the <visa/visa.h> header file. */ #undef HAVE_VISA_VISA_H /* Define to 1 if you have the <winsock2.h> header file. */ #undef HAVE_WINSOCK2_H /* macro for alternative Octave symbols */ #undef OCTAVE_BASE_CLASS /* macro for alternative Octave symbols */ #undef OCTAVE__FEVAL /* Use new register_binary_op */ #undef OCTAVE__NEW_REGISTER_OP /* macro for alternative Octave symbols */ #undef OCTAVE__REGISTER_BINARY_OP /* macro for alternative Octave symbols */ #undef OCTAVE__UNWIND_PROTECT /* octave_base_value ref count field */ #undef OV_COUNT /* macro for alternative Octave symbols */ #undef OV_ISFLOAT /* macro for alternative Octave symbols */ #undef OV_ISINTEGER /* macro for alternative Octave symbols */ #undef OV_ISLOGICAL /* 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 all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Dont define guid == ops */ #undef _NO_SYS_GUID_OPERATOR_EQ_ #include "oct-alt-includes.h" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/config.sub�������������������������������������������������������������0000755�0000000�0000000�00000106246�14743226261�015132� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # 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 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 <http://www.gnu.org/licenses/>. # # 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to <config-patches@gnu.org>. # # 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. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # 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 <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) Copyright 1992-2015 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-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) 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 | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -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*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -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 \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | 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 \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-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-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | 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-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | 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-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # 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 ;; aros) basic_machine=i386-pc os=-aros ;; 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 ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; 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 | 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 ;; dicos) basic_machine=i686-pc os=-dicos ;; 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*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 ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; 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 ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-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 ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; 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 ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; 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 | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) 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-* | ppc64p7-*) 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 | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) 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 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; 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 ;; tile*) basic_machine=$basic_machine-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 ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-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[24]aeb | 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. -auroraux) os=-auroraux ;; -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* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -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* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -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* | -es* | -tirtos*) # 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 ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -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 ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) 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 ;; 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 ;; -cnk*|-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: ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/configure��������������������������������������������������������������0000755�0000000�0000000�00000535632�14743226261�015063� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for octave instrument control package 0.9.4. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 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="as_nop=: if test \${ZSH_VERSION+y} && (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 \$as_nop 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 \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || 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" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: 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_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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=`printf "%s\n" "$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 || printf "%s\n" 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_nop 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_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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 || printf "%s\n" 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" || { printf "%s\n" "$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 } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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'" test -n "$DJDIR" || exec 7<&0 </dev/null exec 6>&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='octave instrument control package' PACKAGE_TARNAME='octave-instrument-control-package' PACKAGE_VERSION='0.9.4' PACKAGE_STRING='octave instrument control package 0.9.4' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include <stddef.h> #ifdef HAVE_STDIO_H # include <stdio.h> #endif #ifdef HAVE_STDLIB_H # include <stdlib.h> #endif #ifdef HAVE_STRING_H # include <string.h> #endif #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif #ifdef HAVE_STDINT_H # include <stdint.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif" ac_header_cxx_list= ac_subst_vars='LTLIBOBJS LIBOBJS BUILD_VXI11 MODBUSINCLUDES MODBUSLIBS LIBMODBUS_LIBS LIBMODBUS_CFLAGS VISALIBS RPCGENOPTS RPCGEN RPCLIBS RPCINCLUDE TIRPC_LIBS TIRPC_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG GPIBLIBS TCPLIBS BUILD_FOR_WINDOWS OCTAVE_CONFIG MKOCTFILE SED GREP OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build 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 runstatedir 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 with_librpc ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR TIRPC_CFLAGS TIRPC_LIBS LIBMODBUS_CFLAGS LIBMODBUS_LIBS' # 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' runstatedir='${localstatedir}/run' 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 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=`printf "%s\n" "$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=`printf "%s\n" "$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 ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -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=`printf "%s\n" "$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=`printf "%s\n" "$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. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$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" ;; *) printf "%s\n" "$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 runstatedir 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 || printf "%s\n" 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 octave instrument control package 0.9.4 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] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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/octave-instrument-control-package] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of octave instrument control package 0.9.4:";; esac cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-librpc=tirpc|sunrpc|auto|none Choose use/selection of librpc used Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> 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 TIRPC_CFLAGS C compiler flags for TIRPC, overriding pkg-config TIRPC_LIBS linker flags for TIRPC, overriding pkg-config LIBMODBUS_CFLAGS C compiler flags for LIBMODBUS, overriding pkg-config LIBMODBUS_LIBS linker flags for LIBMODBUS, 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 the package provider. _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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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 configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. 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 printf "%s\n" "$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 octave instrument control package configure 0.9.4 generated by GNU Autoconf 2.71 Copyright (C) 2021 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 conftest.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile # 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.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac 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 octave instrument control package $as_me 0.9.4, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "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=`printf "%s\n" "$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=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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 printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$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 printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include <cstdlib> #include <exception> // <cassert> and <cstring> are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template <typename T> struct test_template { T const val; explicit test_template(T t) : val(t) {} template <typename U> T add(U u) { return static_cast<T>(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template<double> tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template <typename Ret, typename Fn> Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template <typename V> auto sum(V first) -> V { return first; } template <typename V, typename... Args> auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template<int>> v(test_template<int>(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " as_fn_append ac_header_cxx_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_cxx_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_cxx_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_cxx_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_cxx_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_cxx_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_cxx_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_cxx_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_cxx_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="config.guess config.sub" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$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. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" 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,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-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_config_headers="$ac_config_headers config.h" # Avoid warnings for redefining AH-generated preprocessor symbols of # Octave. # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 printf %s "checking target system type... " >&6; } if test ${ac_cv_target+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 printf "%s\n" "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- # 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 clang++ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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. printf "%s\n" "$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\"" printf "%s\n" "$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 printf "%s\n" "$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 (void) { ; 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 printf %s "checking whether the C++ compiler works... " >&6; } ac_link_default=`printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$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+y} && 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 $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 printf %s "checking for C++ compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$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 <stdio.h> int main (void) { 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$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 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$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_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; 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_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed 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 # Define macros needed #AC_DEFINE(__STDC_CONSTANT_MACROS, [], [workaround for C++ programs to use C99 macros]) # Extract the first word of "mkoctfile", so it can be a program name with args. set dummy mkoctfile; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MKOCTFILE+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MKOCTFILE"; then ac_cv_prog_MKOCTFILE="$MKOCTFILE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_MKOCTFILE="mkoctfile" printf "%s\n" "$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_prog_MKOCTFILE" && ac_cv_prog_MKOCTFILE="none" fi fi MKOCTFILE=$ac_cv_prog_MKOCTFILE if test -n "$MKOCTFILE"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKOCTFILE" >&5 printf "%s\n" "$MKOCTFILE" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "$MKOCTFILE" = "none"; then as_fn_error $? "mkoctfile required to install $PACKAGE_NAME" "$LINENO" 5 fi # Extract the first word of "octave-config", so it can be a program name with args. set dummy octave-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OCTAVE_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OCTAVE_CONFIG"; then ac_cv_prog_OCTAVE_CONFIG="$OCTAVE_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_OCTAVE_CONFIG="octave-config" printf "%s\n" "$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 OCTAVE_CONFIG=$ac_cv_prog_OCTAVE_CONFIG if test -n "$OCTAVE_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_CONFIG" >&5 printf "%s\n" "$OCTAVE_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$OCTAVE_CONFIG" && OCTAVE_CONFIG=$MKOCTFILE # try get around possible spaces in the path if test "X${IGNORE_MINGW_PATH_MODIFICATION}" == "X"; then case $host_os in mingw*) # try demangle spaces in escaped input strings MKOCTFILE=`echo $MKOCTFILE | $SED "s,\\\\\ ,?,g"` OCTAVE_CONFIG=`echo $OCTAVE_CONFIG | $SED "s,\\\\\ ,?,g"` ;; *) ;; esac fi ## Simple symbol alternatives of different Octave versions. save_altsyms_CXX="$CXX" save_altsyms_CXXFLAGS="$CXXFLAGS" save_altsyms_LDFLAGS="$LDFLAGS" save_altsyms_LIBS="$LIBS" OCTINCLUDEDIR="${OCTINCLUDEDIR:-`$MKOCTFILE -p OCTINCLUDEDIR`}/.." OCTLIBDIR=${OCTLIBDIR:-`$MKOCTFILE -p OCTLIBDIR`} if test "X${IGNORE_MINGW_PATH_MODIFICATION}" == "X"; then MSYSTEM="${MSYSTEM}" else MSYSTEM="none" fi case X$MSYSTEM in XMINGW64*) OCTAVE_HOME=`${MKOCTFILE} -p OCTAVE_HOME | $SED 's,\\\\,/,g'` # change \ to / and replace octave home part with mingw part OCTINCLUDEDIR=`echo $OCTINCLUDEDIR | $SED -e 's,\\\\,/,g' -e "s,${OCTAVE_HOME},/mingw64,g"` OCTLIBDIR=`echo $OCTLIBDIR | $SED -e 's,\\\\,/,g' -e "s,${OCTAVE_HOME},/mingw64,g"` ;; XMINGW32*) OCTAVE_HOME=`${MKOCTFILE} -p OCTAVE_HOME | $SED 's,\\\\,/,g'` # change \ to / and replace octave home part with mingw part OCTINCLUDEDIR=`echo $OCTINCLUDEDIR | $SED -e 's,\\\\,/,g' -e "s,${OCTAVE_HOME},/mingw32,g"` OCTLIBDIR=`echo $OCTLIBDIR | $SED -e 's,\\\\,/,g -e "s,${OCTAVE_HOME},/mingw32,g"'` ;; *) ;; esac CXX=`${MKOCTFILE} -p CXX` CXXFLAGS="-I$OCTINCLUDEDIR $CXXFLAGS" LDFLAGS="-L$OCTLIBDIR $LDFLAGS" LIBS="-loctinterp $LIBS" # includes ac_fn_cxx_check_header_compile "$LINENO" "octave/interpreter.h" "ac_cv_header_octave_interpreter_h" "#include <octave/oct.h> " if test "x$ac_cv_header_octave_interpreter_h" = xyes then : printf "%s\n" "#define HAVE_OCTAVE_INTERPRETER_H 1" >>confdefs.h fi ac_fn_cxx_check_header_compile "$LINENO" "octave/lo-sysdep.h" "ac_cv_header_octave_lo_sysdep_h" "#include <octave/oct.h> " if test "x$ac_cv_header_octave_lo_sysdep_h" = xyes then : printf "%s\n" "#define HAVE_OCTAVE_LO_SYSDEP_H 1" >>confdefs.h fi echo '/* generated by configure */' > oct-alt-includes.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking feval or octave::feval" >&5 printf %s "checking feval or octave::feval... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> #include <octave/parse.h> int main (void) { octave::feval ("date"); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OCTAVE__FEVAL octave::feval" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: octave::feval" >&5 printf "%s\n" "octave::feval" >&6; } echo '#include <octave/parse.h> ' >> oct-alt-includes.h ac_cv_octsym_OCTAVE__FEVAL="octave::feval" else $as_nop printf "%s\n" "#define OCTAVE__FEVAL feval" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: feval" >&5 printf "%s\n" " feval" >&6; } echo '#include <octave/parse.h>' >> oct-alt-includes.h ac_cv_octsym_OCTAVE__FEVAL=" feval" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking is_float_type or isfloat" >&5 printf %s "checking is_float_type or isfloat... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> int main (void) { octave_value ().isfloat (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OV_ISFLOAT isfloat" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: isfloat" >&5 printf "%s\n" "isfloat" >&6; } echo ' ' >> oct-alt-includes.h ac_cv_octsym_OV_ISFLOAT="isfloat" else $as_nop printf "%s\n" "#define OV_ISFLOAT is_float_type" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: is_float_type" >&5 printf "%s\n" " is_float_type" >&6; } echo '' >> oct-alt-includes.h ac_cv_octsym_OV_ISFLOAT=" is_float_type" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking is_integer_type or isinteger" >&5 printf %s "checking is_integer_type or isinteger... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> int main (void) { octave_value ().isinteger (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OV_ISINTEGER isinteger" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: isinteger" >&5 printf "%s\n" "isinteger" >&6; } echo ' ' >> oct-alt-includes.h ac_cv_octsym_OV_ISINTEGER="isinteger" else $as_nop printf "%s\n" "#define OV_ISINTEGER is_integer_type" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: is_integer_type" >&5 printf "%s\n" " is_integer_type" >&6; } echo '' >> oct-alt-includes.h ac_cv_octsym_OV_ISINTEGER=" is_integer_type" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking is_bool_type or islogical" >&5 printf %s "checking is_bool_type or islogical... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> int main (void) { octave_value ().islogical (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OV_ISLOGICAL islogical" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: islogical" >&5 printf "%s\n" "islogical" >&6; } echo ' ' >> oct-alt-includes.h ac_cv_octsym_OV_ISLOGICAL="islogical" else $as_nop printf "%s\n" "#define OV_ISLOGICAL is_bool_type" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: is_bool_type" >&5 printf "%s\n" " is_bool_type" >&6; } echo '' >> oct-alt-includes.h ac_cv_octsym_OV_ISLOGICAL=" is_bool_type" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking unwind_protect or octave::unwind_protect" >&5 printf %s "checking unwind_protect or octave::unwind_protect... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> #include <octave/unwind-prot.h> #include <octave/octave.h> int main (void) { octave::unwind_protect frame; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OCTAVE__UNWIND_PROTECT octave::unwind_protect" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: octave::unwind_protect" >&5 printf "%s\n" "octave::unwind_protect" >&6; } echo '#include <octave/unwind-prot.h> #include <octave/octave.h> ' >> oct-alt-includes.h ac_cv_octsym_OCTAVE__UNWIND_PROTECT="octave::unwind_protect" else $as_nop printf "%s\n" "#define OCTAVE__UNWIND_PROTECT unwind_protect" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unwind_protect" >&5 printf "%s\n" " unwind_protect" >&6; } echo '#include <octave/unwind-prot.h> #include <octave/octave.h> ' >> oct-alt-includes.h ac_cv_octsym_OCTAVE__UNWIND_PROTECT=" unwind_protect" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking octave_value_typeinfo::register_binary_op or octave::type_info::register_binary_op" >&5 printf %s "checking octave_value_typeinfo::register_binary_op or octave::type_info::register_binary_op... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> #include <octave/octave.h> #include <octave/interpreter.h> int main (void) { octave::type_info& ti = octave::interpreter::the_interpreter ()->get_type_info (); ti.register_binary_op(octave_value::op_eq, 1,1,0); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OCTAVE__REGISTER_BINARY_OP octave::type_info::register_binary_op" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: octave::type_info::register_binary_op" >&5 printf "%s\n" "octave::type_info::register_binary_op" >&6; } echo ' #include <octave/octave.h> #include <octave/interpreter.h> ' >> oct-alt-includes.h ac_cv_octsym_OCTAVE__REGISTER_BINARY_OP="octave::type_info::register_binary_op" else $as_nop printf "%s\n" "#define OCTAVE__REGISTER_BINARY_OP octave_value_typeinfo::register_binary_op" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: octave_value_typeinfo::register_binary_op" >&5 printf "%s\n" " octave_value_typeinfo::register_binary_op" >&6; } echo '#include <octave/octave.h>' >> oct-alt-includes.h ac_cv_octsym_OCTAVE__REGISTER_BINARY_OP=" octave_value_typeinfo::register_binary_op" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking octave_base_value or octave_base_dld_value" >&5 printf %s "checking octave_base_value or octave_base_dld_value... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> int main (void) { octave_base_dld_value tmp; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define OCTAVE_BASE_CLASS octave_base_dld_value" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: octave_base_dld_value" >&5 printf "%s\n" "octave_base_dld_value" >&6; } echo ' ' >> oct-alt-includes.h ac_cv_octsym_OCTAVE_BASE_CLASS="octave_base_dld_value" else $as_nop printf "%s\n" "#define OCTAVE_BASE_CLASS octave_base_value" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: octave_base_value" >&5 printf "%s\n" " octave_base_value" >&6; } echo '' >> oct-alt-includes.h ac_cv_octsym_OCTAVE_BASE_CLASS=" octave_base_value" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $ac_cv_octsym_OCTAVE__REGISTER_BINARY_OP = "octave::type_info::register_binary_op"; then printf "%s\n" "#define OCTAVE__NEW_REGISTER_OP /**/" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for octave::sys::u8_to_wstring" >&5 printf %s "checking for octave::sys::u8_to_wstring... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> #include <octave/lo-sysdep.h> int main (void) { std::wstring s = octave::sys::u8_to_wstring("test"); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : printf "%s\n" "#define HAVE_OCTAVE_U8_TO_WSTRING 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for octave_base_value count field" >&5 printf %s "checking for octave_base_value count field... " >&6; } octave_count_field=count cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "config.h" #endif class test_base_class : public octave_base_value { public: test_base_class() {} ~test_base_class() {} void test() { m_count ++; } bool is_object (void) const { return true; } }; int main (void) { test_base_class t; t.is_object(); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : octave_count_field=m_count else $as_nop octave_count_field=count fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $octave_count_field" >&5 printf "%s\n" "$octave_count_field" >&6; } printf "%s\n" "#define OV_COUNT $octave_count_field" >>confdefs.h CXX=$save_altsyms_CXX CXXFLAGS=$save_altsyms_CXXFLAGS LDFLAGS=$save_altsyms_LDFLAGS LIBS=$save_altsyms_LIBS build_parallel=no build_serial=no build_i2c=no build_spi=no build_usbtmc=no build_tcp=no build_udp=no build_gpib=no build_vxi11=no build_visa=no build_resolvehost=no build_modbus=no # Check for Windows { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for windows" >&5 printf %s "checking for windows... " >&6; } have_windows=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <windows.h> #ifndef __WIN32__ #error "Not windows!" #endif int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } have_windows=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # if windows, we can build some of the packages just by having # windows.h if test $have_windows = yes; then build_serial=yes BUILD_FOR_WINDOWS=1 # prevent some warnings by defining this ... printf "%s\n" "#define _NO_SYS_GUID_OPERATOR_EQ_ 1" >>confdefs.h fi # check for i2c # if linux/i2c-dev.h exists we are probably under linux, so build usbtmc as well ac_header= ac_cache= for ac_item in $ac_header_cxx_list do if test $ac_cache; then ac_fn_cxx_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in linux/i2c-dev.h do : ac_fn_cxx_check_header_compile "$LINENO" "linux/i2c-dev.h" "ac_cv_header_linux_i2c_dev_h" "$ac_includes_default" if test "x$ac_cv_header_linux_i2c_dev_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_I2C_DEV_H 1" >>confdefs.h build_i2c=yes build_usbtmc=yes fi done for ac_header in dev/iicbus/iic.h do : ac_fn_cxx_check_header_compile "$LINENO" "dev/iicbus/iic.h" "ac_cv_header_dev_iicbus_iic_h" "$ac_includes_default" if test "x$ac_cv_header_dev_iicbus_iic_h" = xyes then : printf "%s\n" "#define HAVE_DEV_IICBUS_IIC_H 1" >>confdefs.h build_i2c=yes fi done # check for spi for ac_header in linux/spi/spidev.h do : ac_fn_cxx_check_header_compile "$LINENO" "linux/spi/spidev.h" "ac_cv_header_linux_spi_spidev_h" "$ac_includes_default" if test "x$ac_cv_header_linux_spi_spidev_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_SPI_SPIDEV_H 1" >>confdefs.h build_spi=yes fi done # check for serial for ac_header in termios.h do : ac_fn_cxx_check_header_compile "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default" if test "x$ac_cv_header_termios_h" = xyes then : printf "%s\n" "#define HAVE_TERMIOS_H 1" >>confdefs.h build_serial=yes fi done # check for parallel for ac_header in linux/parport.h linux/ppdev.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_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 `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF build_parallel=yes fi done for ac_header in dev/ppbus/ppi.h dev/ppbus/ppbconf.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_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 `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF build_parallel=yes fi done # build tcp, available for most platforms for ac_header in sys/socket.h do : ac_fn_cxx_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" if test "x$ac_cv_header_sys_socket_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h build_tcp=yes fi done # Check for winsock2 and ws2_32 have_winsock2=no for ac_header in winsock2.h do : ac_fn_cxx_check_header_compile "$LINENO" "winsock2.h" "ac_cv_header_winsock2_h" "$ac_includes_default" if test "x$ac_cv_header_winsock2_h" = xyes then : printf "%s\n" "#define HAVE_WINSOCK2_H 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing _head_libws2_32_a" >&5 printf %s "checking for library containing _head_libws2_32_a... " >&6; } if test ${ac_cv_search__head_libws2_32_a+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int _head_libws2_32_a (); } int main (void) { return conftest::_head_libws2_32_a (); ; return 0; } _ACEOF for ac_lib in '' ws2_32 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__head_libws2_32_a=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search__head_libws2_32_a+y} then : break fi done if test ${ac_cv_search__head_libws2_32_a+y} then : else $as_nop ac_cv_search__head_libws2_32_a=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search__head_libws2_32_a" >&5 printf "%s\n" "$ac_cv_search__head_libws2_32_a" >&6; } ac_res=$ac_cv_search__head_libws2_32_a if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_winsock2=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing _head_lib32_libws2_32_a" >&5 printf %s "checking for library containing _head_lib32_libws2_32_a... " >&6; } if test ${ac_cv_search__head_lib32_libws2_32_a+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int _head_lib32_libws2_32_a (); } int main (void) { return conftest::_head_lib32_libws2_32_a (); ; return 0; } _ACEOF for ac_lib in '' ws2_32 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__head_lib32_libws2_32_a=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search__head_lib32_libws2_32_a+y} then : break fi done if test ${ac_cv_search__head_lib32_libws2_32_a+y} then : else $as_nop ac_cv_search__head_lib32_libws2_32_a=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search__head_lib32_libws2_32_a" >&5 printf "%s\n" "$ac_cv_search__head_lib32_libws2_32_a" >&6; } ac_res=$ac_cv_search__head_lib32_libws2_32_a if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_winsock2=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing _head_lib64_libws2_32_a" >&5 printf %s "checking for library containing _head_lib64_libws2_32_a... " >&6; } if test ${ac_cv_search__head_lib64_libws2_32_a+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int _head_lib64_libws2_32_a (); } int main (void) { return conftest::_head_lib64_libws2_32_a (); ; return 0; } _ACEOF for ac_lib in '' ws2_32 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__head_lib64_libws2_32_a=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search__head_lib64_libws2_32_a+y} then : break fi done if test ${ac_cv_search__head_lib64_libws2_32_a+y} then : else $as_nop ac_cv_search__head_lib64_libws2_32_a=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search__head_lib64_libws2_32_a" >&5 printf "%s\n" "$ac_cv_search__head_lib64_libws2_32_a" >&6; } ac_res=$ac_cv_search__head_lib64_libws2_32_a if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_winsock2=yes fi fi done if test $have_winsock2 = yes; then TCPLIBS="-lws2_32" build_tcp=yes build_resolvehost=yes fi # if can build tcp, can build udp if test $build_tcp = yes; then build_udp=yes fi # checks for resolve host if test $build_tcp = yes; then if test $build_resolvehost = no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing getnameinfo" >&5 printf %s "checking for library containing getnameinfo... " >&6; } if test ${ac_cv_search_getnameinfo+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int getnameinfo (); } int main (void) { return conftest::getnameinfo (); ; return 0; } _ACEOF for ac_lib in '' inet6 socket 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_getnameinfo=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_getnameinfo+y} then : break fi done if test ${ac_cv_search_getnameinfo+y} then : else $as_nop ac_cv_search_getnameinfo=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getnameinfo" >&5 printf "%s\n" "$ac_cv_search_getnameinfo" >&6; } ac_res=$ac_cv_search_getnameinfo if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" build_resolvehost=yes fi if test "x$ac_cv_search_getnameinfo" != "xno"; then test "x$ac_cv_search_getnameinfo" = "xnone required" || TCPLIBS=$ac_cv_search_getnameinfo fi fi fi # Checks for GPIB for ac_header in gpib/ib.h do : ac_fn_cxx_check_header_compile "$LINENO" "gpib/ib.h" "ac_cv_header_gpib_ib_h" "$ac_includes_default" if test "x$ac_cv_header_gpib_ib_h" = xyes then : printf "%s\n" "#define HAVE_GPIB_IB_H 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing ibrd" >&5 printf %s "checking for library containing ibrd... " >&6; } if test ${ac_cv_search_ibrd+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int ibrd (); } int main (void) { return conftest::ibrd (); ; return 0; } _ACEOF for ac_lib in '' gpib 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_ibrd=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_ibrd+y} then : break fi done if test ${ac_cv_search_ibrd+y} then : else $as_nop ac_cv_search_ibrd=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ibrd" >&5 printf "%s\n" "$ac_cv_search_ibrd" >&6; } ac_res=$ac_cv_search_ibrd if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" build_gpib=yes fi fi done if test "x$ac_cv_search_ibrd" != "xno"; then test "x$ac_cv_search_ibrd" = "xnone required" || GPIBLIBS=$ac_cv_search_ibrd fi # Checks for RPC/VXI11 # Check whether --with-librpc was given. if test ${with_librpc+y} then : withval=$with_librpc; with_libtirpc="$with_librpc" else $as_nop with_librpc="auto" fi if test "x${with_librpc}" = "xyes"; then with_librpc="auto" fi if test "x${with_librpc}" = "xno"; then with_librpc="none" fi if test "x${with_librpc}" = "xauto" || test "x${with_librpc}" = "xtirpc"; then 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libtirpc" >&5 printf %s "checking for libtirpc... " >&6; } if test -n "$TIRPC_CFLAGS"; then pkg_cv_TIRPC_CFLAGS="$TIRPC_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TIRPC_CFLAGS=`$PKG_CONFIG --cflags "libtirpc" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$TIRPC_LIBS"; then pkg_cv_TIRPC_LIBS="$TIRPC_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TIRPC_LIBS=`$PKG_CONFIG --libs "libtirpc" 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 TIRPC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libtirpc" 2>&1` else TIRPC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libtirpc" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$TIRPC_PKG_ERRORS" >&5 RPCINCLUDE="$RPCINCLUDE" elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } RPCINCLUDE="$RPCINCLUDE" else TIRPC_CFLAGS=$pkg_cv_TIRPC_CFLAGS TIRPC_LIBS=$pkg_cv_TIRPC_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } with_librpc="yes"; build_vxi11=yes; RPCINCLUDE="$RPCINCLUDE $TIRPC_CFLAGS"; RPCLIBS="$RPCLIBS $TIRPC_LIBS"; fi fi if test "x${with_librpc}" = "xauto" || test "x${with_librpc}" = "xsunrpc"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing clnt_create" >&5 printf %s "checking for library containing clnt_create... " >&6; } if test ${ac_cv_search_clnt_create+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int clnt_create (); } int main (void) { return conftest::clnt_create (); ; return 0; } _ACEOF for ac_lib in '' tirpc 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_clnt_create=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_clnt_create+y} then : break fi done if test ${ac_cv_search_clnt_create+y} then : else $as_nop ac_cv_search_clnt_create=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clnt_create" >&5 printf "%s\n" "$ac_cv_search_clnt_create" >&6; } ac_res=$ac_cv_search_clnt_create if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" with_librpc="yes" fi if test "x$ac_cv_search_clnt_create" != "xnone required"; then RPCLIBS="$RPCLIBS $ac_cv_search_clnt_create" fi for ac_header in rpc/rpc.h do : ac_fn_cxx_check_header_compile "$LINENO" "rpc/rpc.h" "ac_cv_header_rpc_rpc_h" "$ac_includes_default" if test "x$ac_cv_header_rpc_rpc_h" = xyes then : printf "%s\n" "#define HAVE_RPC_RPC_H 1" >>confdefs.h RPCINCLUDE="$RPC_CFLAGS" else $as_nop with_librpc="no"; build_vxi11=no fi done fi if test "x${with_librpc}" = "xauto"; then with_librpc="none" fi # with_librpc should now be yes, if found # none if was never wanted or not auto detected if test "x${with_librpc}" != "xyes" && test "x${with_librpc}" != "xnone"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Did not find valid rpc libraries - disabling vxi11 interface" >&5 printf "%s\n" "$as_me: Did not find valid rpc libraries - disabling vxi11 interface" >&6;} fi if test "x${with_librpc}" = "xyes"; then build_vxi11=yes # we support const input into clnt_create ? { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking const input allowed into clnt_perror" >&5 printf %s "checking const input allowed into clnt_perror... " >&6; } const_clnt_perror=no 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 save_LIBS=$LIBS save_CPPFLAGS=$CPPFLAGS LIBS=$RPCLIBS CPPFLAGS=$RPCINCLUDE cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <rpc/rpc.h> int main (void) { const char * msg = "const message"; CLIENT *clnt = 0; clnt_perror(clnt, msg); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } const_clnt_perror=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext LIBS=$save_LIBS= CPPFLAGS=$save_CPPFLAGS 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 $const_clnt_perror = yes; then printf "%s\n" "#define CONST_CLNT_SUPPORT 1" >>confdefs.h fi fi # we have rpcgen ? for ac_prog in rpcgen rpcgen-mt do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RPCGEN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RPCGEN"; then ac_cv_prog_RPCGEN="$RPCGEN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_RPCGEN="$ac_prog" printf "%s\n" "$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 RPCGEN=$ac_cv_prog_RPCGEN if test -n "$RPCGEN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 printf "%s\n" "$RPCGEN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$RPCGEN" && break done test -n "$RPCGEN" || RPCGEN="none" if test "xRPCGEN" = "xnone"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: No rpcgen found - if rpc sources are modified, the build will fail" >&5 printf "%s\n" "$as_me: WARNING: No rpcgen found - if rpc sources are modified, the build will fail" >&2;} else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${RPCGEN} accepts -M option" >&5 printf %s "checking whether ${RPCGEN} accepts -M option... " >&6; } rm -f rpcgen_test.* cat > rpcgen_test.x <<END program STRLEN { version STRLENVERS { int strlen(string) = 1; } = 1; } = 11; END RPCGENOPTS="" ${RPCGEN} -M rpcgen_test.x > /dev/null 2>&1 if test -f rpcgen_test.h; then _rpcgen_result=yes RPCGENOPTS="-M" else _rpcgen_result=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $_rpcgen_result" >&5 printf "%s\n" "$_rpcgen_result" >&6; } RPCGENOPTS=$RPCGENOPTS rm -f rpcgen_test.* rm -f rpcgen_test_* fi # Checks for openvisa for ac_header in visa/visa.h do : ac_fn_cxx_check_header_compile "$LINENO" "visa/visa.h" "ac_cv_header_visa_visa_h" "$ac_includes_default" if test "x$ac_cv_header_visa_visa_h" = xyes then : printf "%s\n" "#define HAVE_VISA_VISA_H 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing viOpenDefaultRM" >&5 printf %s "checking for library containing viOpenDefaultRM... " >&6; } if test ${ac_cv_search_viOpenDefaultRM+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int viOpenDefaultRM (); } int main (void) { return conftest::viOpenDefaultRM (); ; return 0; } _ACEOF for ac_lib in '' openvisa 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_viOpenDefaultRM=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_viOpenDefaultRM+y} then : break fi done if test ${ac_cv_search_viOpenDefaultRM+y} then : else $as_nop ac_cv_search_viOpenDefaultRM=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_viOpenDefaultRM" >&5 printf "%s\n" "$ac_cv_search_viOpenDefaultRM" >&6; } ac_res=$ac_cv_search_viOpenDefaultRM if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" build_visa=yes fi fi done if test "x$ac_cv_search_viOpenDefaultRM" != "xno"; then test "x$ac_cv_search_viOpenDefaultRM" = "xnone required" || VISALIBS=$ac_cv_search_viOpenDefaultRM fi # Checks for libmodbus build_modbus=no pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmodbus" >&5 printf %s "checking for libmodbus... " >&6; } if test -n "$LIBMODBUS_CFLAGS"; then pkg_cv_LIBMODBUS_CFLAGS="$LIBMODBUS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmodbus\""; } >&5 ($PKG_CONFIG --exists --print-errors "libmodbus") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBMODBUS_CFLAGS=`$PKG_CONFIG --cflags "libmodbus" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LIBMODBUS_LIBS"; then pkg_cv_LIBMODBUS_LIBS="$LIBMODBUS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmodbus\""; } >&5 ($PKG_CONFIG --exists --print-errors "libmodbus") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBMODBUS_LIBS=`$PKG_CONFIG --libs "libmodbus" 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 LIBMODBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmodbus" 2>&1` else LIBMODBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmodbus" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBMODBUS_PKG_ERRORS" >&5 build_modbus=no elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } build_modbus=no else LIBMODBUS_CFLAGS=$pkg_cv_LIBMODBUS_CFLAGS LIBMODBUS_LIBS=$pkg_cv_LIBMODBUS_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } for ac_header in modbus/modbus.h do : ac_fn_cxx_check_header_compile "$LINENO" "modbus/modbus.h" "ac_cv_header_modbus_modbus_h" "$ac_includes_default" if test "x$ac_cv_header_modbus_modbus_h" = xyes then : printf "%s\n" "#define HAVE_MODBUS_MODBUS_H 1" >>confdefs.h build_modbus=yes fi done fi if test $build_modbus = yes; then MODBUSLIBS=$LIBMODBUS_LIBS MODBUSINCLUDES=$LIBMODBUS_CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking modbus_set_response_timeout(modbus_t*,uint32,uint32)" >&5 printf %s "checking modbus_set_response_timeout(modbus_t*,uint32,uint32)... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <modbus/modbus.h> int main (void) { modbus_t *m=0; modbus_set_response_timeout(m,0,0); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_MODBUS_SET_RESPONSE_TIMEOUT2 /**/" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test $build_parallel = yes; then printf "%s\n" "#define BUILD_PARALLEL /**/" >>confdefs.h fi if test $build_serial = yes; then printf "%s\n" "#define BUILD_SERIAL /**/" >>confdefs.h fi if test $build_i2c = yes; then printf "%s\n" "#define BUILD_I2C /**/" >>confdefs.h fi if test $build_spi = yes; then printf "%s\n" "#define BUILD_SPI /**/" >>confdefs.h fi if test $build_usbtmc = yes; then printf "%s\n" "#define BUILD_USBTMC /**/" >>confdefs.h fi if test $build_tcp = yes; then printf "%s\n" "#define BUILD_TCP /**/" >>confdefs.h fi if test $build_udp = yes; then printf "%s\n" "#define BUILD_UDP /**/" >>confdefs.h fi if test $build_gpib = yes; then printf "%s\n" "#define BUILD_GPIB /**/" >>confdefs.h fi if test $build_vxi11 = yes; then printf "%s\n" "#define BUILD_VXI11 /**/" >>confdefs.h BUILD_VXI11=1 fi if test $build_visa = yes; then printf "%s\n" "#define BUILD_VISA /**/" >>confdefs.h fi if test $build_resolvehost = yes; then printf "%s\n" "#define BUILD_RESOLVEHOST /**/" >>confdefs.h fi if test $build_modbus = yes; then printf "%s\n" "#define BUILD_MODBUS /**/" >>confdefs.h fi # all done ac_config_files="$ac_config_files common.mk Makefile gpib/Makefile tcp/Makefile tcpclient/Makefile tcpserver/Makefile udp/Makefile udpport/Makefile vxi11/Makefile usbtmc/Makefile spi/Makefile serial/Makefile parallel/Makefile i2c/Makefile resolvehost/Makefile hwinfo/Makefile serialport/Makefile modbus/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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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+y} || &/ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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_nop 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_nop 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 || printf "%s\n" 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 # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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=`printf "%s\n" "$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 || printf "%s\n" 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 octave instrument control package $as_me 0.9.4, which was generated by GNU Autoconf 2.71. 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" _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 Report bugs to the package provider." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ octave instrument control package config.status 0.9.4 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 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' 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 ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$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=`printf "%s\n" "$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 ) printf "%s\n" "$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 \printf "%s\n" "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 printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _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 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "common.mk") CONFIG_FILES="$CONFIG_FILES common.mk" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "gpib/Makefile") CONFIG_FILES="$CONFIG_FILES gpib/Makefile" ;; "tcp/Makefile") CONFIG_FILES="$CONFIG_FILES tcp/Makefile" ;; "tcpclient/Makefile") CONFIG_FILES="$CONFIG_FILES tcpclient/Makefile" ;; "tcpserver/Makefile") CONFIG_FILES="$CONFIG_FILES tcpserver/Makefile" ;; "udp/Makefile") CONFIG_FILES="$CONFIG_FILES udp/Makefile" ;; "udpport/Makefile") CONFIG_FILES="$CONFIG_FILES udpport/Makefile" ;; "vxi11/Makefile") CONFIG_FILES="$CONFIG_FILES vxi11/Makefile" ;; "usbtmc/Makefile") CONFIG_FILES="$CONFIG_FILES usbtmc/Makefile" ;; "spi/Makefile") CONFIG_FILES="$CONFIG_FILES spi/Makefile" ;; "serial/Makefile") CONFIG_FILES="$CONFIG_FILES serial/Makefile" ;; "parallel/Makefile") CONFIG_FILES="$CONFIG_FILES parallel/Makefile" ;; "i2c/Makefile") CONFIG_FILES="$CONFIG_FILES i2c/Makefile" ;; "resolvehost/Makefile") CONFIG_FILES="$CONFIG_FILES resolvehost/Makefile" ;; "hwinfo/Makefile") CONFIG_FILES="$CONFIG_FILES hwinfo/Makefile" ;; "serialport/Makefile") CONFIG_FILES="$CONFIG_FILES serialport/Makefile" ;; "modbus/Makefile") CONFIG_FILES="$CONFIG_FILES modbus/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+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers 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 2>/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 ' <conf$$subs.awk | sed ' /^[^""]/{ N s/\n// } ' >>$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 ' <confdefs.h | sed ' s/'"$ac_delim"'/"\\\ "/g' >>$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 " 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=`printf "%s\n" "$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 '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$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 || printf "%s\n" 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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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 # _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@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$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 $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"; } && { printf "%s\n" "$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 printf "%s\n" "$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 { printf "%s\n" "/* $configure_input */" >&1 \ && 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$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 printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $PACKAGE_NAME is now configured with BUILD SERIAL: $build_serial BUILD PARALLEL: $build_parallel BUILD I2C: $build_i2c BUILD SPI: $build_spi BUILD TCP: $build_tcp BUILD UDP: $build_udp BUILD USBTMC: $build_usbtmc BUILD GPIB: $build_gpib BUILD VXI11: $build_vxi11 BUILD RESOLVEHOST: $build_resolvehost BUILD MODBUS: $build_modbus GPIB LIBS: $GPIBLIBS VXI11 LIBS: $RPCLIBS VXI11 INCLUDE: $RPCINCLUDE VISA LIBS: $VISALIBS TCP LIBS: $TCPLIBS MODBUS LIBS: $MODBUSLIBS MODBUS INCLUDE: $MODBUSINCLUDE " >&5 printf "%s\n" "$as_me: $PACKAGE_NAME is now configured with BUILD SERIAL: $build_serial BUILD PARALLEL: $build_parallel BUILD I2C: $build_i2c BUILD SPI: $build_spi BUILD TCP: $build_tcp BUILD UDP: $build_udp BUILD USBTMC: $build_usbtmc BUILD GPIB: $build_gpib BUILD VXI11: $build_vxi11 BUILD RESOLVEHOST: $build_resolvehost BUILD MODBUS: $build_modbus GPIB LIBS: $GPIBLIBS VXI11 LIBS: $RPCLIBS VXI11 INCLUDE: $RPCINCLUDE VISA LIBS: $VISALIBS TCP LIBS: $TCPLIBS MODBUS LIBS: $MODBUSLIBS MODBUS INCLUDE: $MODBUSINCLUDE " >&6;} ������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/configure.ac�����������������������������������������������������������0000644�0000000�0000000�00000034133�14743226261�015430� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. # ### Copyright (C) 2020-2024 John Donoghue <john.donoghue@ieee.org> ### ### 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 ### <http://www.gnu.org/licenses/>. AC_PREREQ([2.69]) AC_INIT([octave instrument control package],[0.9.4]) AC_CONFIG_HEADERS([config.h]) # Avoid warnings for redefining AH-generated preprocessor symbols of # Octave. AH_TOP([#include "undef-ah-octave.h"]) AC_CONFIG_MACRO_DIRS([m4]) AC_CANONICAL_HOST AC_CANONICAL_TARGET # Checks for programs. AC_PROG_CXX AC_PROG_GREP AC_PROG_SED AC_LANG(C++) # Define macros needed #AC_DEFINE(__STDC_CONSTANT_MACROS, [], [workaround for C++ programs to use C99 macros]) AC_CHECK_PROG([MKOCTFILE], [mkoctfile], [mkoctfile], [none]) if [test "$MKOCTFILE" = "none"]; then AC_MSG_ERROR([mkoctfile required to install $PACKAGE_NAME]) fi AC_CHECK_PROG(OCTAVE_CONFIG,octave-config,octave-config) test -z "$OCTAVE_CONFIG" && OCTAVE_CONFIG=$MKOCTFILE # try get around possible spaces in the path if test "X${IGNORE_MINGW_PATH_MODIFICATION}" == "X"; then case $host_os in mingw*) # try demangle spaces in escaped input strings MKOCTFILE=`echo $MKOCTFILE | $SED "s,\\\\\ ,?,g"` OCTAVE_CONFIG=`echo $OCTAVE_CONFIG | $SED "s,\\\\\ ,?,g"` ;; *) ;; esac fi ## Simple symbol alternatives of different Octave versions. save_altsyms_CXX="$CXX" save_altsyms_CXXFLAGS="$CXXFLAGS" save_altsyms_LDFLAGS="$LDFLAGS" save_altsyms_LIBS="$LIBS" OCTINCLUDEDIR="${OCTINCLUDEDIR:-`$MKOCTFILE -p OCTINCLUDEDIR`}/.." OCTLIBDIR=${OCTLIBDIR:-`$MKOCTFILE -p OCTLIBDIR`} if test "X${IGNORE_MINGW_PATH_MODIFICATION}" == "X"; then MSYSTEM="${MSYSTEM}" else MSYSTEM="none" fi case X$MSYSTEM in XMINGW64*) OCTAVE_HOME=`${MKOCTFILE} -p OCTAVE_HOME | $SED 's,\\\\,/,g'` # change \ to / and replace octave home part with mingw part OCTINCLUDEDIR=`echo $OCTINCLUDEDIR | $SED -e 's,\\\\,/,g' -e "s,${OCTAVE_HOME},/mingw64,g"` OCTLIBDIR=`echo $OCTLIBDIR | $SED -e 's,\\\\,/,g' -e "s,${OCTAVE_HOME},/mingw64,g"` ;; XMINGW32*) OCTAVE_HOME=`${MKOCTFILE} -p OCTAVE_HOME | $SED 's,\\\\,/,g'` # change \ to / and replace octave home part with mingw part OCTINCLUDEDIR=`echo $OCTINCLUDEDIR | $SED -e 's,\\\\,/,g' -e "s,${OCTAVE_HOME},/mingw32,g"` OCTLIBDIR=`echo $OCTLIBDIR | $SED -e 's,\\\\,/,g -e "s,${OCTAVE_HOME},/mingw32,g"'` ;; *) ;; esac CXX=`${MKOCTFILE} -p CXX` CXXFLAGS="-I$OCTINCLUDEDIR $CXXFLAGS" LDFLAGS="-L$OCTLIBDIR $LDFLAGS" LIBS="-loctinterp $LIBS" # includes AC_CHECK_HEADERS([octave/interpreter.h], [], [], [#include <octave/oct.h>] ) AC_CHECK_HEADERS([octave/lo-sysdep.h], [], [], [#include <octave/oct.h>] ) OF_OCTAVE_LIST_ALT_SYMS([ [dnl [feval], [octave::feval], [[octave::feval ("date");]], [OCTAVE__FEVAL], [[#include <octave/parse.h>]], [[#include <octave/parse.h>]] ], [dnl [is_float_type], [isfloat], [[octave_value ().isfloat ();]], [OV_ISFLOAT], [], [] ], [dnl [is_integer_type], [isinteger], [[octave_value ().isinteger ();]], [OV_ISINTEGER], [], [] ], [dnl [is_bool_type], [islogical], [[octave_value ().islogical ();]], [OV_ISLOGICAL], [], [] ], [dnl [unwind_protect], [octave::unwind_protect], [[octave::unwind_protect frame;]], [OCTAVE__UNWIND_PROTECT], [[#include <octave/unwind-prot.h>] [#include <octave/octave.h>] ], [[#include <octave/unwind-prot.h>] [#include <octave/octave.h>] ] ], [dnl [octave_value_typeinfo::register_binary_op], [octave::type_info::register_binary_op], [ [octave::type_info& ti = octave::interpreter::the_interpreter ()->get_type_info ();] [ti.register_binary_op(octave_value::op_eq, 1,1,0);] ], [OCTAVE__REGISTER_BINARY_OP], [[#include <octave/octave.h>]], [ [#include <octave/octave.h>] [#include <octave/interpreter.h>] ] ], [dnl [octave_base_value], [octave_base_dld_value], [[octave_base_dld_value tmp;]], [OCTAVE_BASE_CLASS], [], [] ] ],[oct-alt-includes.h]) if test $ac_cv_octsym_OCTAVE__REGISTER_BINARY_OP = "octave::type_info::register_binary_op"; then AC_DEFINE([OCTAVE__NEW_REGISTER_OP], [], [Use new register_binary_op]) fi OF_OCTAVE_CHECK_SYM( [for octave::sys::u8_to_wstring], [ std::wstring s = octave::sys::u8_to_wstring("test"); ], [HAVE_OCTAVE_U8_TO_WSTRING], [ #include <octave/lo-sysdep.h> ] ) AC_MSG_CHECKING([for octave_base_value count field]) octave_count_field=count AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "config.h" #endif class test_base_class : public octave_base_value { public: test_base_class() {} ~test_base_class() {} void test() { m_count ++; } bool is_object (void) const { return true; } }; ]], [ test_base_class t; t.is_object(); ])], [octave_count_field=m_count], [octave_count_field=count] ) AC_MSG_RESULT([$octave_count_field]) AC_DEFINE_UNQUOTED([OV_COUNT],$octave_count_field,[octave_base_value ref count field]) CXX=$save_altsyms_CXX CXXFLAGS=$save_altsyms_CXXFLAGS LDFLAGS=$save_altsyms_LDFLAGS LIBS=$save_altsyms_LIBS build_parallel=no build_serial=no build_i2c=no build_spi=no build_usbtmc=no build_tcp=no build_udp=no build_gpib=no build_vxi11=no build_visa=no build_resolvehost=no build_modbus=no # Check for Windows AC_MSG_CHECKING([for windows]) have_windows=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <windows.h> #ifndef __WIN32__ #error "Not windows!" #endif ]], [])], [AC_MSG_RESULT([yes]) have_windows=yes], [AC_MSG_RESULT([no])]) # if windows, we can build some of the packages just by having # windows.h if test $have_windows = yes; then build_serial=yes AC_SUBST([BUILD_FOR_WINDOWS], [1], [build using native windows functions]) # prevent some warnings by defining this ... AC_DEFINE([_NO_SYS_GUID_OPERATOR_EQ_], [1], [Dont define guid == ops]) fi # check for i2c # if linux/i2c-dev.h exists we are probably under linux, so build usbtmc as well AC_CHECK_HEADERS([linux/i2c-dev.h],[build_i2c=yes build_usbtmc=yes]) AC_CHECK_HEADERS([dev/iicbus/iic.h],[build_i2c=yes]) # check for spi AC_CHECK_HEADERS([linux/spi/spidev.h],[build_spi=yes]) # check for serial AC_CHECK_HEADERS([termios.h],[build_serial=yes]) # check for parallel AC_CHECK_HEADERS([linux/parport.h linux/ppdev.h],[build_parallel=yes]) AC_CHECK_HEADERS([dev/ppbus/ppi.h dev/ppbus/ppbconf.h],[build_parallel=yes]) # build tcp, available for most platforms AC_CHECK_HEADERS([sys/socket.h],[build_tcp=yes]) # Check for winsock2 and ws2_32 have_winsock2=no AC_CHECK_HEADERS([winsock2.h], [AC_SEARCH_LIBS([_head_libws2_32_a], [ws2_32], [have_winsock2=yes] , [] ) AC_SEARCH_LIBS([_head_lib32_libws2_32_a], [ws2_32], [have_winsock2=yes] , [] ) AC_SEARCH_LIBS([_head_lib64_libws2_32_a], [ws2_32], [have_winsock2=yes] , [] ) ], []) if test $have_winsock2 = yes; then AC_SUBST(TCPLIBS, ["-lws2_32"]) build_tcp=yes build_resolvehost=yes fi # if can build tcp, can build udp if test $build_tcp = yes; then build_udp=yes fi # checks for resolve host if test $build_tcp = yes; then if test $build_resolvehost = no; then AC_SEARCH_LIBS(getnameinfo, [inet6 socket], [build_resolvehost=yes]) if test "x$ac_cv_search_getnameinfo" != "xno"; then test "x$ac_cv_search_getnameinfo" = "xnone required" || AC_SUBST(TCPLIBS, [$ac_cv_search_getnameinfo]) fi fi fi # Checks for GPIB AC_CHECK_HEADERS([gpib/ib.h], [AC_SEARCH_LIBS([ibrd], [gpib], [build_gpib=yes], [])] , [] ) if test "x$ac_cv_search_ibrd" != "xno"; then test "x$ac_cv_search_ibrd" = "xnone required" || AC_SUBST(GPIBLIBS, [$ac_cv_search_ibrd]) fi # Checks for RPC/VXI11 AC_ARG_WITH([librpc], [AS_HELP_STRING([--with-librpc=tirpc|sunrpc|auto|none],[Choose use/selection of librpc used])], [with_libtirpc="$with_librpc"], [with_librpc="auto"]) if test "x${with_librpc}" = "xyes"; then with_librpc="auto" fi if test "x${with_librpc}" = "xno"; then with_librpc="none" fi if test "x${with_librpc}" = "xauto" || test "x${with_librpc}" = "xtirpc"; then PKG_CHECK_MODULES([TIRPC], [libtirpc], [with_librpc="yes"; build_vxi11=yes; RPCINCLUDE="$RPCINCLUDE $TIRPC_CFLAGS"; RPCLIBS="$RPCLIBS $TIRPC_LIBS";], [RPCINCLUDE="$RPCINCLUDE"]) fi if test "x${with_librpc}" = "xauto" || test "x${with_librpc}" = "xsunrpc"; then AC_SEARCH_LIBS([clnt_create], [tirpc], [with_librpc="yes"], []) if test "x$ac_cv_search_clnt_create" != "xnone required"; then RPCLIBS="$RPCLIBS $ac_cv_search_clnt_create" fi AC_CHECK_HEADERS([rpc/rpc.h],[RPCINCLUDE="$RPC_CFLAGS"],[with_librpc="no"; build_vxi11=no]) fi if test "x${with_librpc}" = "xauto"; then with_librpc="none" fi AC_SUBST(RPCINCLUDE) AC_SUBST(RPCLIBS) # with_librpc should now be yes, if found # none if was never wanted or not auto detected if test "x${with_librpc}" != "xyes" && test "x${with_librpc}" != "xnone"; then AC_MSG_NOTICE([Did not find valid rpc libraries - disabling vxi11 interface]) fi if test "x${with_librpc}" = "xyes"; then build_vxi11=yes # we support const input into clnt_create ? AC_MSG_CHECKING([const input allowed into clnt_perror]) const_clnt_perror=no AC_LANG_PUSH([C++]) save_LIBS=$LIBS save_CPPFLAGS=$CPPFLAGS LIBS=$RPCLIBS CPPFLAGS=$RPCINCLUDE AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <rpc/rpc.h> ]], [[ const char * msg = "const message"; CLIENT *clnt = 0; clnt_perror(clnt, msg); ]])], [AC_MSG_RESULT([yes]) const_clnt_perror=yes], [AC_MSG_RESULT([no])] ) LIBS=$save_LIBS= CPPFLAGS=$save_CPPFLAGS AC_LANG_POP([C++]) if test $const_clnt_perror = yes; then AC_DEFINE([CONST_CLNT_SUPPORT], [1], [clnt allows const inputs]) fi fi # we have rpcgen ? AC_CHECK_PROGS([RPCGEN], [rpcgen rpcgen-mt], [none]) if test "xRPCGEN" = "xnone"; then AC_MSG_WARN([No rpcgen found - if rpc sources are modified, the build will fail]) else AC_MSG_CHECKING([whether ${RPCGEN} accepts -M option]) rm -f rpcgen_test.* cat > rpcgen_test.x <<END program STRLEN { version STRLENVERS { int strlen(string) = 1; } = 1; } = 11; END RPCGENOPTS="" ${RPCGEN} -M rpcgen_test.x > /dev/null 2>&1 if test -f rpcgen_test.h; then _rpcgen_result=yes RPCGENOPTS="-M" else _rpcgen_result=no fi AC_MSG_RESULT([$_rpcgen_result]) AC_SUBST([RPCGENOPTS], [$RPCGENOPTS]) rm -f rpcgen_test.* rm -f rpcgen_test_* fi # Checks for openvisa AC_CHECK_HEADERS([visa/visa.h], [AC_SEARCH_LIBS([viOpenDefaultRM], [openvisa], [build_visa=yes], [])] , [] ) if test "x$ac_cv_search_viOpenDefaultRM" != "xno"; then test "x$ac_cv_search_viOpenDefaultRM" = "xnone required" || AC_SUBST(VISALIBS, [$ac_cv_search_viOpenDefaultRM]) fi # Checks for libmodbus build_modbus=no PKG_CHECK_MODULES([LIBMODBUS], [libmodbus], [AC_CHECK_HEADERS([modbus/modbus.h],[build_modbus=yes], [])], [build_modbus=no]) if test $build_modbus = yes; then AC_SUBST(MODBUSLIBS, [$LIBMODBUS_LIBS]) AC_SUBST(MODBUSINCLUDES, [$LIBMODBUS_CFLAGS]) AC_MSG_CHECKING([modbus_set_response_timeout(modbus_t*,uint32,uint32)]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <modbus/modbus.h>]], [[ modbus_t *m=0; modbus_set_response_timeout(m,0,0); ]])], [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_MODBUS_SET_RESPONSE_TIMEOUT2], [], [Defined if have modbus_set_response_timeout(modbus_t*,uint32,uint32)])], [AC_MSG_RESULT([no])]) fi if test $build_parallel = yes; then AC_DEFINE([BUILD_PARALLEL], [], [build PARALLEL interface functions]) fi if test $build_serial = yes; then AC_DEFINE([BUILD_SERIAL], [], [build SERIAL interface functions]) fi if test $build_i2c = yes; then AC_DEFINE([BUILD_I2C], [], [build I2C interface functions]) fi if test $build_spi = yes; then AC_DEFINE([BUILD_SPI], [], [build SPI interface functions]) fi if test $build_usbtmc = yes; then AC_DEFINE([BUILD_USBTMC], [], [build USBTMC interface functions]) fi if test $build_tcp = yes; then AC_DEFINE([BUILD_TCP], [], [build TCP interface functions]) fi if test $build_udp = yes; then AC_DEFINE([BUILD_UDP], [], [build UDP interface functions]) fi if test $build_gpib = yes; then AC_DEFINE([BUILD_GPIB], [], [build GPIB interface functions]) fi if test $build_vxi11 = yes; then AC_DEFINE([BUILD_VXI11], [], [build VXI11 interface functions]) AC_SUBST([BUILD_VXI11], [1]) fi if test $build_visa = yes; then AC_DEFINE([BUILD_VISA], [], [build VISA interface functions]) fi if test $build_resolvehost = yes; then AC_DEFINE([BUILD_RESOLVEHOST], [], [build resolvehost function]) fi if test $build_modbus = yes; then AC_DEFINE([BUILD_MODBUS], [], [build MODBUS interface functions]) fi # all done AC_CONFIG_FILES([common.mk Makefile gpib/Makefile tcp/Makefile tcpclient/Makefile tcpserver/Makefile udp/Makefile udpport/Makefile vxi11/Makefile usbtmc/Makefile spi/Makefile serial/Makefile parallel/Makefile i2c/Makefile resolvehost/Makefile hwinfo/Makefile serialport/Makefile modbus/Makefile]) AC_OUTPUT AC_MSG_NOTICE([ $PACKAGE_NAME is now configured with BUILD SERIAL: $build_serial BUILD PARALLEL: $build_parallel BUILD I2C: $build_i2c BUILD SPI: $build_spi BUILD TCP: $build_tcp BUILD UDP: $build_udp BUILD USBTMC: $build_usbtmc BUILD GPIB: $build_gpib BUILD VXI11: $build_vxi11 BUILD RESOLVEHOST: $build_resolvehost BUILD MODBUS: $build_modbus GPIB LIBS: $GPIBLIBS VXI11 LIBS: $RPCLIBS VXI11 INCLUDE: $RPCINCLUDE VISA LIBS: $VISALIBS TCP LIBS: $TCPLIBS MODBUS LIBS: $MODBUSLIBS MODBUS INCLUDE: $MODBUSINCLUDE ]) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014057� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/Makefile.in�������������������������������������������������������0000644�0000000�0000000�00000000417�14743226261�016126� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../gpib.oct OBJ := gpib.o gpib_timeout.o gpib_write.o gpib_close.o gpib_read.o __gpib_spoll__.o __gpib_trigger__.o __gpib_clrdevice__.o gpib_class.o __gpib_pkg_lock__.o LFLAGS = $(LIBS) @GPIBLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/__gpib_clrdevice__.cc���������������������������������������������0000644�0000000�0000000�00000003227�14743226261�020127� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <errno.h> #include "gpib_class.h" #endif // PKG_ADD: autoload ("__gpib_clrdevice__", "gpib.oct"); DEFUN_DLD (__gpib_clrdevice__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} __gpib_clrdevice__ (@var{gpib})\n \ \n\ Sends clear command to gpib device.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.@*\ \n\ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_gpib::static_type_id ()) { print_usage (); return octave_value (-1); } octave_gpib* gpib = NULL; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); gpib->cleardevice (); return octave_value (); #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/__gpib_pkg_lock__.cc����������������������������������������������0000644�0000000�0000000�00000002761�14743226261�017762� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__gpib_pkg_lock__", "gpib.oct"); // PKG_ADD: __gpib_pkg_lock__(1); // PKG_DEL: __gpib_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__gpib_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__gpib_pkg_lock__")) interp.munlock("__gpib_pkg_lock__"); } return retval; } #else DEFUN_DLD(__gpib_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif ���������������instrument-control-0.9.4/src/gpib/__gpib_spoll__.cc�������������������������������������������������0000644�0000000�0000000�00000003472�14743226261�017322� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <errno.h> #include "gpib_class.h" #endif // PKG_ADD: autoload ("__gpib_spoll__", "gpib.oct"); DEFUN_DLD (__gpib_spoll__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{sb} = } __gpib_spoll__ (@var{gpib})\n \ \n\ serial poll gpib interface.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.@*\ \n\ Upon successful completion, gpib_spoll() shall return the status byte @var{sb}.\n \ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_gpib::static_type_id ()) { print_usage (); return octave_value (-1); } octave_gpib* gpib = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); char rqs; retval = gpib->spoll (&rqs); if (retval == -1) return octave_value (); return octave_value (rqs); #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/__gpib_trigger__.cc�����������������������������������������������0000644�0000000�0000000�00000003200�14743226261�017621� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <errno.h> #include "gpib_class.h" #endif // PKG_ADD: autoload ("__gpib_trigger__", "gpib.oct"); DEFUN_DLD (__gpib_trigger__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} __gpib_trigger__ (@var{gpib})\n \ \n\ triggers gpib device.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.@*\ \n\ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_gpib::static_type_id ()) { print_usage (); return octave_value (-1); } octave_gpib* gpib = NULL; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); gpib->trigger (); return octave_value (); #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/gpib.cc�����������������������������������������������������������0000644�0000000�0000000�00000006151�14743226261�015312� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <errno.h> //#include <fcntl.h> #include "gpib_class.h" #endif // PKG_ADD: autoload ("gpib", "gpib.oct"); DEFUN_DLD (gpib, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{gpib} = } gpib ([@var{gpibid}], [@var{timeout}])\n \ \n\ Open gpib interface.\n \ \n\ @var{gpibid} - the interface number.@* \ @var{timeout} - the interface timeout value. If omitted defaults to blocking call.\n \ \n\ The gpib() shall return instance of @var{octave_gpib} class as the result @var{gpib}.\n \ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values int gpibid; const int minor = 0; int timeout = -1; const int secid = 0; const int send_eoi = 1; const int eos_mode = 0; // Parse the function arguments if (args.length() > 0) { if (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) { gpibid = args (0).int_value (); } else { print_usage (); return octave_value (); } } else { print_usage (); return octave_value (); } // is_float_type() is or'ed to allow expression like ("", 123), without user // having to use ("", int32(123)), as we still only take "int_value" if (args.length() > 1) { if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { timeout = args (1).int_value (); } else { print_usage (); return octave_value (); } } // Open the interface octave_gpib* retval = new octave_gpib (); retval->open (minor, gpibid, secid, timeout, send_eoi, eos_mode); //retval->set_timeout(timeout); //retval->set_sad(eot); //retval->set_send_eoi(eot); //retval->set_eos_mode(eot); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "gpib")) %! fail ("gpib ()", "Invalid call to gpib"); %! else %! fail ("gpib ()", "gpib: Your system doesn't support the GPIB interface"); %! endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/gpib_class.cc�����������������������������������������������������0000644�0000000�0000000�00000020424�14743226261�016476� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/unwind-prot.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <iostream> #include <string> #include <algorithm> #include <stdio.h> #include <unistd.h> #include "gpib/ib.h" #define GPIB_USEBLOCKREAD #include "gpib_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_gpib, "octave_gpib", "octave_gpib"); static void close_fd (int fd) { ibonl(fd,0); } octave_gpib::octave_gpib () { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } minor = -1; gpibid = -1; } octave_gpib::~octave_gpib () { octave_gpib::close (); } void octave_gpib::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_gpib::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_gpib::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << gpibid; } int octave_gpib::open (int minor, int gpibid, int sad, int timeout, int send_eoi, int eos_mode) { this->minor = minor; this->gpibid = gpibid; this->sad = sad; this->timeout = timeout; this->send_eoi = send_eoi; this->eos_mode = eos_mode; return 1; } int octave_gpib::read (uint8_t *buf, unsigned int len, bool *eoi) { int gperr,fd; int bytes_read = 0; if (this->minor < 0) { error ("gpib_read: Interface must be opened first..."); return -1; } fd = ibdev (this->minor, this->gpibid, this->sad, this->timeout, this->send_eoi, this->eos_mode); if (fd < 0) { error ("gpib_read: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); #if defined(GPIB_USEBLOCKREAD) // blocking read - not interruptable gperr = ibrd (fd,(void *)buf,len); if (gperr & ERR) { if (gperr & TIMO) { warning ("gpib_read: read timeout"); } else { int localiberr = ThreadIberr (); error ("gpib_read: Error while reading: %d - %d\n", gperr, localiberr); if (localiberr == 0) { localiberr = ThreadIbcnt (); warning ("gpib_read: failed system call: %d - %s\n", localiberr, strerror (localiberr)); } return -1; } } #else // async read - not interruptable as well gperr = ibrda (fd, (void *)buf, len); if (gperr & ERR) { error ("gpib_read: Error while reading: %d\n", ThreadIberr()); return -1; } while (1) { OCTAVE_QUIT; gperr = ibwait (fd,CMPL); warning ("gpib_read: read timeout %d - %d - %d",gperr, ThreadIberr (),ThreadIbcnt ()); if (gperr & ERR) { if (gperr & TIMO) { warning ("gpib_read: read timeout"); } else { int localiberr = ThreadIberr (); error ("gpib_read: Error while reading: %d - %d\n", gperr, localiberr); if (localiberr == 0) { localiberr = ThreadIbcnt(); warning ("gpib_read: failed system call: %d - %s\n", localiberr, strerror (localiberr)); } return -1; } } } #endif bytes_read = ThreadIbcnt (); *eoi = (ThreadIbsta () & 0x2000) ? true : false; return bytes_read; } int octave_gpib::write (const std::string &str) { int gperr,fd; if (minor < 0) { error ("gpib_write: Interface must be opened first..."); return -1; } fd = ibdev (minor, gpibid, sad, timeout, send_eoi, eos_mode); if (fd < 0) { error ("gpib_read: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); gperr = ibwrt (fd,str.c_str (), str.length ()); if (gperr & ERR) { // warning: can not write if (ThreadIberr () != ENOL) { // ENOL is handled by library error ("gpib: can not write gpib data to device"); } } return gperr; } int octave_gpib::write (uint8_t *buf, unsigned int len) { int gperr,fd; if (minor < 0) { error ("gpib_write: Interface must be opened first..."); return -1; } fd = ibdev(minor, gpibid, sad, timeout, send_eoi, eos_mode); if (fd < 0) { error ("gpib_write: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); gperr = ibwrt (fd, buf, len); if (gperr & ERR) { // warning: can not write if (ThreadIberr() != ENOL) { // ENOL is handled by library error ("gpib: can not write gpib data to device"); } } return gperr; } int octave_gpib::spoll (char *rqs) { int gperr,fd; if (minor < 0) { error("gpib_spoll: Interface must be opened first..."); return -1; } fd = ibdev (minor, gpibid, sad, timeout, send_eoi, eos_mode); if (fd < 0) { error ("gpib_spoll: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); gperr = ibrsp (fd,rqs); if (gperr & ERR) { error ("gpib_spoll: some error occured: %d", ThreadIberr ()); return -1; } //warning ("aaa: %X - %X",gperr, buf); return gperr; } int octave_gpib::trigger() { int gperr,fd; if (this->minor < 0) { error ("gpib_trigger: Interface must be opened first..."); return -1; } fd = ibdev(minor, gpibid, sad, timeout, send_eoi, eos_mode); if (fd < 0) { error("gpib_trigger: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); gperr = ibtrg (fd); if (gperr & ERR) { error ("gpib_trigger: some error occured: %d", ThreadIberr ()); return -1; } return gperr; } int octave_gpib::cleardevice() { int gperr,fd; if (minor < 0) { error ("gpib_clear: Interface must be opened first..."); return -1; } fd = ibdev(minor, gpibid, sad, timeout, send_eoi, eos_mode); if (fd < 0) { error("gpib_clear: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); gperr = ibclr(fd); if (gperr & ERR) { error ("gpib_clear: some error occured: %d", ThreadIberr ()); return -1; } return gperr; } int octave_gpib::set_timeout (int newtimeout) { if (minor < 0) { error ("gpib_timeout: Interface must be opened first..."); return -1; } if (timeout < 0 || timeout > 17) { error ("gpib_timeout: timeout must be between 0 and 17"); return -1; } timeout = newtimeout; return 1; } int octave_gpib::get_timeout() const { return timeout; } int octave_gpib::close() { int fd,gperr; if (minor > -1) { fd = ibdev(minor, gpibid, sad, timeout, send_eoi, eos_mode); if (fd < 0) { error("gpib_close: error opening gpib device..."); return -1; } // set up a frame to close fd OCTAVE__UNWIND_PROTECT frame; frame.add_fcn (close_fd, fd); gperr = ibloc (fd); if (gperr & ERR) { error ("gpib_close: can not set device to local"); } } minor = -1; return -1; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/gpib_class.h������������������������������������������������������0000644�0000000�0000000�00000004071�14743226261�016340� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef GPIB_CLASS_H #define GPIB_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_gpib : public OCTAVE_BASE_CLASS { public: octave_gpib(); ~octave_gpib(); int write(const std::string&); int write(uint8_t*, unsigned int); int read(uint8_t*, unsigned int, bool*); int spoll(char*); int trigger(); int cleardevice(); int open(int, int, int, int, int, int); int close(); int set_timeout(int); int get_timeout() const; //int set_sad(int); //int set_send_eoi(int); //int set_eos_mode(int); // Overloaded base functions double gpib_value() const { return (double)this->gpibid; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)this->gpibid; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool print_as_scalar (void) const { return true;} private: int minor; int gpibid; int sad; int timeout; int send_eoi; int eos_mode; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/gpib_close.cc�����������������������������������������������������0000644�0000000�0000000�00000003146�14743226261�016500� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include "gpib_class.h" #endif // PKG_ADD: autoload ("gpib_close", "gpib.oct"); DEFUN_DLD (gpib_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gpib_close (@var{gpib})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.\n \ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else if (args.length() != 1 || args(0).type_id() != octave_gpib::static_type_id()) { print_usage (); return octave_value (-1); } octave_gpib* gpib = NULL; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); gpib->close (); return octave_value (); #endif } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/gpib_read.cc������������������������������������������������������0000644�0000000�0000000�00000005515�14743226261�016310� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <octave/uint8NDArray.h> #include <errno.h> #include "gpib_class.h" #endif // PKG_ADD: autoload ("gpib_read", "gpib.oct"); DEFUN_DLD (gpib_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}, @var{eoi}] = } gpib_read (@var{gpib}, @var{n})\n \ \n\ Read from gpib interface.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.@* \ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ The gpib_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @var{eoi} indicates read operation complete \n \ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else if (args.length () < 2 || args.length () > 3 || args (0).type_id () != octave_gpib::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 0; if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } buffer_len = args (1).int_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("gpib_read: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } octave_gpib* gpib = NULL; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); // Read data bool eoi; int bytes_read = gpib->read (buffer, buffer_len, &eoi); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data(dim_vector (1, bytes_read)); for (int i = 0; i < bytes_read; i++) data (i) = buffer[i]; return_list (0) = data; return_list (1) = bytes_read; return_list (2) = eoi; return return_list; #endif } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/gpib/gpib_timeout.cc���������������������������������������������������0000644�0000000�0000000�00000004721�14743226261�017061� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include "gpib_class.h" #endif // PKG_ADD: autoload ("gpib_timeout", "gpib.oct"); DEFUN_DLD (gpib_timeout, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gpib_timeout (@var{gpib}, @var{timeout})\n \ @deftypefnx {Loadable Function} {@var{t} = } gpib_timeout (@var{gpib})\n \ \n\ Set new or get existing gpib interface timeout parameter. The timeout value is valid from 0 to 17.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.@* \ @var{timeout} - Value of 0 means never timeout, 11 means one second and 17 means 1000 seconds (see GPIB documentation (ibtmo) for further details)\n \ \n\ If @var{timeout} parameter is omitted, the gpib_timeout() shall return current timeout value as the result @var{t}.\n \ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value(); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_gpib::static_type_id ()) { print_usage (); return octave_value (-1); } octave_gpib* gpib = NULL; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); // Setting new timeout if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } gpib->set_timeout (args (1).int_value ()); return octave_value (); // Should it return by default? } // Returning current timeout return octave_value (gpib->get_timeout ()); #endif } �����������������������������������������������instrument-control-0.9.4/src/gpib/gpib_write.cc�����������������������������������������������������0000644�0000000�0000000�00000005061�14743226261�016523� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_GPIB #include <errno.h> #include "gpib_class.h" #endif // PKG_ADD: autoload ("gpib_write", "gpib.oct"); DEFUN_DLD (gpib_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } gpib_write (@var{gpib}, @var{data})\n \ \n\ Write data to a gpib interface.\n \ \n\ @var{gpib} - instance of @var{octave_gpib} class.@* \ @var{data} - data to be written to the gpib interface. Can be either of String or uint8 type.\n \ \n\ Upon successful completion, gpib_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_GPIB error ("gpib: Your system doesn't support the GPIB interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_gpib::static_type_id ()) { print_usage(); return octave_value(-1); } octave_gpib* gpib = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); gpib = &((octave_gpib &)rep); if (args (1).is_string ()) // String { retval = gpib->write (args (1).string_value ()); } else if (args (1).is_uint8_type ()) // uint8_t { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("gpib_write: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value(-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data (i)); retval = gpib->write (buf, data.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/hwinfo/����������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014430� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/hwinfo/Makefile.in�����������������������������������������������������0000644�0000000�0000000�00000000230�14743226261�016470� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../__instr_hwinfo__.oct OBJ := __instr_hwinfo__.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/hwinfo/__instr_hwinfo__.cc���������������������������������������������0000644�0000000�0000000�00000004334�14743226261�020250� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017-2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/oct-map.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif DEFUN_DLD (__instr_hwinfo__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{res} = } __instr_hwinfo__()\n \ \n\ Internal private function\n \ \n\ @end deftypefn") { octave_value_list return_value; octave_value_list interfaces; octave_map inf; inf.assign("ToolboxVersion", octave_value(PACKAGE_VERSION)); inf.assign("ToolboxName", octave_value(PACKAGE_NAME)); int int_count = 0; #ifdef BUILD_GPIB interfaces (int_count++) = "gpib"; #endif #ifdef BUILD_I2C interfaces (int_count++) = "i2c"; #endif #ifdef BUILD_MODBUS interfaces (int_count++) = "modbus"; #endif #ifdef BUILD_PARALLEL interfaces (int_count++) = "parallel"; #endif #ifdef BUILD_SERIAL interfaces (int_count++) = "serial"; interfaces (int_count++) = "serialport"; #endif #ifdef BUILD_SPI interfaces (int_count++) = "spi"; #endif #ifdef BUILD_TCP interfaces (int_count++) = "tcp"; interfaces (int_count++) = "tcpclient"; interfaces (int_count++) = "tcpserver"; #endif #ifdef BUILD_UDP interfaces (int_count++) = "udp"; interfaces (int_count++) = "udpport"; #endif #ifdef BUILD_USBTMC interfaces (int_count++) = "usbtmc"; #endif #ifdef BUILD_VXI11 interfaces (int_count++) = "vxi11"; #endif inf.assign("SupportedInterfaces", octave_value(interfaces.cell_value())); return_value (0) = inf; return return_value; } #if 0 %!test %! a = __instr_hwinfo__(); %! assert (! isempty (a)); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/�������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013613� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/Makefile.in��������������������������������������������������������0000644�0000000�0000000�00000000321�14743226261�015654� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../i2c.oct OBJ := i2c.o i2c_close.o i2c_addr.o i2c_write.o i2c_read.o i2c_class.o __i2c_pkg_lock__.o __i2c_properties__.o LFLAGS = $(LIBS) CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/__i2c_pkg_lock__.cc������������������������������������������������0000644�0000000�0000000�00000002751�14743226261�017251� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__i2c_pkg_lock__", "i2c.oct"); // PKG_ADD: __i2c_pkg_lock__(1); // PKG_DEL: __i2c_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__i2c_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__i2c_pkg_lock__")) interp.munlock("__i2c_pkg_lock__"); } return retval; } #else DEFUN_DLD(__i2c_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �����������������������instrument-control-0.9.4/src/i2c/__i2c_properties__.cc����������������������������������������������0000644�0000000�0000000�00000005252�14743226261�017653� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_I2C # include "i2c_class.h" #endif // PKG_ADD: autoload ("__i2c_properties__", "i2c.oct"); DEFUN_DLD (__i2c_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __i2c_properties__ (@var{octave_i2c}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_I2C if (args.length () < 2 || args.length () > 3 || args(0).type_id () != octave_i2c::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_i2c* i2c = &((octave_i2c &)rep); std::string property = args(1).string_value (); if (args.length () == 2) // get { if (property == "name") return octave_value (i2c->get_name ()); else if (property == "remoteaddress") return octave_value (i2c->get_addr ()); else if (property == "status") return octave_value (i2c->get_status ()); else if (property == "port") return octave_value (i2c->get_port ()); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (i2c->set_name (args(2).string_value ())); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "remoteaddress") return octave_value (i2c->set_addr (args(2).int_value ())); else if (property == "port") (*current_liboctave_error_handler) ("can not set this property"); else (*current_liboctave_error_handler) ("invalid property name"); } #else /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the I2C interface"); #endif return octave_value(); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c.cc�������������������������������������������������������������0000644�0000000�0000000�00000006222�14743226261�014601� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017-2020 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_I2C #include <fcntl.h> #include "i2c_class.h" #endif // PKG_ADD: autoload ("i2c", "i2c.oct"); DEFUN_DLD (i2c, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{i2c} = } i2c ([@var{port_path}], [@var{address}])\n \ \n\ Open i2c interface.\n \ \n\ @subsubheading Inputs\n \ @var{port_path} - the interface device port/path of type String. If omitted defaults to \n \ '/dev/i2c-0'. @*\n \ @var{address} - the slave device address. If omitted must be set using i2c_addr() call.\n \ \n\ @subsubheading Outputs\n \ @var{i2c} - An instance of @var{octave_i2c} class.\n \ \n\ @subsubheading Properties\n \ The i2c object has the following properties:\n \ @table @asis\n \ @item name\n \ Name of the object\n \ @item remoteaddress\n \ the slave device address\n \ @item port\n \ The interface driver port (readonly)\n \ @end table\n \ @end deftypefn") { #ifndef BUILD_I2C error ("i2c: Your system doesn't support the I2C interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values int oflags = O_RDWR; std::string path ("/dev/i2c-0"); int addr = -1; // Parse the function arguments if (args.length () > 0) { if (args (0).is_string ()) { path = args (0).string_value (); } else { print_usage (); return octave_value (); } } // is_float_type() is or'ed to allow expression like ("", 123), without user // having to use ("", int32(123)), as we still only take "int_value" if (args.length () > 1) { if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { addr = args (1).int_value (); } else { print_usage (); return octave_value (); } } octave_i2c* retval = new octave_i2c (); // Open the interface if (retval->open (path, oflags) < 0) return octave_value (); if (addr > 0) retval->set_addr (addr); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "i2c")) %! fail ("i2c ()", "Invalid call to i2c"); %! else %! fail ("i2c ()", "i2c: Your system doesn't support the I2C interface"); %! endif #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c_addr.cc��������������������������������������������������������0000644�0000000�0000000�00000004517�14743226261�015600� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_I2C #include "i2c_class.h" #endif // PKG_ADD: autoload ("i2c_addr", "i2c.oct"); DEFUN_DLD (i2c_addr, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} i2c_addr (@var{i2c}, @var{address})\n \ @deftypefnx {Loadable Function} {@var{addr} = } i2c_addr (@var{i2c})\n \ \n\ Set new or get existing i2c slave device address.\n \ \n\ @subsubheading Inputs\n \ @var{i2c} - instance of @var{octave_i2c} class.@*\ @var{address} - i2c slave device address of type Integer. \ The address is passed in the 7 or 10 lower bits of the argument.\n \ \n\ @subsubheading Outputs\n \ @var{addr} - If @var{address} parameter is omitted, the i2c_addr() shall return \ current i2c slave device address.\n \ @end deftypefn") { #ifndef BUILD_I2C error ("i2c: Your system doesn't support the I2C interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_i2c::static_type_id ()) { print_usage (); return octave_value (-1); } octave_i2c* i2c = NULL; const octave_base_value& rep = args (0).get_rep(); i2c = &((octave_i2c &)rep); // Setting new slave address if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } i2c->set_addr(args (1).int_value ()); return octave_value (); } // Returning current slave address return octave_value (i2c->get_addr ()); #endif } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c_class.cc�������������������������������������������������������0000644�0000000�0000000�00000016071�14743226261�015771� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_I2C #include <stdio.h> #include <stdlib.h> #include <string> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #if defined (__linux__) #include <linux/i2c-dev.h> #endif // Platform specific header files #if defined (__FreeBSD__) #include <dev/iicbus/iic.h> #endif #include "i2c_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_i2c, "octave_i2c", "octave_i2c"); octave_i2c::octave_i2c (void) : fieldnames(4) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } fd = -1; addr = -1; fieldnames[0] = "status"; fieldnames[1] = "name"; fieldnames[2] = "remoteaddress"; fieldnames[3] = "port"; } octave_i2c::~octave_i2c (void) { octave_i2c::close (); } int octave_i2c::get_fd (void) const { return fd; } void octave_i2c::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_i2c::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_i2c::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " I2C Object " << this->get_name(); newline(os); os << " status: " << this->get_status(); newline(os); if (get_fd() > -1) { if (get_addr() > -1) os << " remoteaddress: " << this->get_addr(); else os << " remoteaddress: None set"; newline(os); } } int octave_i2c::open (const std::string &path, int flags) { port = path; name = "I2C-" + path; fd = ::open (path.c_str (), flags, 0); if (get_fd () < 0) { error ("i2c: Error opening the interface: %s\n", strerror (errno)); return -1; } return get_fd (); } int octave_i2c::set_addr (int addr) { if (get_fd () < 0) { error ("i2c: Interface must be open first..."); return -1; } #if defined (__linux__) if (::ioctl (get_fd (), I2C_SLAVE, addr) < 0) { error ("i2c: Error setting slave address: %s\n", strerror (errno)); return -1; } #endif this->addr = addr; return 1; } int octave_i2c::get_addr (void) const { if (get_fd() < 0) { error ("i2c: Interface must be open first..."); return -1; } return addr; } int octave_i2c::read (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("i2c: Interface must be open first..."); return -1; } int retval = -1; #if defined (__linux__) retval = ::read (get_fd (), buf, len); #endif #if defined (__FreeBSD__) // Populate FreeBSD-specific structure struct iiccmd i2c_slave; i2c_slave.slave = static_cast<uint8_t>(get_addr ()); i2c_slave.count = len; i2c_slave.last = 0; // No additional reads will follow for this transaction i2c_slave.buf = buf; ::ioctl (get_fd (), I2CSTART, &i2c_slave); retval = ::ioctl (get_fd(), I2CREAD, &i2c_slave); ::ioctl (get_fd(), I2CSTOP); #endif if (retval < 0) error ("i2c: Failed to read from the i2c bus: %s\n", strerror (errno)); return retval; } int octave_i2c::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("i2c: Interface must be open first..."); return -1; } int retval = -1; #if defined (__linux__) retval = ::write (get_fd (), buf, len); #endif #if defined (__FreeBSD__) // Populate FreeBSD-specific structure struct iiccmd i2c_slave; i2c_slave.slave = static_cast<uint16_t>(get_addri ()); i2c_slave.count = len; i2c_slave.last = 0; // No additional writes will follow for this transaction i2c_slave.buf = buf; ::ioctl (get_fd (), I2CSTART, &i2c_slave); retval = ::ioctl (get_fd (), I2CWRITE, &i2c_slave); ::ioctl(get_fd (), I2CSTOP); #endif if (retval < 0) error ("i2c: Failed to write to the i2c bus: %s\n", strerror (errno)); return retval; } int octave_i2c::close (void) { int retval = -1; if (get_fd () > 0) { retval = ::close(get_fd ()); fd = -1; } return retval; } std::string octave_i2c::get_port () const { return port; } std::string octave_i2c::get_name () const { return name; } std::string octave_i2c::set_name (const std::string &newname) { name = newname; return name; } std::string octave_i2c::get_status () const { if (get_fd () > -1) return "open"; else return "closed"; } octave_value_list octave_i2c::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_i2c object cannot be indexed with %c", type[0]); break; case '.': { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__i2c_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_i2c::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_i2c object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__i2c_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length() > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_i2c invalid index"); } } return retval; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c_class.h��������������������������������������������������������0000644�0000000�0000000�00000005602�14743226261�015631� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef I2C_CLASS_H #define I2C_CLASS_H #include <octave/oct.h> #include <string> #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_i2c : public OCTAVE_BASE_CLASS { public: octave_i2c (void); ~octave_i2c (void); int open (const std::string& /* path */, int /* open flags */); int close (void); int get_fd (void) const; int set_addr (int /* slave ddress */); int get_addr (void) const; std::string get_name () const; std::string set_name (const std::string &newname); std::string get_status () const; std::string get_port () const; // Simple i2c commands int write (uint8_t* /* buffer */, unsigned int /* buffer size */); int read (uint8_t* /* buffer */, unsigned int /* buffer size */); // Overloaded base functions double i2c_value () const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true;} // 4.4+ bool isobject (void) const { return true;} octave_base_value * unique_clone (void) { OV_COUNT++; return this;} /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); private: int fd; int addr; std::string name; std::string port; string_vector fieldnames; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c_close.cc�������������������������������������������������������0000644�0000000�0000000�00000003147�14743226261�015771� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_I2C #include "i2c_class.h" #endif // PKG_ADD: autoload ("i2c_close", "i2c.oct"); DEFUN_DLD (i2c_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} i2c_close (@var{i2c})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @subsubheading Inputs\n \ @var{i2c} - instance of @var{octave_i2c} class.@*\ \n \ @subsubheading Outputs\n \ None\n \ @end deftypefn") { #ifndef BUILD_I2C error ("i2c: Your system doesn't support the I2C interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_i2c::static_type_id ()) { print_usage (); return octave_value (-1); } octave_i2c* i2c = NULL; const octave_base_value& rep = args (0).get_rep (); i2c = &((octave_i2c &)rep); i2c->close (); return octave_value (); #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c_read.cc��������������������������������������������������������0000644�0000000�0000000�00000005246�14743226261�015601� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/uint8NDArray.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_I2C #include <errno.h> #include "i2c_class.h" #endif // PKG_ADD: autoload ("i2c_read", "i2c.oct"); DEFUN_DLD (i2c_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } i2c_read (@var{i2c}, @var{n})\n \ \n\ Read from i2c slave device.\n \ \n\ @subsubheading Inputs\n \ @var{i2c} - instance of @var{octave_i2c} class.@*\ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ @subsubheading Outputs\n \ The i2c_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_I2C error ("i2c: Your system doesn't support the I2C interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_i2c::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 1; if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } buffer_len = args (1).int_value (); } OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len +1)); if (buffer == NULL) { error ("i2c_read: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } octave_i2c* i2c = NULL; const octave_base_value& rep = args (0).get_rep(); i2c = &((octave_i2c &)rep); int retval; retval = i2c->read (buffer, buffer_len); octave_value_list return_list; uint8NDArray data (dim_vector (1, retval)); for (int i = 0; i < retval; i++) data (i) = buffer[i]; return_list (0) = data; return_list (1) = retval; return return_list; #endif } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/i2c/i2c_write.cc�������������������������������������������������������0000644�0000000�0000000�00000004666�14743226261�016025� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2020 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_I2C #include <errno.h> #include "i2c_class.h" #endif // PKG_ADD: autoload ("i2c_write", "i2c.oct"); DEFUN_DLD (i2c_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } i2c_write (@var{i2c}, @var{data})\n \ \n\ Write data to a i2c slave device.\n \ \n\ @subsubheading Inputs\n \ @var{i2c} - instance of @var{octave_i2c} class.@*\ @var{data} - data, of type uint8, to be written to the slave device.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, i2c_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_I2C error ("i2c: Your system doesn't support the I2C interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_i2c::static_type_id ()) { print_usage (); return octave_value (-1); } octave_i2c* i2c = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); i2c = &((octave_i2c &)rep); if (args (1).is_uint8_type ()) // uint8_t { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("i2c_write: cannot allocate requested memory: %s", strerror (errno)); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data (i)); retval = i2c->write (buf, data.numel()); } else { error ("i2c_write: expected uint8 data"); return octave_value (-1); } return octave_value (retval); #endif } ��������������������������������������������������������������������������instrument-control-0.9.4/src/m4/��������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013456� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/m4/octave-forge.m4�����������������������������������������������������0000644�0000000�0000000�00000006762�14743226261�016314� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 2017 Olaf Till <i7tiol@t-online.de> # Modifications to print what is searching for by JohnD # # 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 <http://www.gnu.org/licenses/>. # arguments of OF_OCTAVE_ALT_SYMS (see also description of # OF_OCTAVE_LIST_ALT_SYMS below): # # $1: symbol version 1 # $2: symbol version 2 # $3: test for symbol version 2 # $4: macro name to access alternative symbols # $5: include directives for symbol version 1 # $6: include directives for symbol version 2 # (a list of lists of args 1--6 is $1 of OF_OCTAVE_LIST_ALT_SYMS) # $7: name of generated include file with alternatives of Octave headers # (arg7 is $2 of OF_OCTAVE_LIST_ALT_SYMS) AC_DEFUN([OF_OCTAVE_ALT_SYMS], [ AC_MSG_CHECKING([$1 or $2]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <octave/oct.h>] $6], [$3])], [AC_DEFINE($4, [[$2]], [macro for alternative Octave symbols]) AC_MSG_RESULT([$2]) echo '$6' >> $7 ac_cv_octsym_[$4]=["$2"]], [AC_DEFINE($4, [[$1]], [macro for alternative Octave symbols]) AC_MSG_RESULT([$1]) echo '$5' >> $7 ac_cv_octsym_[$4]=["$1"]], ) ]) # OF_OCTAVE_LIST_ALT_SYMS is called in the following way: # # OF_OCTAVE_LIST_ALT_SYMS([ # [dnl # [old_octave_symbol], # [new_octave_symbol], # [[compilation test] # [for new_octave_symbol]], # [NAME_OF_GENERATED_MACRO____WILL_EXPAND_TO_OLD_OR_NEW_SYMBOL], # [[include directives] # [except #include <octave/oct.h>] # [necessary to compile with old_octave_symbol]], # [[include directives] # [except #include <octave/oct.h>] # [nessary to compile with new_octave_symbol] # [and to compile the test]] # ], # # ... further such lists as the above # # ], # # [name-of-header-file-for-alternative-octave-iclude-directives.h]) # # # This file should be put into src/m4/, and the line # # AC_CONFIG_MACRO_DIRS([m4]) # # should be put into src/configure.ac. The package should use # autoheader to generate config.h.in (src/bootstrap should contain the # lines 'aclocal', 'autoconf', and 'autoheader -f'). Package code # should include config.h and use the generated macros to access the # alternative symbols of Octave. An example of a call to # OF_OCTAVE_LIST_ALT_SYMS in src/configure.ac is available together # with this file. AC_DEFUN([OF_OCTAVE_LIST_ALT_SYMS], [ echo '/* generated by configure */' > $2 m4_foreach([it], [$1], [m4_apply([OF_OCTAVE_ALT_SYMS], [it, $2])]) AH_BOTTOM([#include "$2"]) ]) # check whether can compile # arguments: # $1: symbol # $2: test for symbol version 2 # $3: macro name define if sucessfull # $4: include directives AC_DEFUN([OF_OCTAVE_CHECK_SYM], [ AC_MSG_CHECKING([$1]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <octave/oct.h>] $4], [$2])], [AC_DEFINE($3, [1], [Have $1]) AC_MSG_RESULT([yes]) ], [AC_MSG_RESULT(no)] ) ]) ��������������instrument-control-0.9.4/src/modbus/����������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014427� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/Makefile.in�����������������������������������������������������0000644�0000000�0000000�00000000426�14743226261�016476� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../modbus.oct OBJ := modbus.o modbus_class.o __modbus_read__.o __modbus_write__.o __modbus_write_read__.o __modbus_pkg_lock__.o __modbus_properties__.o CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ @MODBUSINCLUDES@ LFLAGS = $(LIBS) @MODBUSLIBS@ include ../common.mk ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/__modbus_pkg_lock__.cc������������������������������������������0000644�0000000�0000000�00000003001�14743226261�020666� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__modbus_pkg_lock__", "modbus.oct"); // PKG_ADD: __modbus_pkg_lock__(1); // PKG_DEL: __modbus_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__modbus_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__modbus_pkg_lock__")) interp.munlock("__modbus_pkg_lock__"); } return retval; } #else DEFUN_DLD(__modbus_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/__modbus_properties__.cc����������������������������������������0000644�0000000�0000000�00000022401�14743226261�021276� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_MODBUS #include "modbus_class.h" octave_value_list modbus_flush (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Default arguments int queue_selector = 2; // Input and Output if (args.length () > 0) { if (!(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer or float"); queue_selector = args (0).int_value (); } dev->flush (queue_selector); return octave_value (); } octave_value_list modbus_timeout (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); dev->set_timeout (args (0).double_value ()); return octave_value (); // Should it return by default? } // Returning current timeout return octave_value (dev->get_timeout ()); } octave_value_list modbus_numretries (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new reties if (args.length () > 0) { if ( !(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); dev->set_numretries (args (0).double_value ()); return octave_value (); // Should it return by default? } // Returning current value return octave_value (dev->get_numretries ()); } octave_value_list modbus_userdata (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); dev->set_userdata (args (0)); return octave_value (); // Should it return by default? } // Returning current timeout return octave_value (dev->get_userdata ()); } octave_value_list modbus_byteorder (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be a string"); dev->set_byteorder (args (0).string_value()); return octave_value (); // Should it return by default? } return octave_value (dev->get_byteorder ()); } octave_value_list modbus_wordorder (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be a string"); dev->set_wordorder (args (0).string_value()); return octave_value (); // Should it return by default? } return octave_value (dev->get_wordorder ()); } octave_value_list modbus_name (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be a string"); dev->set_name (args (0).string_value()); return octave_value (); // Should it return by default? } return octave_value (dev->get_name ()); } octave_value_list modbus_port (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); // TODO: depending on serial or tcp of what is returned //return octave_value (dev->get_port ()); if(dev->get_transport() == "tcpip") return octave_value(dev->get_tcpport()); else return octave_value(dev->get_rtuport()); } octave_value_list modbus_baudrate (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); return octave_value(dev->get_baudrate()); } octave_value_list modbus_databits (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); return octave_value(dev->get_databits()); } octave_value_list modbus_stopbits (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); return octave_value(dev->get_stopbits()); } octave_value_list modbus_parity (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); return octave_value(dev->get_parity()); } octave_value_list modbus_deviceaddress (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); return octave_value(dev->get_deviceaddress()); } octave_value_list modbus_type (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); // TODO: depending on serial or tcp of what is returned //return octave_value (dev->get_port ()); return octave_value(dev->get_type()); } octave_value_list modbus_transport (octave_modbus* dev, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); // TODO: depending on serial or tcp of what is returned //return octave_value (dev->get_port ()); return octave_value(dev->get_transport()); } #endif // PKG_ADD: autoload ("__modbus_properties__", "modbus.oct"); DEFUN_DLD (__modbus_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __modbus_properties__ (@var{octave_serialport}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_MODBUS if (args.length () < 2 || args (0).type_id () != octave_modbus::static_type_id () || !args (1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args (0).get_rep (); octave_modbus* dev = &((octave_modbus &)rep); std::string property = args (1).string_value (); std::transform (property.begin (), property.end (), property.begin (), ::tolower); octave_value_list args2 = args.slice (2, args.length ()-2); if (property == "port") return modbus_port (dev, args2, nargout); else if (property == "baudrate") return modbus_baudrate (dev, args2, nargout); else if (property == "transport") return modbus_transport (dev, args2, nargout); else if (property == "type") return modbus_type (dev, args2, nargout); else if (property == "byteorder") return modbus_byteorder (dev, args2, nargout); else if (property == "wordorder") return modbus_wordorder (dev, args2, nargout); else if (property == "databits") return modbus_databits (dev, args2, nargout); else if (property == "stopbits") return modbus_stopbits (dev, args2, nargout); else if (property == "parity") return modbus_parity (dev, args2, nargout); else if (property == "timeout") return modbus_timeout (dev, args2, nargout); else if (property == "numretries") return modbus_numretries (dev, args2, nargout); else if (property == "deviceaddress") return modbus_deviceaddress (dev, args2, nargout); else if (property == "name") return modbus_name (dev, args2, nargout); else if (property == "userdata") return modbus_userdata (dev, args2, nargout); // internals else if (property == "__flush__") return modbus_flush (dev, args2, nargout); else (*current_liboctave_error_handler) ("unknown property"); #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the MODBUS interface"); return octave_value(); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/__modbus_read__.cc����������������������������������������������0000644�0000000�0000000�00000010201�14743226261�020010� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_MODBUS #include <octave/uint8NDArray.h> #include <errno.h> #include "modbus_class.h" #endif // PKG_ADD: autoload ("__modbus_read__", "modbus.oct"); DEFUN_DLD (__modbus_read__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{data} = } __modbus_read__ (@var{modbus}, @var{target}, @var{address}, @var{count}, @var{serverId})\n \ \n\ Private function to read from modbus interface.\n \ \n\ @subsubheading Inputs\n \ @var{modbus} - instance of @var{octave_modbus} class.@* \ @var{target} - target for read type@* \n \ @var{address} - address of type Integer@* \n \ @var{count} - number of bytes to attempt to read of type Integer@* \n \ @var{serverId} - serverId as an integer\n \ \n\ @subsubheading Outputs\n \ The __modbus_read__() function shall return the read bytes @var{data} as uint8 or uint16 array.\n \ @end deftypefn") { #ifndef BUILD_MODBUS error("modbus: Your system doesn't support the MODBUS interface"); return octave_value(); #else if (args.length() != 5 || args(0).type_id() != octave_modbus::static_type_id()) { print_usage(); return octave_value(-1); } std::string target = args(1).string_value(); int address = args(2).int_value(); int count = args(3).int_value(); int serverId = args(4).int_value(); octave_modbus* modbus = NULL; const octave_base_value& rep = args(0).get_rep(); modbus = &((octave_modbus &)rep); if (serverId != modbus->get_slave()) { if (modbus->set_slave(serverId) < 0) { error("modbus_read: %s\n", modbus->get_error().c_str()); return octave_value(); } } octave_value ret_value; // uint8 for coils and inputs // uint16 for inputregs and holdingregs if (target == "coils" || target == "inputs") { OCTAVE_LOCAL_BUFFER (uint8_t, buffer, count); if (buffer == NULL) { error("modbus_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value(); } int bytes_read = 0; if (target == "coils") bytes_read = modbus->read_bits(address, buffer, count); else bytes_read = modbus->read_input_bits(address, buffer, count); if (bytes_read < 0) { error("modbus_read: %s\n", modbus->get_error().c_str()); return octave_value(); } // have data here which should be 0s or 1s uint8NDArray data( dim_vector(1, bytes_read) ); for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; ret_value = data; } else { OCTAVE_LOCAL_BUFFER (uint16_t, buffer, count); if (buffer == NULL) { error("modbus_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value(); } int regs_read = 0; if (target == "inputregs") regs_read = modbus->read_input_registers(address, buffer, count); else regs_read = modbus->read_registers(address, buffer, count); if (regs_read < 0) { error("modbus_read: %s\n", modbus->get_error().c_str()); return octave_value(); } // have data here which should be 0s or 1s uint16NDArray data( dim_vector(1, regs_read) ); for (int i = 0; i < regs_read; i++) data(i) = buffer[i]; ret_value = data; } return ret_value; #endif } #if 0 %!error __modbus_read__(1, 10, 0) #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/__modbus_write__.cc���������������������������������������������0000644�0000000�0000000�00000007447�14743226261�020251� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_MODBUS #include <octave/uint8NDArray.h> #include <errno.h> #include "modbus_class.h" #endif // PKG_ADD: autoload ("__modbus_write__", "modbus.oct"); DEFUN_DLD (__modbus_write__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{count} = } __modbus_write__ (@var{modbus}, @var{target}, @var{address}, @var{data}, @var{serverId})\n \ \n\ Private function to write to modbus interface.\n \ \n\ @subsubheading Inputs\n \ @var{modbus} - instance of @var{octave_modbus} class.@* \ @var{target} - target for read type@* \n \ @var{address} - address of type Integer@* \n \ @var{data} - data to write to modbus@* \n \ @var{serverId} - serverId as an integer\n \ \n\ @subsubheading Outputs\n \ The __modbus_write__() function shall return number of bytes successfully written.\n \ @end deftypefn") { #ifndef BUILD_MODBUS error("modbus: Your system doesn't support the MODBUS interface"); return octave_value(); #else if (args.length() != 5 || args(0).type_id() != octave_modbus::static_type_id()) { print_usage(); return octave_value(-1); } std::string target = args(1).string_value(); int address = args(2).int_value(); //data = args(3).int_value(); int serverId = args(4).int_value(); octave_modbus* modbus = NULL; const octave_base_value& rep = args(0).get_rep(); modbus = &((octave_modbus &)rep); if (serverId != modbus->get_slave()) { if (modbus->set_slave(serverId) < 0) { error("modbus_write: %s\n", modbus->get_error().c_str()); return octave_value(); } } int retval = -1; // uint8 for coils and inputs // uint16 for inputregs and holdingregs if (target == "coils") { NDArray data = args (3).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("__modbus_write__: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = modbus->write_bits(address, buf, data.numel()); if (retval < 0) { error("modbus_write: %s\n", modbus->get_error().c_str()); return octave_value(-1); } } else if (target == "holdingregs") { NDArray data = args (3).array_value (); OCTAVE_LOCAL_BUFFER (uint16_t, buf, (data.numel ())); if (buf == NULL) { error ("__modbus_write__: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint16_t>(data(i)); retval = modbus->write_registers(address, buf, data.numel()); if (retval < 0) { error("modbus_write: %s\n", modbus->get_error().c_str()); return octave_value(-1); } } else { error ("__modbus_write__: invalid target"); return octave_value (-1); } return octave_value(retval); #endif } #if 0 %!error __modbus_write__(1, 10, 0) #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/__modbus_write_read__.cc����������������������������������������0000644�0000000�0000000�00000007030�14743226261�021230� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_MODBUS #include <octave/uint8NDArray.h> #include <errno.h> #include "modbus_class.h" #endif // PKG_ADD: autoload ("__modbus_write_read__", "modbus.oct"); DEFUN_DLD (__modbus_write_read__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data} = } __modbus_write_read__ (@var{modbus}, @var{writeaddress}, @var{writedata}, @var{readaddress}, @var{readCount}, @var{serverId})\n \ \n\ Private function to read from modbus interface.\n \ \n\ @subsubheading Inputs\n \ @var{modbus} - instance of @var{octave_modbus} class.@* \ @var{writeaddress} - address of type Integer@* \n \ @var{writedata} - uint16 data to write.@* \n \ @var{readaddress} - address of type Integer@* \n \ @var{readcount} - number of bytes to attempt to read of type Integer@* \n \ @var{serverId} - serverId as an integer\n \ \n\ @subsubheading Outputs\n \ The __modbus_read__() function shall return the read data in @var{data} as uint16 array.\n \ @end deftypefn") { #ifndef BUILD_MODBUS error("modbus: Your system doesn't support the MODBUS interface"); return octave_value(); #else if (args.length() != 6 || args(0).type_id() != octave_modbus::static_type_id()) { print_usage(); return octave_value(-1); } int writeAddress = args(1).int_value(); // writedata = 2 int readAddress = args(3).int_value(); int readCount = args(4).int_value(); int serverId = args(5).int_value(); octave_modbus* modbus = NULL; const octave_base_value& rep = args(0).get_rep(); modbus = &((octave_modbus &)rep); if (serverId != modbus->get_slave()) { if (modbus->set_slave(serverId) < 0) { error("modbus_write_read: %s\n", modbus->get_error().c_str()); return octave_value(); } } octave_value ret_value; NDArray writeData = args (2).array_value (); OCTAVE_LOCAL_BUFFER (uint16_t, writeBuffer, (writeData.numel ())); OCTAVE_LOCAL_BUFFER (uint16_t, readBuffer, readCount); if (readBuffer == NULL || writeBuffer == NULL) { error("modbus_write_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value(); } for (int i = 0; i < writeData.numel (); i++) writeBuffer[i] = static_cast<uint16_t>(writeData(i)); int regs_read = 0; regs_read = modbus->write_read_registers(writeAddress, writeBuffer, writeData.numel(), readAddress, readBuffer, readCount); if (regs_read < 0) { error("modbus_write_read: %s\n", modbus->get_error().c_str()); return octave_value(); } // have data here which should be 0s or 1s uint16NDArray data( dim_vector(1, regs_read) ); for (int i = 0; i < regs_read; i++) data(i) = readBuffer[i]; ret_value = data; return ret_value; #endif } #if 0 %!error __modbus_write_read__(1, 10, 0) #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/modbus.cc�������������������������������������������������������0000644�0000000�0000000�00000024041�14743226261�016230� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_MODBUS # include "modbus_class.h" #endif // PKG_ADD: autoload ("modbus", "modbus.oct"); DEFUN_DLD (modbus, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{dev} = } modbus ('tcpip', @var{deviceaddress})\n \ @deftypefnx {Loadable Function} {@var{dev} = } modbus ('tcpip', @var{deviceaddress}, @var{remoteport})\n \ @deftypefnx {Loadable Function} {@var{dev} = } modbus ('tcpip', @var{deviceaddress}, @var{name}, @var{value})\n \ @deftypefnx {Loadable Function} {@var{dev} = } modbus ('serialrtu', @var{serialport})\n \ @deftypefnx {Loadable Function} {@var{dev} = } modbus ('serialrtu', @var{serialport}, @var{name}, @var{value})\n \ \n\ Open modbus interface using a specified transport of 'tcpip' or 'serialrtu'.\n \ \n\ @subsubheading Inputs\n \ @var{deviceaddress} - the device ip address of type String.@*\n \ @var{remoteport} - the device remote port number. If not specified, a default of 502 will be used.@*\n \ @var{name}, @var{value} - Optional name value pairs for setting properties of the object.@*\n \ @var{serialport} - the name of the serial port to connect to. It must be specified when transport is 'serialrtu'.@*\n \ \n\ @subsubheading Common Input Name, Value pairs\n \ @table @asis\n \ @item Timeout\n \ timeout value used for waiting for data\n \ @item NumRetries\n \ number of retries after a timeout\n \ @item UserData\n \ Additional data to attach to the object\n \ @end table\n \ \n \ @subsubheading Serial RTU Input Name, Value pairs\n \ @table @asis\n \ @item BaudRate\n \ Baudrate for the serial port\n \ @item DataBits\n \ number of databits for serial port\n \ @item Parity\n \ Parity for serial port ('odd', 'even' or 'none')\n \ @item StopBits\n \ number of stopbits for serial port\n \ @end table\n \ \n\ @subsubheading Outputs\n \ The modbus() shall return instance of @var{octave_modbus} class as the result @var{modbus}.\n \ \n \ @subsubheading Properties\n \ The modbus object has the following public properties:\n \ @table @asis\n \ @item Name\n \ name assigned to the modbus object\n \ @item Type\n \ instrument type 'modbus' (readonly)\n \ @item Port\n \ Remote port number or serial port name (readonly)\n \ @item DeviceAddress\n \ Device address if transport was 'tcpip' (readonly)\n \ @item Status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item Timeout\n \ timeout value used for waiting for data\n \ @item NumRetries\n \ number of retries after a timeout\n \ @item UserData\n \ Additional data to attach to the object\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_MODBUS error("modbus: Your system doesn't support the MODBUS interface"); return octave_value(); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage(); return octave_value(); } // at minumum we need transport and device address or serialport (strings) if (args.length() < 2) { print_usage(); return octave_value(); } // Default values std::string transport(""); std::string deviceaddress("127.0.0.1"); int ipport = 502; double timeout = 10; int numretries = 1; std::string name = ""; octave_value userdata = Matrix (); long baudrate = 9600; int databits = 8; int stopbits = 1; std::string parity = "none"; int property_start = -1; if (args(0).is_string()) { transport = args(0).string_value(); } else { error ("Expected transport of 'serialrtu' or 'tcpip'"); return octave_value(); } if (transport == "tcpip") { if (! args(1).is_string()) { error ("Expected deviceaddress as string"); return octave_value(); } deviceaddress = args (1).string_value (); // optional remote port if (args.length () > 2) { if (args (2).OV_ISINTEGER () || args (2).OV_ISFLOAT ()) { ipport = args (2).int_value (); } else { property_start = 2; } } } else if(transport == "serialrtu") { if (! args(1).is_string()) { error ("Expected device port as string"); return octave_value(); } deviceaddress = args (1).string_value (); property_start = 2; } else { error ("Expected transport of 'serialrtu' or 'tcpip'"); return octave_value(); } // property args if (property_start != -1) { if (((args.length () - property_start) & 1) == 1) { error ("Expected property name/value pairs"); return octave_value (); } // go through the properties for(int i=property_start;i<args.length();i+=2) { std::string propname = args(i).string_value(); octave_value propval = args(i+1); std::transform (propname.begin (), propname.end (), propname.begin (), ::tolower); if (propname == "name") { if (propval.is_string ()) name = propval.string_value (); else { error ("name must be a string"); return octave_value (); } } else if (propname == "timeout") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) timeout = propval.double_value (); else { error ("timeout must be a integer or double"); return octave_value (); } } else if (propname == "numretries") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) { numretries = propval.double_value (); if (numretries < 0) { error ("numretries must be 0 or a positive integer"); return octave_value (); } } else { error ("numretries must be a integer or double"); return octave_value (); } } else if (propname == "baudrate") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) { baudrate = propval.long_value (); if (baudrate <= 0) { error ("baudrate must be a positive integer or double"); return octave_value (); } } else { error ("baudrate must be a positive integer or double"); return octave_value (); } } else if (propname == "databits") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) { databits = propval.int_value (); if (databits < 5 || databits > 8) { error ("databits must be a between 5-8"); return octave_value (); } } else { error ("databits must be a positive integer or double"); return octave_value (); } } else if (propname == "stopbits") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) { stopbits = propval.int_value (); if (stopbits < 1 || stopbits > 2) { error ("stopbits must be 1 or 2"); return octave_value (); } } else { error ("stopbits must be 1 or 2"); return octave_value (); } } else if (propname == "parity") { if (propval.is_string ()) { parity = propval.string_value (); if (parity != "none" && parity != "odd" && parity != "even") { error ("parity must be 'odd', 'even' or 'none'"); return octave_value (); } } else { error ("parity must be a string"); return octave_value (); } } else if (propname == "userdata") { userdata = propval; } else { error ("unknown property '%s'", propname.c_str ()); return octave_value (); } } } // Open the interface and connect octave_modbus* retval = new octave_modbus(); if (transport == "tcpip") { if (retval->open_tcp(deviceaddress, ipport) < 0) { return octave_value(); } } else { if (retval->open_serial(deviceaddress, baudrate, databits, parity, stopbits) < 0) { return octave_value(); } } // set w/r properties we may have retval->set_timeout(timeout); retval->set_numretries(numretries); retval->set_userdata(userdata); if (name.length() > 0) retval->set_name(name); return octave_value(retval); #endif } #if 0 %!error modbus (1) %!error modbus ('noatransport', '127.0.0.1') #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/modbus_class.cc�������������������������������������������������0000644�0000000�0000000�00000034157�14743226261�017426� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_MODBUS #include <iostream> #include <string> #include <algorithm> #include <sstream> #include "modbus_class.h" static struct timeval to_timeval(long ms) { struct timeval tv; if(ms <= 0) { tv.tv_usec = 0; tv.tv_sec = 0; } else { tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms/1000;; } return tv; } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_modbus, "octave_modbus", "octave_modbus"); octave_modbus::octave_modbus (void) : fieldnames(15) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } userData = Matrix (); modbus = 0; ipport = 0; name = ""; timeout = -1; retries = 0; slaveid = -1; wordorder = "big-endian"; byteorder = "big-endian"; // common fieldnames[0] = "Transport"; fieldnames[1] = "Type"; fieldnames[2] = "Name"; fieldnames[3] = "Status"; fieldnames[4] = "UserData"; fieldnames[5] = "Port"; fieldnames[6] = "NumRetries"; fieldnames[7] = "Timeout"; fieldnames[8] = "ByteOrder"; fieldnames[9] = "WordOrder"; // tcp fieldnames[10] = "DeviceAddress"; // serial fieldnames[11] = "BaudRate"; fieldnames[12] = "DataBits"; fieldnames[13] = "Parity"; fieldnames[14] = "StopBits"; } bool octave_modbus::has_property(const std::string &name) const { for (octave_idx_type i=0; i<fieldnames.numel(); i++) { if (fieldnames[i] == name) { // properties available depend on type we are if (name == "DeviceAddress") { if(transport != "tcpip") return false; } if (name == "BaudRate") { if(transport != "serialrtu") return false; } if (name == "DataBits") { if(transport != "serialrtu") return false; } if (name == "StopBits") { if(transport != "serialrtu") return false; } if (name == "Parity") { if(transport != "serialrtu") return false; } // if here must be a valid property return true; } } return false; } string_vector octave_modbus::map_keys (void) const { string_vector actual_fields; // get list of fields that are valid for (octave_idx_type idx = 0; idx < fieldnames.numel(); idx++) { std::string name = fieldnames[idx]; if(has_property(name)) actual_fields.append(name); } return actual_fields; } octave_value_list octave_modbus::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_modbus object cannot be indexed with %c", type[0]); break; case '.': { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } else { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__modbus_properties__"), ovl, 1); } } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_modbus::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_modbus object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { std::string property = (idx.front ()) (0).string_value (); if (! has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } else { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__modbus_properties__"), ovl, 1); OV_COUNT++; retval = octave_value (this); } } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_modbus invalid index"); } } return retval; } int octave_modbus::open_tcp (const std::string &address, int port) { modbus_t *bus = modbus_new_tcp (address.c_str(), port); if(!bus) { error( "could not create new modbus context" ); return -1; } if (modbus_connect(bus) == -1) { error( "could not connect - '%s'", modbus_strerror(errno)); modbus_free(bus); return -1; } this->modbus = bus; this->transport = "tcpip"; this->name = "MODBUS-" + address; this->ipport = port; this->ipaddress = address; return 1; } std::string octave_modbus::get_error() const { std::string ret; const char * err = modbus_strerror(errno); if (err) ret = err; return ret; } int octave_modbus::open_serial (const std::string &device, unsigned long baud, int dbits, const std::string &parity, int sbits) { char parityval = 'N'; if(parity == "odd") parityval = 'O'; if(parity == "event") parityval = 'E'; //modbus_t *bus = modbus_new_rtu (device.c_str(), 115200, 'N', 8, 1); modbus_t *bus = modbus_new_rtu (device.c_str(), baud, parityval, dbits, sbits); if(!bus) { error( "could not create new modbus context" ); return -1; } // do we need this ? if (modbus_connect(bus) == -1) { error( "could not connect - '%s'", modbus_strerror(errno)); modbus_free(bus); return -1; } this->modbus = bus; this->transport = "serialrtu"; this->name = "MODBUS-" + device; this->baud = baud; this->parity = parity; this->databits = dbits; this->stopbits = sbits; this->sport = device; return 1; } octave_modbus::~octave_modbus (void) { close(); } void octave_modbus::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_modbus::print (std::ostream& os, bool pr_as_read_syntax) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_modbus::print_raw (std::ostream& os, bool pr_as_read_syntax) const { std::string ttype = "Serial RTU"; if(this->transport == "tcpip") ttype = "TCPIP"; os << " MODBUS " << ttype << " Object " << get_name (); newline(os); if (this->transport == "tcpip") { os << " DeviceAddress: " << get_deviceaddress (); newline(os); //os << " Port: " << get_port (); os << " Port: " << this->get_tcpport(); newline(os); } else if(this->transport == "serialrtu") { os << " Port: " << this->get_rtuport(); newline(os); os << " BaudRate: " << this->get_baudrate(); newline(os); os << " DataBits: " << this->get_databits(); newline(os); os << " Parity: " << this->get_parity(); newline(os); os << " StopBits: " << this->get_stopbits(); newline(os); } os << " Status: " << get_status (); newline(os); os << " NumRetries: " << get_numretries (); newline(os); os << " Timeout: " << get_timeout (); newline(os); os << " ByteOrder: " << get_byteorder (); newline(os); os << " WordOrder: " << get_wordorder (); newline(os); } int octave_modbus::set_slave (int id) { if (! is_open ()) { error ("modbus_read: Interface must be opened first..."); return 0; } int err = modbus_set_slave(this->modbus, id); if(err >= 0) this->slaveid = id; return err; } int octave_modbus::read_bits (int address, uint8_t *buf, unsigned int len) { if (! is_open ()) { error ("modbus_read: Interface must be opened first..."); return 0; } // TODO: handle retries as needed depending errno etc ssize_t bytes_read = -1; bytes_read = modbus_read_bits(this->modbus, address, len, buf); return bytes_read; } int octave_modbus::read_input_bits (int address, uint8_t *buf, unsigned int len) { if (! is_open ()) { error ("modbus_read: Interface must be opened first..."); return 0; } ssize_t bytes_read = -1; bytes_read = modbus_read_input_bits(this->modbus, address, len, buf); return bytes_read; } int octave_modbus::read_registers (int address, uint16_t *buf, unsigned int len) { if (! is_open ()) { error ("modbus_read: Interface must be opened first..."); return 0; } ssize_t bytes_read = -1; bytes_read = modbus_read_registers(this->modbus, address, len, buf); return bytes_read; } int octave_modbus::read_input_registers (int address, uint16_t *buf, unsigned int len) { if (! is_open ()) { error ("modbus_read: Interface must be opened first..."); return 0; } ssize_t bytes_read = -1; bytes_read = modbus_read_input_registers(this->modbus, address, len, buf); return bytes_read; } int octave_modbus::write_bits (int address, const uint8_t *buf, unsigned int len) { if (! is_open ()) { error ("modbus_write: Interface must be opened first..."); return 0; } ssize_t regs_wrote = -1; regs_wrote = modbus_write_bits(this->modbus, address, len, buf); return regs_wrote; } int octave_modbus::write_registers (int address, const uint16_t *buf, unsigned int len) { if (! is_open ()) { error ("modbus_write: Interface must be opened first..."); return 0; } ssize_t regs_wrote = -1; regs_wrote = modbus_write_registers(this->modbus, address, len, buf); return regs_wrote; } int octave_modbus::write_read_registers(int wraddress, const uint16_t *wrbuf, unsigned int wrlen, int rdaddress, uint16_t *rdbuf, unsigned int rdlen) { if (! is_open ()) { error ("modbus_write_read: Interface must be opened first..."); return 0; } ssize_t regs_read = -1; regs_read = modbus_write_and_read_registers(this->modbus, wraddress, wrlen, wrbuf, rdaddress, rdlen, rdbuf); return regs_read; } int octave_modbus::set_timeout (double newtimeout) { if (! is_open ()) { error ("modbus: Interface must be opened first..."); return -1; } if (newtimeout < -1 ) { error ("modbus_timeout: timeout value must be -1 or positive"); return -1; } struct timeval tv = to_timeval((long)(newtimeout*1000L)); #ifdef HAVE_MODBUS_SET_RESPONSE_TIMEOUT2 modbus_set_response_timeout(this->modbus, tv.tv_sec, tv.tv_usec); #else modbus_set_response_timeout(this->modbus, &tv); #endif timeout = newtimeout; return 1; } int octave_modbus::set_numretries (int newretries) { if (! is_open ()) { error ("modbus: Interface must be opened first..."); return -1; } if (newretries < 0 ) { error ("modbus_numretries: must be 0 or positive"); return -1; } // we use the num retries to handle errors retries = newretries; return 1; } std::string octave_modbus::set_name (const std::string &n) { if (n.length() == 0 ) { error ("modbus_name: value must be non empty"); } else { name = n; } return name; } bool octave_modbus::is_open (void) const { return modbus != 0; } std::string octave_modbus::get_status (void) const { if (! is_open ()) { return "closed"; } else { return "open"; } } int octave_modbus::close (void) { int retval = -1; if (is_open ()) { modbus_close(modbus); modbus_free(modbus); modbus = 0; retval = 0; } return retval; } int octave_modbus::flush (int mode) { int retval = -1; if (is_open()) { if (mode == 0 || mode == 2) { // we are sending data as we get it, so no outout // buffers to flush } if (mode == 1 || mode == 2) { retval = modbus_flush(this->modbus); } } return retval; } int octave_modbus::set_byteorder(const std::string& neworder) { std::string order = neworder; std::transform (order.begin (), order.end (), order.begin (), ::tolower); if (order == "big" || order == "big-endian") byteorder = "big-endian"; else if (order == "little" || order == "little-endian") byteorder = "little-endian"; else error ("octave_modbus invalid byteorder"); return 1; } int octave_modbus::set_wordorder(const std::string& neworder) { std::string order = neworder; std::transform (order.begin (), order.end (), order.begin (), ::tolower); if (order == "big" || order == "big-endian") wordorder = "big-endian"; else if (order == "little" || order == "little-endian") wordorder = "little-endian"; else error ("octave_modbus invalid wordorder"); return 1; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/modbus/modbus_class.h��������������������������������������������������0000644�0000000�0000000�00000011353�14743226261�017261� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef MODBUS_CLASS_H #define MODBUS_CLASS_H #include <octave/oct.h> //#include <octave/ov-int32.h> #include <modbus/modbus.h> #include <string> #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_modbus : public OCTAVE_BASE_CLASS { public: octave_modbus (void); ~octave_modbus (void); int open_tcp (const std::string &address, int port); int open_serial (const std::string &comport, unsigned long baud=9600, int dbits=8, const std::string &parity="none", int sbits=1); int close (void); std::string get_error() const; int set_slave (int id); int get_slave () const { return slaveid; } int read_bits (int address, uint8_t *buf, unsigned int len); int read_input_bits (int address, uint8_t *buf, unsigned int len); int read_registers (int address, uint16_t *buf, unsigned int len); int read_input_registers (int address, uint16_t *buf, unsigned int len); int write_bits (int address, const uint8_t *buf, unsigned int len); int write_registers (int address, const uint16_t *buf, unsigned int len); int write_read_registers (int wraddress, const uint16_t *wrbuf, unsigned int wrlen, int rdaddress, uint16_t *rdbuf, unsigned int rdlen); void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; int flush (int mode); // Properties bool is_constant (void) const { return true; } bool is_defined (void) const { return true; } // < 4.4 bool is_object (void) const { return true; } // 4.4 + bool isobject (void) const { return true; } octave_base_value * unique_clone (void) { OV_COUNT++; return this;} // required to use subsasn string_vector map_keys (void) const; dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); std::string get_name (void) const { return name; } std::string set_name (const std::string &); bool is_open(void) const; std::string get_type (void) const { return "modbus"; } std::string get_status (void) const; int set_timeout (double); double get_timeout (void) const { return timeout; } double get_numretries (void) const { return retries; } int set_numretries (int retries); std::string get_deviceaddress (void) const { return ipaddress; } int get_tcpport (void) const { return ipport; } int set_byteorder(const std::string& /* order */); std::string get_byteorder() const { return byteorder; } int set_wordorder(const std::string& /* order */); std::string get_wordorder() const { return wordorder; } std::string get_transport (void) const { return transport; } std::string get_parity (void) const { return parity; } std::string get_rtuport (void) const { return sport; } unsigned long get_baudrate (void) const { return baud; } int get_databits (void) const { return databits; } int get_stopbits (void) const { return stopbits; } octave_value get_userdata () const { return userData; } void set_userdata (const octave_value &newv) { userData = newv; } private: bool has_property(const std::string &name) const; modbus_t *modbus; // common properties std::string name; std::string transport; double timeout; int retries; std::string byteorder; std::string wordorder; octave_value userData; int slaveid; // tcpip std::string ipaddress; int ipport; // serial unsigned long baud; std::string parity; int databits; int stopbits; std::string sport; string_vector fieldnames; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/��������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014732� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/Makefile.in���������������������������������������������������0000644�0000000�0000000�00000000330�14743226261�016773� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../parallel.oct OBJ := parallel.o parallel_class.o pp_close.o pp_datadir.o pp_data.o pp_stat.o pp_ctrl.o __parallel_pkg_lock__.o LFLAGS = $(LIBS) CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/__parallel_pkg_lock__.cc��������������������������������������0000644�0000000�0000000�00000003021�14743226261�021476� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__parallel_pkg_lock__", "parallel.oct"); // PKG_ADD: __parallel_pkg_lock__(1); // PKG_DEL: __parallel_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__parallel_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__parallel_pkg_lock__")) interp.munlock("__parallel_pkg_lock__"); } return retval; } #else DEFUN_DLD(__parallel_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/parallel.cc���������������������������������������������������0000644�0000000�0000000�00000006554�14743226261�017047� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017,2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include <octave/ov-int32.h> #include <iostream> #include <string> #include <algorithm> #ifndef __WIN32__ #include <errno.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #endif using std::string; #include "parallel_class.h" #endif // PKG_ADD: autoload ("parallel", "parallel.oct"); DEFUN_DLD (parallel, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{parallel} = } parallel ([@var{path}], [@var{direction}])\n \ \n\ Open Parallel interface.\n \ \n\ @subsubheading Inputs\n \ @var{path} - the interface path of type String. If omitted defaults to '/dev/parport0'.@*\ @var{direction} - the direction of interface drivers of type Integer, see: PP_DATADIR for more info. \ If omitted defaults to 1 (Input).\n \ \n\ @subsubheading Outputs\n \ The parallel() shall return instance of @var{octave_parallel} class as the result @var{parallel}.\n \ @end deftypefn") { #ifndef BUILD_PARALLEL error ("parallel: Your system doesn't support the parallel interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values int oflags = O_RDWR; int dir = 1; // Input string path ("/dev/parport0"); // Parse the function arguments if (args.length () > 0) { if (args (0).is_string ()) { path = args (0).string_value (); } else { print_usage (); return octave_value (); } } // is_float_type () is or'ed to allow expression like ("", 123), without user // having to use ("", int32(123)), as we still only take "int_value" if (args.length () > 1) { if (args (1).OV_ISINTEGER() || args (1).OV_ISFLOAT()) { dir = args (1).int_value (); } else { print_usage (); return octave_value (); } } octave_parallel* retval = new octave_parallel (); // Open the interface if (retval->open (path, oflags) < 0) return octave_value (); // Set direction retval->set_datadir(dir); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("parallel ()", "Invalid call to parallel"); %! else %! fail ("parallel ()", "parallel: Your system doesn't support the parallel interface"); %! endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/parallel_class.cc���������������������������������������������0000644�0000000�0000000�00000014221�14743226261�020222� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-int32.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include <iostream> #include <string> #include <algorithm> #include <errno.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #if defined (__linux__) #include <linux/parport.h> #include <linux/ppdev.h> #endif // Platform specific header files #if defined (__FreeBSD__) #include <dev/ppbus/ppi.h> #include <dev/ppbus/ppbconf.h> // And constants #define PPWCONTROL PPISCTRL #define PPRCONTROL PPIGCTRL #define PPWSTATUS PPISSTATUS #define PPRSTATUS PPIGSTATUS #define PPWDATA PPISDATA #define PPRDATA PPIGDATA #endif using std::string; #include "parallel_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_parallel, "octave_parallel", "octave_parallel"); octave_parallel::octave_parallel (void) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } this->fd = -1; } octave_parallel::~octave_parallel (void) { this->close (); } int octave_parallel::open (string path, int flags) { this->fd = ::open (path.c_str (), flags, 0); if (this->get_fd () < 0) { error("parallel: Error opening the interface: %s\n", strerror (errno)); return -1; } // Claim control of parallel port // Not used with FreeBSD #if !defined(__FreeBSD__) if (ioctl (this->get_fd (), PPCLAIM) < 0) { error("parallel: Error when claiming the interface: %s\n", strerror(errno)); ::close (this->get_fd ()); this->fd = -1; return -1; } #endif return this->get_fd (); } int octave_parallel::get_fd (void) { return this->fd; } void octave_parallel::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_parallel::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_parallel::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << this->fd; } int octave_parallel::set_datadir (int dir) { if (this->get_fd () < 0) { error ("parallel: Open the interface first..."); return -1; } if (dir < 0 || 1 < dir) { error ("parallel: Unsupported data direction..."); return -1; } // The ioctl parameter is a pointer to an int. // If the int is zero, the drivers are turned on (forward/output direction); // if non-zero, the drivers are turned off (reverse/input direction). // Not used with FreeBSD #if !defined(__FreeBSD__) if (ioctl (this->get_fd (), PPDATADIR, &dir) < 0) { error ("pp_datadir: error setting data direction: %s\n", strerror (errno)); return false; } #endif this->dir = dir; return 1; } int octave_parallel::get_datadir (void) { if (this->get_fd () < 0) { error ("parallel: Open the interface first..."); return false; } return this->dir; } int octave_parallel::get_stat (void) { if (this->get_fd () < 0) { error ("parallel: Open the interface first..."); return -1; } uint8_t status; if (ioctl (this->get_fd (), PPRSTATUS, &status) < 0) { error ("parallel: Error while reading from Status register: %s\n", strerror (errno)); return -1; } return status; } int octave_parallel::set_data (uint8_t data) { if (this->get_fd () < 0) { error("parallel: Open the interface first..."); return -1; } /* if (this->get_dir () == 1) { error ("parallel: Trying to output data while in Input mode, this can result in hardware damage! \ Use override if you know what you are doing..."); return false; } */ if (ioctl (this->get_fd (), PPWDATA, &data) < 0) { error ("parallel: Error while writing to Data register: %s\n", strerror (errno)); return -1; } return 1; } int octave_parallel::get_data (void) { if (this->get_fd () < 0) { error ("parallel: Open the interface first..."); return -1; } uint8_t data; if (ioctl(this->get_fd (), PPRDATA, &data) < 0) { error ("parallel: Error while reading from Data register: %s\n", strerror (errno)); return -1; } return data; } int octave_parallel::set_ctrl (uint8_t ctrl) { if (this->get_fd () < 0) { error ("parallel: Open the interface first..."); return -1; } if (ioctl(this->get_fd (), PPWCONTROL, &ctrl) < 0) { error ("parallel: Error while writing to Control register: %s\n", strerror (errno)); return -1; } return 1; } int octave_parallel::get_ctrl (void) { if (this->get_fd () < 0) { error ("parallel: Open the interface first..."); return -1; } uint8_t ctrl; if (ioctl(this->get_fd (), PPRCONTROL, &ctrl) < 0) { error ("parallel: Error while reading from Control register: %s\n", strerror (errno)); return -1; } return ctrl; } int octave_parallel::close (void) { if (this->get_fd () > 0) { // Release parallel port // Not used with FreeBSD #if !defined(__FreeBSD__) if (ioctl (this->get_fd (), PPRELEASE) < 0) error ("parallel: error releasing parallel port: %s\n", strerror (errno)); #endif int retval = ::close (this->get_fd ()); this->fd = -1; return retval; } return -1; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/parallel_class.h����������������������������������������������0000644�0000000�0000000�00000004003�14743226261�020061� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef PARALLEL_CLASS_H #define PARALLEL_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> using std::string; #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_parallel : public OCTAVE_BASE_CLASS { public: octave_parallel (void); ~octave_parallel (void); int open (string /* path */, int /* open flags */); int close (void); int get_fd (); int get_datadir (void); int set_datadir (int /* direction */); int get_data (void); int set_data (uint8_t /* value */); int get_stat (void); //int set_stat (uint8_t); int get_ctrl (void); int set_ctrl (uint8_t /* value */); // Overloaded base functions double parallel_value(void) const { return (double)this->fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)this->fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool print_as_scalar (void) const { return true;} private: int fd; // 1 - Input // 0 - Output int dir; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/pp_close.cc���������������������������������������������������0000644�0000000�0000000�00000004101�14743226261�017041� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include "parallel_class.h" #endif // PKG_ADD: autoload ("pp_close", "parallel.oct"); DEFUN_DLD (pp_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} pp_close (@var{parallel})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @subsubheading Inputs\n \ @var{parallel} - instance of @var{octave_serial} class.@*\ @subsubheading Outputs\n \ None\n \ @end deftypefn") { #ifndef BUILD_PARALLEL error ("parallel: Your system doesn't support the parallel interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id() != octave_parallel::static_type_id ()) { print_usage (); return octave_value (-1); } octave_parallel* parallel = NULL; const octave_base_value& rep = args (0).get_rep (); parallel = &((octave_parallel &)rep); parallel->close (); return octave_value (); #endif } #if 0 %!xtest %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! a = parallel (); %! pp_close (a); %! endif %!test %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("pp_close(1);", "Invalid call to pp_close"); %! endif %!test %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("pp_close();", "Invalid call to pp_close"); %! endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/pp_ctrl.cc����������������������������������������������������0000644�0000000�0000000�00000005166�14743226261�016714� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017,2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include "parallel_class.h" #endif // PKG_ADD: autoload ("pp_ctrl", "parallel.oct"); DEFUN_DLD (pp_ctrl, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} pp_ctrl (@var{parallel}, @var{ctrl})\n \ @deftypefnx {Loadable Function} {@var{c} = } pp_ctrl (@var{parallel})\n \ \n\ Sets or Read the Control lines.\ \n\ @subsubheading Inputs\n \ @var{parallel} - instance of @var{octave_parallel} class.@*\ @var{ctrl} - control parameter to be set of type Byte.\n \ \n\ @subsubheading Outputs\n \ If @var{ctrl} parameter is omitted, the pp_ctrl() shall return current Control lines state as the result @var{c}.\n \ @end deftypefn") { #ifndef BUILD_PARALLEL error ("parallel: Your system doesn't support the parallel interface"); return octave_value(); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_parallel::static_type_id ()) { print_usage (); return octave_value (-1); } octave_parallel* parallel = NULL; const octave_base_value& rep = args (0).get_rep (); parallel = &((octave_parallel &)rep); // Set new Control register value if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args(1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } parallel->set_ctrl (args (1).int_value ()); return octave_value (); } // Return current Control register value on port return octave_value (parallel->get_ctrl ()); #endif } #if 0 %!xtest %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! a = parallel (); %! v = pp_ctrl(a); %! pp_close (a); %! endif %!test %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("pp_ctrl(1);", "Invalid call to pp_ctrl"); %! endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/pp_data.cc����������������������������������������������������0000644�0000000�0000000�00000005153�14743226261�016655� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017,2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include "parallel_class.h" #endif // PKG_ADD: autoload ("pp_data", "parallel.oct"); DEFUN_DLD (pp_data, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} pp_data (@var{parallel}, @var{data})\n \ @deftypefnx {Loadable Function} {@var{d} = } pp_data (@var{parallel})\n \ \n\ Sets or Read the Data lines.\ \n\ @subsubheading Inputs\n \ @var{parallel} - instance of @var{octave_parallel} class.@*\ @var{data} - data parameter to be set of type Byte.\n \ \n\ @subsubheading Outputs\n \ If @var{data} parameter is omitted, the pp_data() shall return current Data lines state as the result @var{d}.\n \ @end deftypefn") { #ifndef BUILD_PARALLEL error ("parallel: Your system doesn't support the parallel interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_parallel::static_type_id ()) { print_usage (); return octave_value (-1); } octave_parallel* parallel = NULL; const octave_base_value& rep = args (0).get_rep (); parallel = &((octave_parallel &)rep); // Set new Data register value if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args(1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } parallel->set_data (args (1).int_value ()); return octave_value (); } // Return current Data register value on port return octave_value (parallel->get_data ()); #endif } #if 0 %!xtest %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! a = parallel (); %! d = pp_data (a); %! pp_close (a); %! endif %!test %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("pp_data(1);", "Invalid call to pp_data"); %! endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/pp_datadir.cc�������������������������������������������������0000644�0000000�0000000�00000006121�14743226261�017350� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017,2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include "parallel_class.h" #endif // PKG_ADD: autoload ("pp_datadir", "parallel.oct"); DEFUN_DLD (pp_datadir, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} pp_datadir (@var{parallel}, @var{direction})\n \ @deftypefnx {Loadable Function} {@var{dir} = } pp_datadir (@var{parallel})\n \ \n\ Controls the Data line drivers.\n \ \n \ Normally the computer's parallel port will drive the data lines, \ but for byte-wide transfers from the peripheral to the host it is useful to turn off those drivers \ and let the peripheral drive the signals. (If the drivers on the computer's parallel port are left \ on when this happens, the port might be damaged.)\n \ \n\ @subsubheading Inputs\n \ @var{parallel} - instance of @var{octave_parallel} class.@*\ @var{direction} - direction parameter of type Integer. Supported values: 0 - the drivers are turned on \ (Output/Forward direction); 1 - the drivers are turned off (Input/Reverse direction).\n \ \n\ @subsubheading Outputs\n \ If @var{direction} parameter is omitted, the pp_datadir() shall return current Data direction as the result @var{dir}.\n \ @end deftypefn") { #ifndef BUILD_PARALLEL error ("parallel: Your system doesn't support the parallel interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_parallel::static_type_id ()) { print_usage (); return octave_value (-1); } octave_parallel* parallel = NULL; const octave_base_value& rep = args (0).get_rep (); parallel = &((octave_parallel &)rep); // Set new direction if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } parallel->set_datadir (args (1).int_value ()); return octave_value (); } // Return current direction return octave_value (parallel->get_datadir ()); #endif } #if 0 %!xtest %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! a = parallel (); %! d = pp_datadir (a); %! pp_close (a); %! endif %!test %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("pp_datadir(1);", "Invalid call to pp_datadir"); %! endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/parallel/pp_stat.cc����������������������������������������������������0000644�0000000�0000000�00000004176�14743226261�016723� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_PARALLEL #include "parallel_class.h" #endif // PKG_ADD: autoload ("pp_stat", "parallel.oct"); DEFUN_DLD (pp_stat, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{stat} = } pp_stat (@var{parallel})\n \ \n\ Reads the Status lines.\n \ \n\ @subsubheading Inputs\n \ @var{parallel} - instance of @var{octave_parallel} class.@*\ \n\ @subsubheading Outputs\n \ The pp_stat() shall return current Status lines state as the result @var{stat}.\n \ @end deftypefn") { #ifndef BUILD_PARALLEL error ("parallel: Your system doesn't support the parallel interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_parallel::static_type_id ()) { print_usage (); return octave_value (-1); } octave_parallel* parallel = NULL; const octave_base_value& rep = args (0).get_rep (); parallel = &((octave_parallel &)rep); // Return current Status register value on port return octave_value (parallel->get_stat ()); #endif } #if 0 %!xtest %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! a = parallel (); %! d = pp_stat (a); %! pp_close (a); %! endif %!test %! if any (strcmp(instrhwinfo().SupportedInterfaces, "parallel")) %! fail ("pp_stat(1);", "Invalid call to pp_stat"); %! endif #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/resolvehost/�����������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015513� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/resolvehost/Makefile.in������������������������������������������������0000644�0000000�0000000�00000000215�14743226261�017556� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../resolvehost.oct OBJ := resolvehost.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/resolvehost/resolvehost.cc���������������������������������������������0000644�0000000�0000000�00000014051�14743226261�020400� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP #include <iostream> #include <string> #ifndef __WIN32__ # include <unistd.h> # include <errno.h> # include <netinet/in.h> # include <sys/socket.h> # include <netdb.h> # include <arpa/inet.h> #else // tell old versions of mingw32 to be win2k # ifdef __MINGW32__ # if _MINGW32_MAJOR_VERSION < 5 # undef _WIN32_WINNT # define _WIN32_WINNT 0x0501 # endif # endif # include <winsock2.h> # include <ws2tcpip.h> #endif #ifndef __WIN32__ # define SOCKETERR errno # define STRSOCKETERR strerror(errno) #else # define SOCKETERR WSAGetLastError() # define STRSOCKETERR "" #endif static bool type_loaded = false; #endif DEFUN_DLD (resolvehost, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{name} = } resolvehost (@var{host})\n \ @deftypefnx {Loadable Function} {[@var{name}, @var{address}] = } resolvehost (@var{host})\n \ @deftypefnx {Loadable Function} {@var{out} = } resolvehost (@var{host}, @var{returntype})\n \ \n\ Resolve a network host name or address to network name and address\n \ \n\ @subsubheading Inputs\n \ @var{host} - Host name or IP address string to resolve.@* \ @var{name} - Resolved IP host name.@* \ @var{returntype} - 'name' to get host name, 'address' to get IP address.\n \ \n \ @subsubheading Outputs\n \ @var{name} - Resolved IP host name.@* \ @var{address} - Resolved IP host address.@* \ @var{out} - host name if @var{returntype} is 'name', ipaddress if @var{returntype} is 'address'@* \ \n \ @subsubheading Example\n \ @example\n \ %% get resolved ip name and address of www.gnu.org\n \ [name, address] = resolvehost ('www.gnu.org');\n \ \n \ %% get ip address of www.gnu.org\n \ ipaddress = resolvehost ('www.gnu.org', 'address');\n \ \n \ @end example\n \ \n \ @seealso{tcp, udp}\n \ \n\ @end deftypefn") { #ifndef BUILD_RESOLVEHOST error("resolvehost: Your system doesn't support the resolvehost interface"); return octave_value(); #else octave_value_list return_value; if (!type_loaded) { #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD ( 2, 2 ); err = WSAStartup (wVersionRequested, &wsaData); if (err != 0) { error ("resolvehost: could not initialize winsock library"); return return_value; } #endif type_loaded = true; } // Nothing to do if (args.length () != 1 && args.length () != 2) { print_usage (); return return_value; } // expects host string if (! args (0).is_string ()) { print_usage (); return return_value; } std::string host = args (0).string_value (); // optional return type std::string return_type = "both"; if (args.length () == 2) { if(! args (1).is_string ()) { print_usage (); return return_value; } return_type = args (1).string_value (); std::transform (return_type.begin (), return_type.end (), return_type.begin (), ::tolower); if (return_type != "name" && return_type != "address") { print_usage (); return return_value; } } // create addr from ip/looked up ip of value sockaddr_in in; memset (&in, 0, sizeof (in)); in.sin_family = AF_INET; in.sin_addr.s_addr = inet_addr (host.c_str ()); if (in.sin_addr.s_addr == INADDR_NONE) { struct hostent * hostinfo = gethostbyname (host.c_str ()); if (hostinfo) memcpy (&in.sin_addr, hostinfo->h_addr_list[0], hostinfo->h_length); } if (in.sin_addr.s_addr == INADDR_NONE) { error ("resolvehost: could not lookup IP address"); return return_value; } // we want to look up the name (ie: not only address) if (return_type != "address") { char name[1025]; if( getnameinfo ((struct sockaddr *)&in, sizeof (in), name, sizeof(name), NULL, 0, 0) != 0) { error ("resolvehost: error looking up host name : %d - %s\n", SOCKETERR, STRSOCKETERR); return return_value; } return_value (0) = name; } // we want the ip address (both or address) if (return_type != "name") { std::stringstream n; u_long addr = ntohl (in.sin_addr.s_addr); int b[4]; b[0] = (addr>>24)&0xff; b[1] = (addr>>16)&0xff; b[2] = (addr>>8)&0xff; b[3] = (addr>>0)&0xff; n << b[0] << "." << b[1] << "." << b[2] << "." << b[3]; if (return_type == "both") return_value (1) = n.str (); else return_value (0) = n.str (); } return return_value; #endif } #if 0 %!xtest %! name = resolvehost ("wiki.octave.org"); %! assert(! isempty (name)); %!xtest %! [name, addr] = resolvehost ("wiki.octave.org"); %! assert (! isempty (name)); %! assert (! isempty (addr)); %! assert (name, resolvehost ("wiki.octave.org", "name")); %! assert (addr, resolvehost ("wiki.octave.org", "address")); %!error <Invalid call to resolvehost> resolvehost (); %!error <Invalid call to resolvehost> resolvehost (1); %!error <Invalid call to resolvehost> resolvehost ("wiki.octave.org", 1); %!error <Invalid call to resolvehost> resolvehost ("wiki.octave.org", "addr"); %!error <Invalid call to resolvehost> resolvehost ("wiki.octave.org", "name", 1); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/����������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014415� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/Makefile.in�����������������������������������������������������0000644�0000000�0000000�00000000455�14743226261�016466� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../serial.oct OBJ := serial.o srl_write.o srl_read.o __srl_properties__.o __serial_pkg_lock__.o serial_class.o LFLAGS = $(LIBS) CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ ifeq ("@BUILD_FOR_WINDOWS@","1") OBJ += serial_class_win32.o else OBJ += serial_class_lin.o endif include ../common.mk �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/__serial_pkg_lock__.cc������������������������������������������0000644�0000000�0000000�00000003001�14743226261�020642� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__serial_pkg_lock__", "serial.oct"); // PKG_ADD: __serial_pkg_lock__(1); // PKG_DEL: __serial_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__serial_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__serial_pkg_lock__")) interp.munlock("__serial_pkg_lock__"); } return retval; } #else DEFUN_DLD(__serial_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/__srl_properties__.cc�������������������������������������������0000644�0000000�0000000�00000027013�14743226261�020577� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include "serial_class.h" #endif #ifdef BUILD_SERIAL octave_value_list srl_close (octave_serial* serial, const octave_value_list& args, int nargout) { serial->close (); return octave_value (); } octave_value_list srl_flush (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Default arguments int queue_selector = 2; // Input and Output if (args.length () > 0) { if (!(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer or float"); queue_selector = args (0).int_value (); } serial->flush (queue_selector); return octave_value (); } octave_value_list srl_break (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Default arguments int ms = 2; // Input and Output if (args.length () > 0) { if (!(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer"); ms = args (0).int_value (); } serial->sendbreak (ms); return octave_value (); } octave_value_list srl_timeout (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serial->set_timeout (args (0).int_value ()); return octave_value (); // Should it return by default? } // Returning current timeout return octave_value (serial->get_timeout ()); } octave_value_list srl_bytesavailable (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); // Returning bytes available return octave_value (serial->get_bytesavailable ()); } octave_value_list srl_status (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); // Returning bytes available return octave_value (serial->get_status ()); } octave_value_list srl_type (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); // Returning bytes available return octave_value (serial->get_type ()); } octave_value_list srl_port (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); // Returning bytes available return octave_value (serial->get_port ()); } octave_value_list srl_name (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new name if (args.length () > 0) { if (! (args (0).is_string ())) (*current_liboctave_error_handler) ("argument must be string"); serial->set_name (args (0).string_value ()); return octave_value (); } // Returning current baud rate return octave_value (serial->get_name ()); } octave_value_list srl_baudrate (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new baudrate if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer or float"); serial->set_baudrate (args (0).int_value ()); return octave_value (); } // Returning current baud rate return octave_value (serial->get_baudrate ()); } octave_value_list srl_bytesize (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new byte size if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serial->set_bytesize (args (0).int_value ()); return octave_value (); } // Returning current byte size return octave_value (serial->get_bytesize ()); } octave_value_list srl_stopbits (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new stop bits if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serial->set_stopbits(args (0).int_value ()); return octave_value (); } // Returning current stop bits return octave_value (serial->get_stopbits ()); } octave_value_list srl_parity (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new parity if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be string"); serial->set_parity (args (0).string_value()); return octave_value (); } // Returning current parity return octave_value (serial->get_parity ()); } octave_value_list srl_requesttosend (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); std::string onoff = ""; // Setting RTS if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be string"); onoff = args (0).string_value (); std::transform (onoff.begin (), onoff.end (), onoff.begin (), ::tolower); if (onoff == "on") serial->set_control_line ("RTS", true); else if (onoff == "off") serial->set_control_line ("RTS", false); else (*current_liboctave_error_handler) ("wrong argument"); } // Returning RTS if (serial->get_control_line ("RTS")) return octave_value ("on"); return octave_value ("off"); } octave_value_list srl_dataterminalready (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); std::string onoff = ""; // Setting DTR if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be string"); onoff = args (0).string_value (); std::transform (onoff.begin (), onoff.end (), onoff.begin (), ::tolower); if (onoff == "on") serial->set_control_line ("DTR", true); else if (onoff == "off") serial->set_control_line ("DTR", false); else (*current_liboctave_error_handler) ("wrong argument"); } // Returning DTR if (serial->get_control_line ("DTR")) return octave_value ("on"); return octave_value ("off"); } octave_value_list srl_pinstatus (octave_serial* serial, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); octave_scalar_map res; res.assign ("CarrierDetect", serial->get_control_line ("CD") ? octave_value ("on") : octave_value ("off")); res.assign ("ClearToSend", serial->get_control_line ("CTS") ? octave_value ("on") : octave_value ("off")); res.assign ("DataSetReady", serial->get_control_line ("DSR") ? octave_value ("on") : octave_value ("off")); res.assign ("RingIndicator", serial->get_control_line ("RI") ? octave_value ("on") : octave_value ("off")); return octave_value (res); } #endif // PKG_ADD: autoload ("__srl_properties__", "serial.oct"); DEFUN_DLD (__srl_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __srl_properties__ (@var{octave_serial}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_SERIAL if (args.length () < 2 || args (0).type_id () != octave_serial::static_type_id () || !args (1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args (0).get_rep (); octave_serial* serial = &((octave_serial &)rep); std::string property = args (1).string_value (); octave_value_list args2 = args.slice (2, args.length ()-2); if (property == "baudrate") return srl_baudrate (serial, args2, nargout); else if (property == "bytesize") return srl_bytesize (serial, args2, nargout); else if (property == "dataterminalready") return srl_dataterminalready (serial, args2, nargout); else if (property == "close") return srl_close (serial, args2, nargout); else if (property == "flush") return srl_flush (serial, args2, nargout); else if (property == "break") return srl_break (serial, args2, nargout); else if (property == "parity") return srl_parity (serial, args2, nargout); else if (property == "pinstatus") return srl_pinstatus (serial, args2, nargout); else if (property == "requesttosend") return srl_requesttosend (serial, args2, nargout); else if (property == "stopbits") return srl_stopbits (serial, args2, nargout); else if (property == "timeout") return srl_timeout (serial, args2, nargout); else if (property == "bytesavailable") return srl_bytesavailable (serial, args2, nargout); else if (property == "status") return srl_status (serial, args2, nargout); else if (property == "name") return srl_name (serial, args2, nargout); else if (property == "type") return srl_type (serial, args2, nargout); else if (property == "port") return srl_port (serial, args2, nargout); else (*current_liboctave_error_handler) ("wrong keyword"); #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the SERIAL interface"); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial.cc�������������������������������������������������������0000644�0000000�0000000�00000010632�14743226261�016205� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. // TODO: Implement Flow Control // TODO: Implement H/W handshaking #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include <errno.h> #include <fcntl.h> #include "serial_class.h" #endif // PKG_ADD: autoload ("serial", "serial.oct"); DEFUN_DLD (serial, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{serial} = } serial ([@var{path}], [@var{baudrate}], [@var{timeout}])\n \ \n\ Open serial interface.\n \ \n\ @subsubheading Inputs\n \ @var{path} - the interface path of type String. @*\ @var{baudrate} - the baudrate of interface. If omitted defaults to 115200. @*\ @var{timeout} - the interface timeout value. If omitted defaults to blocking call.\n \ \n\ @subsubheading Outputs\n \ The serial() shall return an instance of @var{octave_serial} class as the result @var{serial}.\n \ @subsubheading Properties\n \ The serial object has the following public properties:\n \ @table @asis\n \ @item name\n \ name assigned to the object\n \ @item type\n \ instrument type 'serial' (readonly)\n \ @item port\n \ OS specific port name (readonly)\n \ @item status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item timeout\n \ timeout value used for waiting for data\n \ @item bytesavailable\n \ number of bytes currently available to read (readonly)\n \ @item stopbits\n \ number of stopbits to use\n \ @item requesttosend\n \ request to send state - 'on' or 'off'\n \ @item parity\n \ Parity setting 'none', 'even', 'odd'\n \ @item bytesize\n \ Number of bits to a byte (7 or 8)\n \ @item baudrate\n \ Baudrate setting\n \ @item dataterminalready\n \ state of dataterminal ready - 'on' or 'off'\n \ @item pinstatus\n \ current state of pins (readonly)\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_SERIAL error ("serial: Your system doesn't support the SERIAL interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values std::string path; unsigned int baud_rate = 115200; short timeout = -1; unsigned short bytesize = 8; std::string parity("N"); unsigned short stopbits = 1; // Parse the function arguments if ((args.length () == 0) || !args(0 ).is_string ()) { print_usage (); return octave_value (); } path = args (0).string_value (); // isfloat() is or'ed to allow expression like ("", 123), without user // having to use ("", int32(123)), as we still only take "int_value" if (args.length() > 1) { if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { baud_rate = args (1).int_value (); } else { print_usage (); return octave_value (); } } if (args.length () > 2) { if (args (2).OV_ISINTEGER () || args (2).OV_ISFLOAT ()) { timeout = args (2).int_value (); } else { print_usage (); return octave_value (); } } octave_serial* retval = new octave_serial (); // Open the interface retval->open (path); retval->set_baudrate (baud_rate); retval->set_timeout (timeout); retval->set_parity (parity); retval->set_bytesize (bytesize); retval->set_stopbits (stopbits); //retval->flush (2); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "serial")) %! fail ("serial ()", "Invalid call to serial"); %! else %! fail ("serial ()", "serial: Your system doesn't support the serial interface"); %! endif #endif ������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial_class.cc�������������������������������������������������0000644�0000000�0000000�00000006427�14743226261�017401� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include "serial_class.h" octave_serial_common::octave_serial_common () : fieldnames(13) { fieldnames[0] = "baudrate"; fieldnames[1] = "bytesize"; fieldnames[2] = "dataterminalready"; fieldnames[3] = "parity"; fieldnames[4] = "pinstatus"; fieldnames[5] = "requesttosend"; fieldnames[6] = "stopbits"; fieldnames[7] = "timeout"; fieldnames[8] = "bytesavailable"; fieldnames[9] = "status"; fieldnames[10] = "name"; fieldnames[11] = "type"; fieldnames[12] = "port"; } octave_value_list octave_serial_common::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_serial object cannot be indexed with %c", type[0]); break; case '.': { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__srl_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_serial_common::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_serial object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__srl_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); } OV_COUNT++; retval = octave_value (this); } else { error ("octave_serial invalid index"); } } return retval; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial_class.h��������������������������������������������������0000644�0000000�0000000�00000012544�14743226261�017240� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // 2018 John Donoghue <john.donoghue@ieee.org> // 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef SERIAL_CLASS_H #define SERIAL_CLASS_H #include <octave/oct.h> //#include <octave/ops.h> #include <string> #define BITMASK_SET(x,y) ((x) |= (y)) #define BITMASK_CLEAR(x,y) ((x) &= (~(y))) #define BITMASK_TOGGLE(x,y) ((x) ^= (y)) #define BITMASK_CHECK(x,y) ((x) & (y)) #define BITMASK_CHECK_VALUE(x,y,z) (((x) & (y)) == (z)) #define CONCAT2X(x,y) x ## y #define CONCAT2(x,y) CONCAT2X(x,y) #define BINOPDECL(name, a1, a2) \ static octave_value \ CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) #define CAST_BINOP_ARGS(t1, t2) \ t1 v1 = dynamic_cast<t1> (a1); \ t2 v2 = dynamic_cast<t2> (a2) #define DEFBINOP_CLASS_OP(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \ return octave_value \ (&v1 op &v2); \ } #ifdef OCTAVE__NEW_REGISTER_OP #define INSTALL_BINOP(op, t1, t2, f) \ {octave::type_info& ti = octave::interpreter::the_interpreter ()->get_type_info (); \ ti.register_binary_op \ (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ CONCAT2(oct_binop_, f));} #else #define INSTALL_BINOP(op, t1, t2, f) \ octave_value_typeinfo::register_binary_op \ (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ CONCAT2(oct_binop_, f)); #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_serial_common : public OCTAVE_BASE_CLASS { protected: octave_serial_common(); public: // os dependent functions virtual bool fd_is_valid() const = 0; virtual int get_timeout() const = 0; virtual int get_baudrate() const = 0; virtual int get_bytesize() const = 0; virtual std::string get_parity() const = 0; virtual int get_stopbits() const = 0; virtual int get_bytesavailable() const = 0; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true;} // 4.4+ bool isobject (void) const { return true;} octave_base_value * unique_clone (void) { OV_COUNT++; return this;} // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } void print (std::ostream& os, bool pr_as_read_syntax = false) { print_raw(os, pr_as_read_syntax); newline(os); } void print (std::ostream& os, bool pr_as_read_syntax = false) const { print_raw(os, pr_as_read_syntax); newline(os); } void print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " Serial Port Object " << this->get_name(); newline(os); os << " status: " << this->get_status(); newline(os); if (this->fd_is_valid()) { os << " port: " << this->portPath; newline(os); os << " baudrate: " << this->get_baudrate(); newline(os); os << " parity: " << this->get_parity(); newline(os); os << " bytesize: " << this->get_bytesize(); newline(os); os << " stopbits: " << this->get_stopbits(); newline(os); os << " timeout: " << this->get_timeout(); newline(os); //os << "Mode: " << blockmode; newline(os); } } bool operator==(octave_serial_common& other) const { return (this == &other); } bool operator!=(octave_serial_common& other) const { return ! (this == &other); } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); std::string get_status () const { if (fd_is_valid ()) return "open"; else return "closed"; } std::string get_type () const { return "serial"; } std::string get_port () const { return portPath; } std::string get_name () const { return name; } void set_name (const std::string &newname) { name = newname; } protected: string_vector fieldnames; std::string name; std::string portPath; }; #ifdef __WIN32__ #include "serial_class_win32.h" #else #include "serial_class_lin.h" #endif //DEFBINOP_CLASS_OP (eq_serial_serial, serial, serial, ==) //DEFBINOP_CLASS_OP (ne_serial_serial, serial, serial, !=) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial_class_lin.cc���������������������������������������������0000644�0000000�0000000�00000036267�14743226261�020250� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include <iostream> #include <string> #include <algorithm> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <unistd.h> #include "serial_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_serial, "octave_serial", "octave_serial"); DEFBINOP_CLASS_OP (eq_serial_serial, serial, serial, ==) DEFBINOP_CLASS_OP (ne_serial_serial, serial, serial, !=) octave_serial::octave_serial (void) : fd (-1) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); INSTALL_BINOP (op_eq, octave_serial, octave_serial, eq_serial_serial); INSTALL_BINOP (op_ne, octave_serial, octave_serial, ne_serial_serial); } } void octave_serial::open (const std::string &path) { int flags = O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY; // O_SYNC - All writes immediately effective, no buffering // O_NOCTTY - Do not make serial terminal the controlling terminal for the process // O_NDELAY - Do not care what state the DCD signal line is in. Used for open only, later disabled. fd = ::open (path.c_str (), flags); portPath = path; name = "Serial-" + portPath; if (fd_is_valid ()) { // Check whether fd is an open file descriptor referring to a terminal if(! isatty (fd)) { error("serial: Interface does not refer to a terminal: %s\n", strerror (errno)); octave_serial::close (); return; } if (tcgetattr (fd, &config) < 0) { error ("serial: Failed to get terminal attributes: %s\n", strerror (errno)); octave_serial::close (); return; } // Clear all settings config.c_iflag = 0; // Input modes config.c_oflag = 0; // Output modes config.c_cflag = CS8 | CREAD | CLOCAL; // Control modes, 8n1 config.c_lflag = 0; // Local modes config.c_cc[VMIN] = 1; if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serial: Failed to set default terminal attributes: %s\n", strerror (errno)); octave_serial::close (); return; } // Disable NDELAY if (fcntl (fd, F_SETFL, 0) < 0) { error ("serial: Failed to disable NDELAY flag: %s\n", strerror (errno)); octave_serial::close (); return; } timeout = -1; blocking_read = true; } else { error ("serial: Error opening the interface: %s\n", strerror (errno)); return; } } octave_serial::~octave_serial (void) { octave_serial::close(); } int octave_serial::read (uint8_t *buf, unsigned int len) { if (! fd_is_valid ()) { error ("srl_read: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; int maxwait = timeout; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; read_retval = ::read (fd, (void *)(buf + bytes_read), len - bytes_read); //printf("read_retval: %d\n\r", read_retval); if (read_retval < 0) { error ("srl_read: Error while reading: %s\n", strerror (errno)); break; } bytes_read += read_retval; // Timeout while in non-blocking mode if (read_retval == 0 && !blocking_read) { maxwait -= config.c_cc[VTIME]; // actual timeout if (maxwait <= 0) break; } } return bytes_read; } int octave_serial::write (const std::string &str) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } return ::write (fd, str.c_str (), str.length ()); } int octave_serial::write(uint8_t *buf, unsigned int len) { if (!fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } return ::write (fd, buf, len); } int octave_serial::set_timeout (short newtimeout) { if (! fd_is_valid ()) { error("serial: Interface must be opened first..."); return -1; } if (newtimeout < -1 || newtimeout > 255) { error("srl_timeout: timeout value must be between [-1..255]..."); return -1; } timeout = newtimeout; // Disable custom timeout, enable blocking read if (newtimeout < 0) { blocking_read = true; newtimeout = 5; } // Enable custom timeout, disable blocking read else { blocking_read = false; if(newtimeout > 10) newtimeout = 5; } BITMASK_CLEAR (config.c_lflag, ICANON); // Set non-canonical mode config.c_cc[VMIN] = 0; config.c_cc[VTIME] = (unsigned) newtimeout; // Set timeout of 'timeout * 10' seconds if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("srl_timeout: error setting timeout..."); return -1; } return 1; } int octave_serial::get_timeout (void) const { if (blocking_read) return -1; else return timeout; } int octave_serial::set_stopbits (unsigned short stopbits) { if (!fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } /* * CSTOPB Send two stop bits, else one. */ if (stopbits == 1) { // Set to one stop bit BITMASK_CLEAR (config.c_cflag, CSTOPB); } else if (stopbits == 2) { // Set to two stop bits BITMASK_SET (config.c_cflag, CSTOPB); } else { error ("srl_stopbits: Only 1 or 2 stop bits are supported..."); return false; } if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("srl_stopbits: error setting stop bits: %s\n", strerror (errno)); return false; } return true; } int octave_serial::get_stopbits (void) const { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } if (BITMASK_CHECK (config.c_cflag, CSTOPB)) return 2; else return 1; } int octave_serial::set_bytesize (unsigned short bytesize) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } tcflag_t c_bytesize = 0; switch (bytesize) { case 5: c_bytesize = CS5; break; case 6: c_bytesize = CS6; break; case 7: c_bytesize = CS7; break; case 8: c_bytesize = CS8; break; default: error ("srl_bytesize: expecting value between [5..8]..."); return false; } // Clear bitmask CSIZE BITMASK_CLEAR (config.c_cflag, CSIZE); // Apply new BITMASK_SET (config.c_cflag, c_bytesize); if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("srl_bytesize: error setting byte size: %s\n", strerror (errno)); return false; } return true; } int octave_serial::get_bytesize (void) const { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } int retval = -1; if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS5)) retval = 5; else if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS6)) retval = 6; else if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS7)) retval = 7; else if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS8)) retval = 8; return retval; } int octave_serial::set_baudrate (unsigned int baud) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } speed_t baud_rate = 0; switch (baud) { case 0: baud_rate = B0; break; case 50: baud_rate = B50; break; case 75: baud_rate = B75; break; case 110: baud_rate = B110; break; case 134: baud_rate = B134; break; case 150: baud_rate = B150; break; case 200: baud_rate = B200; break; case 300: baud_rate = B300; break; case 600: baud_rate = B600; break; case 1200: baud_rate = B1200; break; case 1800: baud_rate = B1800; break; case 2400: baud_rate = B2400; break; case 4800: baud_rate = B4800; break; case 9600: baud_rate = B9600; break; case 19200: baud_rate = B19200; break; case 38400: baud_rate = B38400; break; #ifdef B57600 case 57600: baud_rate = B57600; break; #endif #ifdef B115200 case 115200: baud_rate = B115200; break; #endif #ifdef B230400 case 230400: baud_rate = B230400; break; #endif #ifdef B460800 case 460800: baud_rate = B460800; break; #endif #ifdef B500000 case 500000: baud_rate = B500000; break; #endif #ifdef B576000 case 576000: baud_rate = B576000; break; #endif #ifdef B921600 case 921600: baud_rate = B921600; break; #endif #ifdef B1000000 case 1000000: baud_rate = B1000000; break; #endif #ifdef B1152000 case 1152000: baud_rate = B1152000; break; #endif #ifdef B2000000 case 2000000: baud_rate = B2000000; break; #endif #ifdef B3000000 case 3000000: baud_rate = B3000000; break; #endif #ifdef B3500000 case 3500000: baud_rate = B3500000; break; #endif #ifdef B4000000 case 4000000: baud_rate = B4000000; break; #endif default: error ("serial: baud rate not supported..."); return false; } cfsetispeed (&config, baud_rate); cfsetospeed (&config, baud_rate); if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("srl_baudrate: error setting baud rate: %s\n", strerror (errno)); return false; } return true; } int octave_serial::get_baudrate (void) const { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } int retval = -1; speed_t baudrate = cfgetispeed (&config); if (baudrate == B0) retval = 0; else if (baudrate == B50) retval = 50; else if (baudrate == B75) retval = 75; else if (baudrate == B110) retval = 110; else if (baudrate == B134) retval = 134; else if (baudrate == B150) retval = 150; else if (baudrate == B200) retval = 200; else if (baudrate == B300) retval = 300; else if (baudrate == B600) retval = 600; else if (baudrate == B1200) retval = 1200; else if (baudrate == B1800) retval = 1800; else if (baudrate == B2400) retval = 2400; else if (baudrate == B4800) retval = 4800; else if (baudrate == B9600) retval = 9600; else if (baudrate == B19200) retval = 19200; else if (baudrate == B38400) retval = 38400; else if (baudrate == B57600) retval = 57600; else if (baudrate == B115200) retval = 115200; else if (baudrate == B230400) retval = 230400; return retval; } int octave_serial::flush (unsigned short queue_selector) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } /* * TCIOFLUSH Flush both pending input and untransmitted output. * TCOFLUSH Flush untransmitted output. * TCIFLUSH Flush pending input. */ int flag; switch (queue_selector) { case 0: flag = TCOFLUSH; break; case 1: flag = TCIFLUSH; break; case 2: flag = TCIOFLUSH; break; default: error("srl_flush: only [0..2] values are accepted..."); return false; } return ::tcflush (fd, flag); } int octave_serial::sendbreak (unsigned short ms) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } return ::tcsendbreak (fd, ms); } int octave_serial::set_parity (const std::string &newparity) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } // Convert string to lowercase std::string parity = newparity; std::transform (parity.begin (), parity.end (), parity.begin (), ::tolower); /* * PARENB Enable parity generation on output and parity checking for input. * PARODD If set, then parity for input and output is odd; otherwise even parity is used. */ if (parity == "n" || parity == "none") { // Disable parity generation/checking BITMASK_CLEAR (config.c_cflag, PARENB); } else if (parity == "e" || parity == "even") { // Enable parity generation/checking BITMASK_SET (config.c_cflag, PARENB); // Set to Even BITMASK_CLEAR (config.c_cflag, PARODD); } else if (parity == "o" || parity == "odd") { // Enable parity generation/checking BITMASK_SET (config.c_cflag, PARENB); // Set to Odd BITMASK_SET (config.c_cflag, PARODD); } else { error ("srl_parity: Only [N]one, [E]ven or [O]dd parities are supported..."); return false; } if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("srl_parity: error setting parity: %s\n", strerror (errno)); return false; } return true; } std::string octave_serial::get_parity (void) const { if (!BITMASK_CHECK (config.c_cflag, PARENB)) return "None"; else if (BITMASK_CHECK (config.c_cflag, PARODD)) return "Odd"; else return "Even"; } void octave_serial::get_control_line_status (void) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return; } ioctl (fd, TIOCMGET, &status); } bool octave_serial::get_control_line (const std::string &control_signal) { get_control_line_status (); if (control_signal == "DTR") return (status & TIOCM_DTR); else if (control_signal == "RTS") return (status & TIOCM_RTS); else if (control_signal == "CTS") return (status & TIOCM_CTS); else if (control_signal == "DSR") return (status & TIOCM_DSR); else if (control_signal == "CD") return (status & TIOCM_CD); else if (control_signal == "RI") return (status & TIOCM_RI); error ("serial: Unknown control signal..."); return false; } void octave_serial::set_control_line (const std::string &control_signal, bool set) { get_control_line_status (); int signal; if (control_signal == "DTR") signal = TIOCM_DTR; else if (control_signal == "RTS") signal = TIOCM_RTS; else { error ("serial: Unknown control signal..."); return; } if (set) status |= signal; else status &= ~signal; ioctl (fd, TIOCMSET, &status); } bool octave_serial::fd_is_valid (void) const { return (fd >= 0); } void octave_serial::close (void) { if (fd_is_valid ()) { ::close (fd); fd = -1; } } int octave_serial::get_bytesavailable (void) const { int available = 0; if (fd_is_valid ()) { ioctl (fd, FIONREAD, &available); } return available; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial_class_lin.h����������������������������������������������0000644�0000000�0000000�00000004063�14743226261�020077� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef SERIAL_CLASS_LIN_H #define SERIAL_CLASS_LIN_H #include <string> #include <termios.h> class octave_serial : public octave_serial_common { public: octave_serial(void); ~octave_serial(void); int write(const std::string& /* buffer */); int write(uint8_t* /* buffer */, unsigned int /* buffer size */); int read(uint8_t* /* buffer */, unsigned int /* buffer size */); void open(const std::string& /* path */); void close(void); int flush(unsigned short /* stream select */); int sendbreak(unsigned short /* ms */); int set_timeout(short /* timeout */); int get_timeout(void) const; int set_baudrate(unsigned int /* baudrate */); int get_baudrate(void) const; int set_bytesize(unsigned short /* bytesize */); int get_bytesize(void) const; int set_parity(const std::string& /* parity */); std::string get_parity() const; int set_stopbits(unsigned short /* stop bits */); int get_stopbits(void) const; bool get_control_line(const std::string &); void set_control_line(const std::string &, bool); int get_bytesavailable(void) const; private: int fd; int status; struct termios config; short timeout; volatile bool blocking_read; void get_control_line_status(void); bool fd_is_valid(void) const; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial_class_win32.cc�������������������������������������������0000644�0000000�0000000�00000030570�14743226261�020417� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2014-2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #if HAVE_OCTAVE_LO_SYSDEP_H #include <octave/lo-sysdep.h> #endif #include <iostream> #include <string> #include <algorithm> using std::string; #include "serial_class.h" std::string winerror () { DWORD e; e = GetLastError (); #if HAVE_OCTAVE_U8_TO_WSTRING wchar_t errstring[100+1]; if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errstring, 100, 0) == 0) { errstring[0] = '\0'; } return octave::sys::u8_from_wstring (errstring); #else char errstring[100+1]; if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errstring, 100, 0) == 0) { errstring[0] = '\0'; } return errstring; #endif } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_serial, "octave_serial", "octave_serial"); DEFBINOP_CLASS_OP (eq_serial_serial, serial, serial, ==) DEFBINOP_CLASS_OP (ne_serial_serial, serial, serial, !=) octave_serial::octave_serial(void) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); INSTALL_BINOP (op_eq, octave_serial, octave_serial, eq_serial_serial); INSTALL_BINOP (op_ne, octave_serial, octave_serial, ne_serial_serial); } fd = INVALID_HANDLE_VALUE; } void octave_serial::open (const std::string &path) { portPath = path; name = "Serial-" + path; // use full extended port names if not already specified std::string fullPath = path; if (fullPath.length() > 0 && fullPath[0] != '\\') fullPath = "\\\\.\\" + path; fd = CreateFile(fullPath.c_str (), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (! fd_is_valid()) { error("serial: Error opening the interface: %s\n", winerror ().c_str ()); return; } // clear any errors that may be on the port COMSTAT stats; DWORD err; ClearCommError (fd, &err, &stats); // Clean the configuration struct (DCB) memset (&config, 0, sizeof (config)); // set up device settings config.DCBlength = sizeof (config); if(GetCommState (fd, &config) == FALSE) { error ("serial: Failed to get terminal attributes: %s\n", winerror ().c_str ()); octave_serial::close (); return; } timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; timeout = -1; if (SetCommTimeouts(fd, &timeouts) == FALSE) { error ("serial: Failed to disable timeouts: %s\n", winerror ().c_str ()); octave_serial::close (); return; } return; } octave_serial::~octave_serial(void) { octave_serial::close(); } int octave_serial::read(uint8_t *buf, unsigned int len) { if (! fd_is_valid ()) { error ("srl_read: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; int maxwait = timeout; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; DWORD readsz; read_retval = -1; if (ReadFile (fd, (buf + bytes_read), len - bytes_read, &readsz, NULL) == TRUE) { read_retval = readsz; } if(read_retval < 0) { error ("srl_read: Error while reading: %s\n", winerror ().c_str ()); break; } bytes_read += read_retval; if (read_retval == 0 && !blocking_read) { maxwait -= timeouts.ReadTotalTimeoutConstant/100; // actual timeout if (maxwait <= 0) break; } } return bytes_read; } int octave_serial::write (const std::string & str) { if (! fd_is_valid ()) { error("serial: Interface must be opened first..."); return -1; } int wrote_ret = -1; DWORD wrote; if (WriteFile (fd, str.c_str (), str.length (), &wrote, NULL) == TRUE) { wrote_ret = wrote; } return wrote_ret; } int octave_serial::write (uint8_t *buf, unsigned int len) { if (! fd_is_valid ()) { error("serial: Interface must be opened first..."); return -1; } int wrote_ret = -1; DWORD wrote; if (WriteFile (fd, buf, len, &wrote, NULL) == TRUE) { wrote_ret = wrote; } return wrote_ret; } int octave_serial::set_timeout (short newtimeout) { if (! fd_is_valid()) { error ("serial: Interface must be opened first..."); return -1; } if (newtimeout < -1 || newtimeout > 255) { error ("srl_timeout: timeout value must be between [-1..255]..."); return -1; } timeout = newtimeout; // Disable custom timeout, enable blocking read if (newtimeout < 0) { blocking_read = true; newtimeout = 5; } // Enable custom timeout, disable blocking read else { blocking_read = false; if (newtimeout > 10) newtimeout = 5; } timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = newtimeout*100; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (SetCommTimeouts (fd, &timeouts) == FALSE) { error ("srl_timeout: error setting timeout..."); return -1; } return 1; } int octave_serial::get_timeout (void) const { if (blocking_read) return -1; else return timeout; } int octave_serial::set_stopbits (unsigned short stopbits) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } if (stopbits == 1) { // Set to one stop bit config.StopBits = ONESTOPBIT; } else if (stopbits == 2) { // Set to two stop bits config.StopBits = TWOSTOPBITS; } else { error ("srl_stopbits: Only 1 or 2 stop bits are supported..."); return false; } if (SetCommState (fd,&config) == FALSE) { error ("srl_stopbits: error setting stop bits: %s\n", winerror ().c_str ()); return false; } return true; } int octave_serial::get_stopbits (void) const { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } if (config.StopBits == TWOSTOPBITS) return 2; else return 1; } int octave_serial::set_bytesize (unsigned short bytesize) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } if(bytesize < 5 || bytesize > 8) { error ("srl_bytesize: expecting value between [5..8]..."); return false; } config.ByteSize = bytesize; if (SetCommState (fd, &config) == FALSE) { error ("serial: error setting byte size: %s\n", winerror ().c_str ()); return false; } return true; } int octave_serial::get_bytesize (void) const { if (! fd_is_valid ()) { error("serial: Interface must be opened first..."); return -1; } return config.ByteSize; } int octave_serial::set_baudrate (unsigned int baud) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } DWORD old_baud = config.BaudRate; config.BaudRate = baud; if (SetCommState (fd, &config) == FALSE) { error ("serial: error setting baud rate: %s\n", winerror ().c_str ()); config.BaudRate = old_baud; return false; } return true; } int octave_serial::get_baudrate (void) const { if (! fd_is_valid ()) { error("serial: Interface must be opened first..."); return -1; } return config.BaudRate; } int octave_serial::flush (unsigned short queue_selector) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } int flag; switch (queue_selector) { case 0: flag = PURGE_TXCLEAR; break; case 1: flag = PURGE_RXCLEAR; break; case 2: flag = PURGE_RXCLEAR|PURGE_TXCLEAR; break; default: error ("srl_flush: only [0..2] values are accepted..."); return false; } if (PurgeComm (fd,flag) == FALSE) return -1; else return true; } int octave_serial::sendbreak (unsigned short ms) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } if (ms > 5000) ms = 5000; if(SetCommBreak(fd) == TRUE) { Sleep(ms); ClearCommBreak(fd); return true; } return false; } int octave_serial::set_parity (const std::string &newparity) { if (! fd_is_valid ()) { error ("serial: Interface must be opened first..."); return -1; } // Convert string to lowercase std::string parity = newparity; std::transform (parity.begin (), parity.end (), parity.begin (), ::tolower); /* * PARENB Enable parity generation on output and parity checking for input. * PARODD If set, then parity for input and output is odd; otherwise even parity is used. */ if (parity == "n" || parity == "none") { // Disable parity generation/checking config.Parity = NOPARITY; } else if (parity == "e" || parity == "even") { // Enable parity generation/checking config.Parity = EVENPARITY; } else if (parity == "o" || parity == "odd") { config.Parity = ODDPARITY; } else { error ("srl_parity: Only [N]one, [E]ven or [O]dd parities are supported..."); return false; } if (SetCommState (fd, &config) == FALSE) { error ("srl_parity: error setting parity: %s\n", winerror ().c_str ()); return false; } return true; } std::string octave_serial::get_parity (void) const { if(config.Parity == NOPARITY) return "None"; else if(config.Parity == ODDPARITY) return "Odd"; else return "Even"; } void octave_serial::get_control_line_status (void) { if (! fd_is_valid()) { error ("serial: Interface must be opened first..."); return; } GetCommState (fd, &config); GetCommModemStatus (fd, &status); } bool octave_serial::get_control_line (const std::string &control_signal) { get_control_line_status (); if (control_signal == "DTR") return (config.fDtrControl == DTR_CONTROL_ENABLE); else if (control_signal == "RTS") return (config.fRtsControl == RTS_CONTROL_ENABLE); else if (control_signal == "CTS") return (status & MS_CTS_ON); else if (control_signal == "DSR") return (status & MS_DSR_ON); else if (control_signal == "CD") return (status & MS_RLSD_ON); else if (control_signal == "RI") return (status & MS_RING_ON); else error("serial: Unknown control signal..."); return false; } void octave_serial::set_control_line (const std::string &control_signal, bool set) { get_control_line_status (); int signal; if (control_signal == "DTR") { if(set) config.fDtrControl = DTR_CONTROL_ENABLE; else config.fDtrControl = DTR_CONTROL_DISABLE; } else if (control_signal == "RTS") { if(set) config.fRtsControl = RTS_CONTROL_ENABLE; else config.fRtsControl = RTS_CONTROL_DISABLE; } else { error("serial: Unknown control signal..."); return; } SetCommState (fd, &config); } bool octave_serial::fd_is_valid (void) const { return (fd != INVALID_HANDLE_VALUE); } void octave_serial::close (void) { if (fd_is_valid ()) { CloseHandle(fd); fd = INVALID_HANDLE_VALUE; } } int octave_serial::get_bytesavailable (void) const { int available = 0; if (fd_is_valid ()) { COMSTAT stats; DWORD err; if (ClearCommError (fd, &err, &stats)) available = stats.cbInQue; } return available; } #endif ����������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/serial_class_win32.h��������������������������������������������0000644�0000000�0000000�00000004222�14743226261�020254� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef SERIAL_CLASS_WIN32_H #define SERIAL_CLASS_WIN32_H #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #include <string> class octave_serial : public octave_serial_common { public: octave_serial(void); ~octave_serial(void); int write(const std::string& /* buffer */); int write(uint8_t* /* buffer */, unsigned int /* buffer size */); int read(uint8_t* /* buffer */, unsigned int /* buffer size */); void open(const std::string& /* path */); void close(void); int flush(unsigned short /* stream select */); int sendbreak(unsigned short /* breaktime */); int set_timeout(short /* timeout */); int get_timeout(void) const; int set_baudrate(unsigned int /* baudrate */); int get_baudrate() const; int set_bytesize(unsigned short /* bytesize */); int get_bytesize(void) const; int set_parity(const std::string& /* parity */); std::string get_parity(void) const; int set_stopbits(unsigned short /* stop bits */); int get_stopbits(void) const; bool get_control_line(const std::string &); void set_control_line(const std::string&, bool); int get_bytesavailable(void) const; private: HANDLE fd; DWORD status; DCB config; COMMTIMEOUTS timeouts; volatile bool blocking_read; short timeout; void get_control_line_status(void); bool fd_is_valid(void) const; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/srl_read.cc�����������������������������������������������������0000644�0000000�0000000�00000005253�14743226261�016524� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include <octave/uint8NDArray.h> #include <errno.h> #include "serial_class.h" #endif // PKG_ADD: autoload ("srl_read", "serial.oct"); DEFUN_DLD (srl_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } srl_read (@var{serial}, @var{n})\n \ \n\ Read from serial interface.\n \ \n\ @subsubheading Inputs\n \ @var{serial} - instance of @var{octave_serial} class.@*\ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ @subsubheading Outputs\n \ The srl_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_SERIAL error("serial: Your system doesn't support the SERIAL interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_serial::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 0; if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } buffer_len = args (1).int_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("srl_read: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } octave_serial* serial = NULL; const octave_base_value& rep = args (0).get_rep (); serial = &((octave_serial &)rep); // Read data int bytes_read = serial->read (buffer, buffer_len); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data (dim_vector (1, bytes_read)); for (int i = 0; i < bytes_read; i++) data (i) = buffer[i]; return_list (0) = data; return_list (1) = bytes_read; return return_list; #endif } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serial/srl_write.cc����������������������������������������������������0000644�0000000�0000000�00000005046�14743226261�016743� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include "serial_class.h" #endif // PKG_ADD: autoload ("srl_write", "serial.oct"); DEFUN_DLD (srl_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } srl_write (@var{serial}, @var{data})\n \ \n\ Write data to a serial interface.\n \ \n\ @subsubheading Inputs\n \ @var{serial} - instance of @var{octave_serial} class.@*\ @var{data} - data to be written to the serial interface. Can be either of String or uint8 type.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, srl_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_SERIAL error ("serial: Your system doesn't support the SERIAL interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_serial::static_type_id ()) { print_usage (); return octave_value (-1); } octave_serial *serial = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); serial = &((octave_serial &)rep); if (args (1).is_string ()) // String { retval = serial->write (args (1).string_value ()); } else if (args (1).is_uint8_type ()) // uint8_t { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("srl_write: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = serial->write (buf, data.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015322� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/Makefile.in�������������������������������������������������0000644�0000000�0000000�00000000520�14743226261�017364� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../serialport.oct OBJ := serialport.o __srlp_write__.o __srlp_read__.o __srlp_properties__.o __serialport_pkg_lock__.o serialport_class.o LFLAGS = $(LIBS) CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ ifeq ("@BUILD_FOR_WINDOWS@","1") OBJ += serialport_class_win32.o else OBJ += serialport_class_lin.o endif include ../common.mk ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/__serialport_pkg_lock__.cc����������������������������������0000644�0000000�0000000�00000003041�14743226261�022460� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__serialport_pkg_lock__", "serialport.oct"); // PKG_ADD: __serialport_pkg_lock__(1); // PKG_DEL: __serialport_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__serialport_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__serialport_pkg_lock__")) interp.munlock("__serialport_pkg_lock__"); } return retval; } #else DEFUN_DLD(__serialport_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/__srlp_properties__.cc��������������������������������������0000644�0000000�0000000�00000034225�14743226261�021667� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019-2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include "serialport_class.h" #endif #ifdef BUILD_SERIAL octave_value_list srlp_flush (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Default arguments int queue_selector = 2; // Input and Output if (args.length () > 0) { if (!(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer or float"); queue_selector = args (0).int_value (); } serialport->flush (queue_selector); return octave_value (); } octave_value_list srlp_break (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Default arguments int ms = 2; // Input and Output if (args.length () > 0) { if (!(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer"); ms = args (0).int_value (); } serialport->sendbreak (ms); return octave_value (); } octave_value_list srlp_timeout (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serialport->set_timeout (args (0).double_value ()); return octave_value (); // Should it return by default? } // Returning current timeout return octave_value (serialport->get_timeout ()); } octave_value_list srlp_userdata (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serialport->set_userdata (args (0)); return octave_value (); // Should it return by default? } // Returning current timeout return octave_value (serialport->get_userdata ()); } octave_value_list srlp_flowcontrol (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).is_string() )) (*current_liboctave_error_handler) ("argument must be a string"); serialport->set_flowcontrol (args (0).string_value()); return octave_value (); // Should it return by default? } return octave_value (serialport->get_flowcontrol ()); } octave_value_list srlp_terminator (octave_serialport* serialport, const octave_value_list& args, int nargout) { // Setting new timeout if (args.length () == 1) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type())) (*current_liboctave_error_handler) ("argument must be a string or number"); serialport->set_input_terminator (args (0)); serialport->set_output_terminator (args (0)); return octave_value (); // Should it return by default? } else if (args.length () == 2) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type())) (*current_liboctave_error_handler) ("argument must be a string or number"); if ( !(args (1).is_string ()) && !(args (0).is_scalar_type())) (*current_liboctave_error_handler) ("argument must be a string or numer"); // could be 1 or 2 args here serialport->set_input_terminator (args (0)); serialport->set_output_terminator (args (1)); return octave_value (); // Should it return by default? } else if (args.length () > 2) (*current_liboctave_error_handler) ("wrong number of arguments"); // may have a single terminator or a start and stop octave_value in = serialport->get_input_terminator (); octave_value out = serialport->get_output_terminator (); if(in.is_string() && out.is_string() && in.string_value() == out.string_value()) return in; else if(in.is_scalar_type() && out.is_scalar_type() && in.int_value() == out.int_value()) return in; else { Cell ret = Cell(dim_vector(1, 2)); ret(0) = in; ret(1) = out; return octave_value (ret); } return octave_value_list(); } octave_value_list srlp_byteorder (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new timeout if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be a string"); serialport->set_byteorder (args (0).string_value()); return octave_value (); // Should it return by default? } return octave_value (serialport->get_byteorder ()); } octave_value_list srlp_numbytesavailable (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); // Returning bytes available return octave_value (serialport->get_numbytesavailable ()); } octave_value_list srlp_numbyteswritten (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); // Returning bytes available return octave_value (serialport->get_numbyteswritten ()); } octave_value_list srlp_port (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("read only value"); // Returning bytes available return octave_value (serialport->get_port ()); } octave_value_list srlp_baudrate (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new baudrate if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ())) (*current_liboctave_error_handler) ("argument must be integer or float"); serialport->set_baudrate (args (0).int_value ()); return octave_value (); } // Returning current baud rate return octave_value (serialport->get_baudrate ()); } octave_value_list srlp_databits (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new byte size if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serialport->set_databits (args (0).int_value ()); return octave_value (); } // Returning current byte size return octave_value (serialport->get_databits ()); } octave_value_list srlp_stopbits (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length() > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new stop bits if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) ) (*current_liboctave_error_handler) ("argument must be integer or float"); serialport->set_stopbits(args (0).int_value ()); return octave_value (); } // Returning current stop bits return octave_value (serialport->get_stopbits ()); } octave_value_list srlp_parity (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting new parity if (args.length () > 0) { if ( !(args (0).is_string ()) ) (*current_liboctave_error_handler) ("argument must be string"); serialport->set_parity (args (0).string_value()); return octave_value (); } // Returning current parity return octave_value (serialport->get_parity ()); } octave_value_list srlp_requesttosend (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); // Setting RTS if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT () || args(0).OV_ISLOGICAL ()) ) (*current_liboctave_error_handler) ("argument must be boolean or a number"); int onoff = args (0).int_value (); if (onoff) serialport->set_control_line ("RTS", true); else serialport->set_control_line ("RTS", false); } // Returning RTS if (serialport->get_control_line ("RTS")) return octave_value (1); return octave_value (0); } octave_value_list srlp_dataterminalready (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 1) (*current_liboctave_error_handler) ("wrong number of arguments"); std::string onoff = ""; // Setting DTR if (args.length () > 0) { if (! (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT () || args(0).OV_ISLOGICAL ()) ) (*current_liboctave_error_handler) ("argument must be boolean or a number"); int onoff = args (0).int_value (); if (onoff) serialport->set_control_line ("DTR", true); else serialport->set_control_line ("DTR", false); } // Returning DTR if (serialport->get_control_line ("DTR")) return octave_value (1); return octave_value (0); } octave_value_list srlp_pinstatus (octave_serialport* serialport, const octave_value_list& args, int nargout) { if (args.length () > 0) (*current_liboctave_error_handler) ("wrong number of arguments"); octave_scalar_map res; res.assign ("CarrierDetect", serialport->get_control_line ("CD") ? octave_value (1) : octave_value (0)); res.assign ("ClearToSend", serialport->get_control_line ("CTS") ? octave_value (1) : octave_value (0)); res.assign ("DataSetReady", serialport->get_control_line ("DSR") ? octave_value (1) : octave_value (0)); res.assign ("RingIndicator", serialport->get_control_line ("RI") ? octave_value (0) : octave_value (1)); return octave_value (res); } #endif // PKG_ADD: autoload ("__srlp_properties__", "serialport.oct"); DEFUN_DLD (__srlp_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __srlp_properties__ (@var{octave_serialport}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_SERIAL if (args.length () < 2 || args (0).type_id () != octave_serialport::static_type_id () || !args (1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args (0).get_rep (); octave_serialport* serialport = &((octave_serialport &)rep); std::string property = args (1).string_value (); std::transform (property.begin (), property.end (), property.begin (), ::tolower); octave_value_list args2 = args.slice (2, args.length ()-2); if (property == "port") return srlp_port (serialport, args2, nargout); else if (property == "baudrate") return srlp_baudrate (serialport, args2, nargout); else if (property == "numbytesavailable") return srlp_numbytesavailable (serialport, args2, nargout); else if (property == "numbyteswritten") return srlp_numbyteswritten (serialport, args2, nargout); else if (property == "byteorder") return srlp_byteorder (serialport, args2, nargout); else if (property == "databits") return srlp_databits (serialport, args2, nargout); else if (property == "stopbits") return srlp_stopbits (serialport, args2, nargout); else if (property == "parity") return srlp_parity (serialport, args2, nargout); else if (property == "flowcontrol") return srlp_flowcontrol (serialport, args2, nargout); else if (property == "timeout") return srlp_timeout (serialport, args2, nargout); else if (property == "userdata") return srlp_userdata (serialport, args2, nargout); else if (property == "terminator") return srlp_terminator (serialport, args2, nargout); // internals else if (property == "__flush__") return srlp_flush (serialport, args2, nargout); else if (property == "__break__") return srlp_break (serialport, args2, nargout); else if (property == "__pinstatus__") return srlp_pinstatus (serialport, args2, nargout); else if (property == "__requesttosend__") return srlp_requesttosend (serialport, args2, nargout); else if (property == "__dataterminalready__") return srlp_dataterminalready (serialport, args2, nargout); else (*current_liboctave_error_handler) ("wrong keyword"); #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the SERIAL interface"); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/__srlp_read__.cc��������������������������������������������0000644�0000000�0000000�00000005340�14743226261�020402� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include <octave/uint8NDArray.h> #include <errno.h> #include "serialport_class.h" #endif // PKG_ADD: autoload ("__srlp_read__", "serialport.oct"); DEFUN_DLD (__srlp_read__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } __srlp_read__ (@var{serial}, @var{n})\n \ \n\ Read from serialport interface.\n \ \n\ @subsubheading Inputs\n \ @var{serial} - instance of @var{octave_serialport} class.@*\ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ @subsubheading Outputs\n \ The __srlp_read__() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_SERIAL error("serial: Your system doesn't support the SERIAL interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_serialport::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 0; if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } buffer_len = args (1).int_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("__srlp_read__: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } octave_serialport* serial = NULL; const octave_base_value& rep = args (0).get_rep (); serial = &((octave_serialport &)rep); // Read data int bytes_read = serial->read (buffer, buffer_len); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data (dim_vector (1, bytes_read)); for (int i = 0; i < bytes_read; i++) data (i) = buffer[i]; return_list (0) = data; return_list (1) = bytes_read; return return_list; #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/__srlp_write__.cc�������������������������������������������0000644�0000000�0000000�00000005137�14743226261�020625� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include "serialport_class.h" #endif // PKG_ADD: autoload ("__srlp_write__", "serialport.oct"); DEFUN_DLD (__srlp_write__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } __srlp_write__ (@var{serial}, @var{data})\n \ \n\ Write data to a serialport interface.\n \ \n\ @subsubheading Inputs\n \ @var{serial} - instance of @var{octave_serialport} class.@*\ @var{data} - data to be written to the serialport interface. Can be either of String or uint8 type.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, __srlp_write__() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_SERIAL error ("serial: Your system doesn't support the SERIAL interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_serialport::static_type_id ()) { print_usage (); return octave_value (-1); } octave_serialport *serial = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); serial = &((octave_serialport &)rep); if (args (1).is_string ()) // String { retval = serial->write (args (1).string_value ()); } else if (args (1).is_uint8_type ()) // uint8_t { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("__srlp_write__: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = serial->write (buf, data.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport.cc�����������������������������������������������0000644�0000000�0000000�00000016165�14743226261�020026� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017-2020 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include <errno.h> #include <fcntl.h> #include "serialport_class.h" #endif // PKG_ADD: autoload ("serialport", "serialport.oct"); DEFUN_DLD (serialport, args, nargout, "-*- texinfo -*-\n \ @deftypefn {Loadable Function} {@var{serial} = } serialport ([@var{path}], [@var{baudrate}])\n \ @deftypefnx {Loadable Function} {@var{serial} = } serialport ([@var{path}], [@var{propname}, @var{propvalue}])\n \ \n\ Open serial port interface.\n \ \n\ @subsubheading Inputs\n \ @var{path} - the interface path of type String. @*\n \ @var{baudrate} - the baudrate of interface.@*\n \ @var{propname},@var{propvalue} - property name/value pairs.\n \ \n \ Known input properties:\n \ @table @asis\n \ @item BaudRate\n \ Numeric baudrate value\n \ @item Timeout\n \ Numeric timeout value in seconds or -1 to wait forever\n \ @item StopBits\n \ number of stopbits to use\n \ @item Parity\n \ Parity setting 'none', 'even', 'odd'\n \ @item DataBits\n \ Number of bits to a byte (5 to 8)\n \ @item FlowControl\n \ Number of bits to a byte 'none', 'hardware', 'software'\n \ @end table\n \ \n\ @subsubheading Outputs\n \ The serialport() shall return an instance of @var{octave_serialport} class as the result @var{serial}.\n \ \n \ @subsubheading Properties\n \ The serial object has the following public properties:\n \ @table @asis\n \ @item Name\n \ name assigned to the object\n \ @item Type\n \ instrument type 'serial' (readonly)\n \ @item Port\n \ OS specific port name (readonly)\n \ @item Status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item Timeout\n \ timeout value used for waiting for data\n \ @item NumBytesAvailable\n \ number of bytes currently available to read (readonly)\n \ @item NumBytesWritten\n \ number of bytes written (readonly)\n \ @item StopBits\n \ number of stopbits to use\n \ @item Parity\n \ Parity setting 'none', 'even', 'odd'\n \ @item DataBits\n \ Number of bits to a byte (5 to 8)\n \ @item BaudRate\n \ Baudrate setting\n \ @item FlowControl\n \ Number of bits to a byte 'none', 'hardware', 'software'\n \ @item PinStatus\n \ current state of pins (readonly)\n \ @item UserData\n \ user defined data\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_SERIAL error ("serial: Your system doesn't support the SERIAL interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values std::string path; unsigned int baud_rate = 115200; double timeout = -1; unsigned short databits = 8; std::string parity("N"); std::string flow("none"); unsigned short stopbits = 1; // Parse the function arguments if ((args.length () == 0) || !args (0).is_string ()) { print_usage (); return octave_value (); } path = args (0).string_value (); baud_rate = 115200; // baudrate if (args.length() == 2) { if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { baud_rate = args (1).int_value (); } else { print_usage (); return octave_value (); } } else if (args.length() > 2 && (args.length() & 1) == 0) { error ("Expected property name/value pairs"); return octave_value (); } else if (args.length() > 2) { // go through the properties for(int i=1;i<args.length();i+=2) { // first pair should be a property name if (! args (i).is_string ()) { error ("Expected property name string"); return octave_value (); } std::string name = args (i).string_value (); octave_value val = args (i+1); std::transform (name.begin (), name.end (), name.begin (), ::tolower); if (name == "baudrate") { if (val.OV_ISINTEGER () || val.OV_ISFLOAT ()) baud_rate = val.int_value (); else { error ("baudrate must be a integer"); return octave_value(); } } else if (name == "timeout") { if (val.OV_ISINTEGER () || val.OV_ISFLOAT ()) timeout = val.double_value (); else { error ("timeout must be a integer or double"); return octave_value(); } } else if (name == "databits") { if (val.OV_ISINTEGER () || val.OV_ISFLOAT ()) databits = val.int_value (); else { error ("databits must be a integer"); return octave_value(); } } else if (name == "stopbits") { if (val.OV_ISINTEGER () || val.OV_ISFLOAT ()) stopbits = val.int_value (); else { error ("databits must be a integer"); return octave_value(); } } else if (name == "parity") { if (val.is_string ()) parity = val.string_value (); else { error ("parity must be a string"); return octave_value(); } } else if (name == "flowcontrol") { if (val.is_string ()) flow = val.string_value (); else { error ("flowcontrol must be a string"); return octave_value(); } } else { error ("unknown property '%s'", name.c_str()); return octave_value(); } } } octave_serialport* retval = new octave_serialport (); // Open the interface retval->open (path); retval->set_baudrate (baud_rate); retval->set_timeout (timeout); retval->set_parity (parity); retval->set_flowcontrol (flow); retval->set_databits (databits); retval->set_stopbits (stopbits); //retval->flush (2); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "serial")) %! fail ("a = serialport ()", "Invalid call to serial"); %! fail ("a = serialport ('noport', 'a')", "Invalid call to serial"); %! fail ("a = serialport ('noport', 9600, 1)", "Expected property name string"); %! fail ("a = serialport ('noport', 9600, 1, 1)", "Expected property name/value pairs"); %! else %! fail ("serialport ()", "serial: Your system doesn't support the serial interface"); %! endif #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport_class.cc�����������������������������������������0000644�0000000�0000000�00000014061�14743226261�021204� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019-2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include "serialport_class.h" #include <octave/Matrix.h> #include <string> #include <algorithm> octave_serialport_common::octave_serialport_common () : fieldnames(13) { byteswritten = 0; userData = Matrix (); interminator = octave_value("lf"); outterminator = octave_value("lf"); byteOrder = "little-endian"; fieldnames[0] = "BaudRate"; fieldnames[1] = "DataBits"; fieldnames[3] = "Parity"; fieldnames[4] = "StopBits"; fieldnames[5] = "Timeout"; fieldnames[6] = "NumBytesAvailable"; fieldnames[7] = "NumBytesWritten"; fieldnames[8] = "Port"; fieldnames[9] = "FlowControl"; fieldnames[10] = "UserData"; fieldnames[11] = "ByteOrder"; fieldnames[12] = "Terminator"; } bool octave_serialport_common::has_property(const std::string &name) const { for (octave_idx_type i=0; i<fieldnames.numel(); i++) { if (fieldnames[i] == name) return true; } return false; } octave_value_list octave_serialport_common::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_serialport object cannot be indexed with %c", type[0]); return retval; case '.': { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } else { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__srlp_properties__"), ovl, 1); } } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_serialport_common::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_serialport object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { std::string property = (idx.front ()) (0).string_value (); if (! has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } else { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__srlp_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); } OV_COUNT++; retval = octave_value (this); } else { error ("octave_serialport invalid index"); } } return retval; } int octave_serialport_common::set_byteorder(const std::string& neworder) { std::string order = neworder; std::transform (order.begin (), order.end (), order.begin (), ::tolower); if (order == "big" || order == "big-endian") byteOrder = "big-endian"; else if (order == "little" || order == "little-endian") byteOrder = "little-endian"; else error ("octave_serialport invalid byteorder"); return 1; } int octave_serialport_common::set_input_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_serialport invalid input terminator"); else interminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_serialport invalid input terminator"); } else { interminator = octave_value(x); } } else error ("octave_serialport invalid input terminator"); return 1; } int octave_serialport_common::set_output_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_serialport invalid output terminator"); else outterminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_serialport invalid output terminator"); } else { outterminator = octave_value(x); } } else error ("octave_serialport invalid output terminator"); return 1; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport_class.h������������������������������������������0000644�0000000�0000000�00000013164�14743226261�021051� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef SERIALPORT_CLASS_H #define SERIALPORT_CLASS_H #include <octave/oct.h> #include <string> #define BITMASK_SET(x,y) ((x) |= (y)) #define BITMASK_CLEAR(x,y) ((x) &= (~(y))) #define BITMASK_TOGGLE(x,y) ((x) ^= (y)) #define BITMASK_CHECK(x,y) ((x) & (y)) #define BITMASK_CHECK_VALUE(x,y,z) (((x) & (y)) == (z)) #define CONCAT2X(x,y) x ## y #define CONCAT2(x,y) CONCAT2X(x,y) #define BINOPDECL(name, a1, a2) \ static octave_value \ CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) #define CAST_BINOP_ARGS(t1, t2) \ t1 v1 = dynamic_cast<t1> (a1); \ t2 v2 = dynamic_cast<t2> (a2) #define DEFBINOP_CLASS_OP(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \ return octave_value \ (&v1 op &v2); \ } #ifdef OCTAVE__NEW_REGISTER_OP #define INSTALL_BINOP(op, t1, t2, f) \ {octave::type_info& ti = octave::interpreter::the_interpreter ()->get_type_info (); \ ti.register_binary_op \ (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ CONCAT2(oct_binop_, f));} #else #define INSTALL_BINOP(op, t1, t2, f) \ octave_value_typeinfo::register_binary_op \ (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ CONCAT2(oct_binop_, f)); #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_serialport_common : public OCTAVE_BASE_CLASS { protected: octave_serialport_common(); bool has_property(const std::string &name) const; public: // os dependent functions virtual bool fd_is_valid() const = 0; virtual double get_timeout() const = 0; virtual int get_baudrate() const = 0; virtual int get_databits() const = 0; virtual std::string get_parity() const = 0; virtual int get_stopbits() const = 0; virtual int get_numbytesavailable() const = 0; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true;} // 4.4+ bool isobject (void) const { return true;} octave_base_value * unique_clone (void) { OV_COUNT++; return this;} // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } void print (std::ostream& os, bool pr_as_read_syntax = false) { print_raw(os, pr_as_read_syntax); newline(os); } void print (std::ostream& os, bool pr_as_read_syntax = false) const { print_raw(os, pr_as_read_syntax); newline(os); } void print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " Serial Port Object " << this->get_name(); newline(os); //os << " status: " << this->get_status(); newline(os); if (this->fd_is_valid()) { os << " Port: " << this->portPath; newline(os); os << " BaudRate: " << this->get_baudrate(); newline(os); os << " Parity: " << this->get_parity(); newline(os); os << " DataBits: " << this->get_databits(); newline(os); os << " StopBits: " << this->get_stopbits(); newline(os); os << " Timeout: " << this->get_timeout(); newline(os); //os << "Mode: " << blockmode; newline(os); } } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); std::string get_type () const { return "serialport"; } std::string get_port () const { return portPath; } std::string get_name () const { return name; } void set_name (const std::string &newname) { name = newname; } unsigned long get_numbyteswritten() const { return byteswritten; } octave_value get_userdata () const { return userData; } void set_userdata (const octave_value &newv) { userData = newv; } int set_byteorder(const std::string& /* order */); std::string get_byteorder() const { return byteOrder; } int set_input_terminator(const octave_value& /* term */); int set_output_terminator(const octave_value& /* term */); octave_value get_input_terminator() const { return interminator; } octave_value get_output_terminator() const { return outterminator; } protected: string_vector fieldnames; unsigned long byteswritten; std::string name; std::string portPath; std::string byteOrder; octave_value interminator; octave_value outterminator; octave_value userData; }; #ifdef __WIN32__ #include "serialport_class_win32.h" #else #include "serialport_class_lin.h" #endif #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport_class_lin.cc�������������������������������������0000644�0000000�0000000�00000042170�14743226261�022050� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #include <iostream> #include <string> #include <algorithm> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <unistd.h> #include "serialport_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_serialport, "octave_serialport", "octave_serialport"); octave_serialport::octave_serialport (void) : fd (-1) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } } void octave_serialport::open (const std::string &path) { int flags = O_RDWR | O_NOCTTY | O_SYNC | O_NDELAY; // O_SYNC - All writes immediately effective, no buffering // O_NOCTTY - Do not make serialport terminal the controlling terminal for the process // O_NDELAY - Do not care what state the DCD signal line is in. Used for open only, later disabled. fd = ::open (path.c_str (), flags); portPath = path; name = "Serial-" + portPath; if (fd_is_valid ()) { // Check whether fd is an open file descriptor referring to a terminal if(! isatty (fd)) { error("serialport: Interface does not refer to a terminal: %s\n", strerror (errno)); octave_serialport::close (); return; } if (tcgetattr (fd, &config) < 0) { error ("serialport: Failed to get terminal attributes: %s\n", strerror (errno)); octave_serialport::close (); return; } // Clear all settings config.c_iflag = 0; // Input modes config.c_oflag = 0; // Output modes config.c_cflag = CS8 | CREAD | CLOCAL; // Control modes, 8n1 config.c_lflag = 0; // Local modes config.c_cc[VMIN] = 0; config.c_cc[VTIME] = 5; // set an intial baudrate cfsetospeed (&config, B9600); cfsetispeed (&config, B9600); if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport: Failed to set default terminal attributes: %s\n", strerror (errno)); octave_serialport::close (); return; } // Disable NDELAY if (fcntl (fd, F_SETFL, 0) < 0) { error ("serialport: Failed to disable NDELAY flag: %s\n", strerror (errno)); octave_serialport::close (); return; } timeout = -1; blocking_read = true; } else { error ("serialport: Error opening the interface: %s\n", strerror (errno)); return; } } octave_serialport::~octave_serialport (void) { octave_serialport::close(); } int octave_serialport::read (uint8_t *buf, unsigned int len) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; double maxwait = timeout; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; read_retval = ::read (fd, (void *)(buf + bytes_read), len - bytes_read); if (read_retval < 0) { error ("serialport: Error while reading: %s\n", strerror (errno)); break; } bytes_read += read_retval; // Timeout while in non-blocking mode if (read_retval == 0 && !blocking_read) { // no waiting if (config.c_cc[VTIME] == 0) break; maxwait -= (double)config.c_cc[VTIME]/10.0; // actual timeout if (maxwait <= 0) break; } } return bytes_read; } int octave_serialport::write (const std::string &str) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } int ret = ::write (fd, str.c_str (), str.length ()); if (ret > 0) byteswritten += ret; return ret; } int octave_serialport::write(uint8_t *buf, unsigned int len) { if (!fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } int ret = ::write (fd, buf, len); if (ret > 0) byteswritten += ret; return ret; } int octave_serialport::set_timeout (double newtimeout) { if (! fd_is_valid ()) { error("serialport: Interface must be opened first..."); return -1; } if (newtimeout < -1) { error("serialport: timeout value must be between -1 or greater"); return -1; } timeout = newtimeout; // into 10ths of a second newtimeout *= 10; // Disable custom timeout, enable blocking read if (newtimeout < 0) { blocking_read = true; newtimeout = 5; } // Enable custom timeout, disable blocking read else { blocking_read = false; if(newtimeout > 5) newtimeout = 5; } if (config.c_cc[VTIME] != (unsigned char) newtimeout) { config.c_cc[VMIN] = 0; config.c_cc[VTIME] = (unsigned char) newtimeout; if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport: error setting timeout..."); return -1; } } return 1; } double octave_serialport::get_timeout (void) const { if (blocking_read) return -1; else return timeout; } int octave_serialport::set_stopbits (unsigned short stopbits) { if (!fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } /* * CSTOPB Send two stop bits, else one. */ if (stopbits == 1) { // Set to one stop bit BITMASK_CLEAR (config.c_cflag, CSTOPB); } else if (stopbits == 2) { // Set to two stop bits BITMASK_SET (config.c_cflag, CSTOPB); } else { error ("serialport: Only 1 or 2 stop bits are supported..."); return false; } if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport: error setting stop bits: %s\n", strerror (errno)); return false; } return true; } int octave_serialport::get_stopbits (void) const { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } if (BITMASK_CHECK (config.c_cflag, CSTOPB)) return 2; else return 1; } int octave_serialport::set_databits (unsigned short bytesize) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } tcflag_t c_bytesize = 0; switch (bytesize) { case 5: c_bytesize = CS5; break; case 6: c_bytesize = CS6; break; case 7: c_bytesize = CS7; break; case 8: c_bytesize = CS8; break; default: error ("serialport.databits: expecting value between [5..8]..."); return false; } // Clear bitmask CSIZE BITMASK_CLEAR (config.c_cflag, CSIZE); // Apply new BITMASK_SET (config.c_cflag, c_bytesize); if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport.databits: error setting data size: %s\n", strerror (errno)); return false; } return true; } int octave_serialport::get_databits (void) const { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } int retval = -1; if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS5)) retval = 5; else if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS6)) retval = 6; else if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS7)) retval = 7; else if (BITMASK_CHECK_VALUE (config.c_cflag, CSIZE, CS8)) retval = 8; return retval; } int octave_serialport::set_baudrate (unsigned int baud) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } speed_t baud_rate = 0; switch (baud) { case 0: baud_rate = B0; break; case 50: baud_rate = B50; break; case 75: baud_rate = B75; break; case 110: baud_rate = B110; break; case 134: baud_rate = B134; break; case 150: baud_rate = B150; break; case 200: baud_rate = B200; break; case 300: baud_rate = B300; break; case 600: baud_rate = B600; break; case 1200: baud_rate = B1200; break; case 1800: baud_rate = B1800; break; case 2400: baud_rate = B2400; break; case 4800: baud_rate = B4800; break; case 9600: baud_rate = B9600; break; case 19200: baud_rate = B19200; break; case 38400: baud_rate = B38400; break; #ifdef B57600 case 57600: baud_rate = B57600; break; #endif #ifdef B115200 case 115200: baud_rate = B115200; break; #endif #ifdef B230400 case 230400: baud_rate = B230400; break; #endif #ifdef B460800 case 460800: baud_rate = B460800; break; #endif #ifdef B500000 case 500000: baud_rate = B500000; break; #endif #ifdef B576000 case 576000: baud_rate = B576000; break; #endif #ifdef B921600 case 921600: baud_rate = B921600; break; #endif #ifdef B1000000 case 1000000: baud_rate = B1000000; break; #endif #ifdef B1152000 case 1152000: baud_rate = B1152000; break; #endif #ifdef B2000000 case 2000000: baud_rate = B2000000; break; #endif #ifdef B3000000 case 3000000: baud_rate = B3000000; break; #endif #ifdef B3500000 case 3500000: baud_rate = B3500000; break; #endif #ifdef B4000000 case 4000000: baud_rate = B4000000; break; #endif default: error ("serialport: baud rate not supported..."); return false; } cfsetospeed (&config, baud_rate); cfsetispeed (&config, baud_rate); if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport: error setting baud rate: %s\n", strerror (errno)); return false; } return true; } int octave_serialport::get_baudrate (void) const { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } int retval = -1; speed_t baudrate = cfgetospeed (&config); if (baudrate == B0) retval = 0; else if (baudrate == B50) retval = 50; else if (baudrate == B75) retval = 75; else if (baudrate == B110) retval = 110; else if (baudrate == B134) retval = 134; else if (baudrate == B150) retval = 150; else if (baudrate == B200) retval = 200; else if (baudrate == B300) retval = 300; else if (baudrate == B600) retval = 600; else if (baudrate == B1200) retval = 1200; else if (baudrate == B1800) retval = 1800; else if (baudrate == B2400) retval = 2400; else if (baudrate == B4800) retval = 4800; else if (baudrate == B9600) retval = 9600; else if (baudrate == B19200) retval = 19200; else if (baudrate == B38400) retval = 38400; else if (baudrate == B57600) retval = 57600; else if (baudrate == B115200) retval = 115200; else if (baudrate == B230400) retval = 230400; return retval; } int octave_serialport::flush (unsigned short queue_selector) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } /* * TCIOFLUSH Flush both pending input and untransmitted output. * TCOFLUSH Flush untransmitted output. * TCIFLUSH Flush pending input. */ int flag; switch (queue_selector) { case 0: flag = TCOFLUSH; break; case 1: flag = TCIFLUSH; break; case 2: flag = TCIOFLUSH; break; default: error("serialport: only [0..2] values are accepted..."); return false; } return ::tcflush (fd, flag); } int octave_serialport::sendbreak (unsigned short ms) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } return ::tcsendbreak (fd, ms); } int octave_serialport::set_parity (const std::string &newparity) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } // Convert string to lowercase std::string parity = newparity; std::transform (parity.begin (), parity.end (), parity.begin (), ::tolower); /* * PARENB Enable parity generation on output and parity checking for input. * PARODD If set, then parity for input and output is odd; otherwise even parity is used. */ if (parity == "n" || parity == "none") { // Disable parity generation/checking BITMASK_CLEAR (config.c_cflag, PARENB); } else if (parity == "e" || parity == "even") { // Enable parity generation/checking BITMASK_SET (config.c_cflag, PARENB); // Set to Even BITMASK_CLEAR (config.c_cflag, PARODD); } else if (parity == "o" || parity == "odd") { // Enable parity generation/checking BITMASK_SET (config.c_cflag, PARENB); // Set to Odd BITMASK_SET (config.c_cflag, PARODD); } else { error ("serialport: Only [N]one, [E]ven or [O]dd parities are supported..."); return false; } if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport: error setting parity: %s\n", strerror (errno)); return false; } return true; } std::string octave_serialport::get_parity (void) const { if (!BITMASK_CHECK (config.c_cflag, PARENB)) return "None"; else if (BITMASK_CHECK (config.c_cflag, PARODD)) return "Odd"; else return "Even"; } int octave_serialport::set_flowcontrol (const std::string &newctrl) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } // Convert string to lowercase std::string ctrl = newctrl; std::transform (ctrl.begin (), ctrl.end (), ctrl.begin (), ::tolower); if (ctrl == "n" || ctrl == "none") { BITMASK_CLEAR (config.c_iflag, IXON | IXOFF | IXANY); #ifdef CNEW_RTSCTS BITMASK_CLEAR (config.c_cflag, CNEW_RTSCTS); #else BITMASK_CLEAR (config.c_cflag, CRTSCTS); #endif } else if (ctrl == "h" || ctrl == "hardware") { BITMASK_CLEAR (config.c_iflag, IXON | IXOFF | IXANY); #ifdef CNEW_RTSCTS BITMASK_SET (config.c_cflag, CNEW_RTSCTS); #else BITMASK_SET (config.c_cflag, CRTSCTS); #endif } else if (ctrl == "s" || ctrl == "software") { BITMASK_CLEAR (config.c_iflag, IXANY); BITMASK_SET (config.c_iflag, IXON | IXOFF); #ifdef CNEW_RTSCTS BITMASK_CLEAR (config.c_cflag, CNEW_RTSCTS); #else BITMASK_CLEAR (config.c_cflag, CRTSCTS); #endif } else { error ("serialport.flowcontrol: Only [N]one, [s]software or [h]hardware flow contols are supported..."); return false; } if (tcsetattr (fd, TCSANOW, &config) < 0) { error ("serialport.flowcontrol: error setting parity: %s\n", strerror (errno)); return false; } return true; } std::string octave_serialport::get_flowcontrol (void) const { #ifdef CNEW_RTSCTS if (BITMASK_CHECK (config.c_cflag, CNEW_RTSCTS)) #else if (BITMASK_CHECK (config.c_cflag, CRTSCTS)) #endif return "hardware"; else if (BITMASK_CHECK (config.c_iflag, IXON | IXOFF | IXANY)) return "software"; else return "none"; } void octave_serialport::get_control_line_status (void) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return; } ioctl (fd, TIOCMGET, &status); } bool octave_serialport::get_control_line (const std::string &control_signal) { get_control_line_status (); if (control_signal == "DTR") return (status & TIOCM_DTR); else if (control_signal == "RTS") return (status & TIOCM_RTS); else if (control_signal == "CTS") return (status & TIOCM_CTS); else if (control_signal == "DSR") return (status & TIOCM_DSR); else if (control_signal == "CD") return (status & TIOCM_CD); else if (control_signal == "RI") return (status & TIOCM_RI); error ("serialport: Unknown control signal..."); return false; } void octave_serialport::set_control_line (const std::string &control_signal, bool set) { get_control_line_status (); int signal; if (control_signal == "DTR") signal = TIOCM_DTR; else if (control_signal == "RTS") signal = TIOCM_RTS; else { error ("serialport: Unknown control signal..."); return; } if (set) status |= signal; else status &= ~signal; ioctl (fd, TIOCMSET, &status); } bool octave_serialport::fd_is_valid (void) const { return (fd >= 0); } void octave_serialport::close (void) { if (fd_is_valid ()) { ::close (fd); fd = -1; } } int octave_serialport::get_numbytesavailable (void) const { int available = 0; if (fd_is_valid ()) { ioctl (fd, FIONREAD, &available); } return available; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport_class_lin.h��������������������������������������0000644�0000000�0000000�00000004153�14743226261�021711� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef SERIALPORT_CLASS_LIN_H #define SERIALPORT_CLASS_LIN_H #include <string> #include <termios.h> class octave_serialport : public octave_serialport_common { public: octave_serialport(void); ~octave_serialport(void); int write(const std::string& /* buffer */); int write(uint8_t* /* buffer */, unsigned int /* buffer size */); int read(uint8_t* /* buffer */, unsigned int /* buffer size */); void open(const std::string& /* path */); void close(void); int flush(unsigned short /* stream select */); int sendbreak(unsigned short /* ms */); int set_timeout(double /* timeout */); double get_timeout(void) const; int set_baudrate(unsigned int /* baudrate */); int get_baudrate(void) const; int set_databits(unsigned short /* size */); int get_databits(void) const; int set_parity(const std::string& /* parity */); std::string get_parity() const; int set_flowcontrol(const std::string& /* flow */); std::string get_flowcontrol() const; int set_stopbits(unsigned short /* stop bits */); int get_stopbits(void) const; bool get_control_line(const std::string &); void set_control_line(const std::string &, bool); int get_numbytesavailable(void) const; private: int fd; int status; struct termios config; double timeout; volatile bool blocking_read; void get_control_line_status(void); bool fd_is_valid(void) const; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport_class_win32.cc�����������������������������������0000644�0000000�0000000�00000033557�14743226261�022241� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SERIAL #if HAVE_OCTAVE_LO_SYSDEP_H #include <octave/lo-sysdep.h> #endif #include <iostream> #include <string> #include <algorithm> using std::string; #include "serialport_class.h" std::string winerror () { DWORD e; e = GetLastError (); #if HAVE_OCTAVE_U8_TO_WSTRING wchar_t errstring[100+1]; if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errstring, 100, 0) == 0) { errstring[0] = '\0'; } return octave::sys::u8_from_wstring (errstring); #else char errstring[100+1]; if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errstring, 100, 0) == 0) { errstring[0] = '\0'; } return errstring; #endif } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_serialport, "octave_serialport", "octave_serialport"); octave_serialport::octave_serialport(void) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } fd = INVALID_HANDLE_VALUE; } void octave_serialport::open (const std::string &path) { portPath = path; name = "Serial-" + path; // use full extended port names if not already specified std::string fullPath = path; if (fullPath.length() > 0 && fullPath[0] != '\\') fullPath = "\\\\.\\" + path; fd = CreateFile(fullPath.c_str (), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (! fd_is_valid()) { error("serialport: Error opening the interface: %s\n", winerror ().c_str ()); return; } // clear any errors that may be on the port COMSTAT stats; DWORD err; ClearCommError (fd, &err, &stats); // Clean the configuration struct (DCB) memset (&config, 0, sizeof (config)); // set up device settings config.DCBlength = sizeof (config); if(GetCommState (fd, &config) == FALSE) { error ("serialport: Failed to get terminal attributes: %s\n", winerror ().c_str ()); octave_serialport::close (); return; } timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; timeout = -1; if (SetCommTimeouts(fd, &timeouts) == FALSE) { error ("serialport: Failed to disable timeouts: %s\n", winerror ().c_str ()); octave_serialport::close (); return; } return; } octave_serialport::~octave_serialport(void) { octave_serialport::close(); } int octave_serialport::read(uint8_t *buf, unsigned int len) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; double maxwait = timeout; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; DWORD readsz; read_retval = -1; if (ReadFile (fd, (buf + bytes_read), len - bytes_read, &readsz, NULL) == TRUE) { read_retval = readsz; } if(read_retval < 0) { error ("serialport.read: Error while reading: %s\n", winerror ().c_str ()); break; } bytes_read += read_retval; if (read_retval == 0 && !blocking_read) { maxwait -= (double)timeouts.ReadTotalTimeoutConstant/1000.0; // actual timeout if (maxwait <= 0) break; } } return bytes_read; } int octave_serialport::write (const std::string & str) { if (! fd_is_valid ()) { error("serialport: Interface must be opened first..."); return -1; } int wrote_ret = -1; DWORD wrote; if (WriteFile (fd, str.c_str (), str.length (), &wrote, NULL) == TRUE) { wrote_ret = wrote; byteswritten += wrote; } return wrote_ret; } int octave_serialport::write (uint8_t *buf, unsigned int len) { if (! fd_is_valid ()) { error("serialport: Interface must be opened first..."); return -1; } int wrote_ret = -1; DWORD wrote; if (WriteFile (fd, buf, len, &wrote, NULL) == TRUE) { wrote_ret = wrote; byteswritten += wrote; } return wrote_ret; } int octave_serialport::set_timeout (double newtimeout) { if (! fd_is_valid()) { error ("serialport: Interface must be opened first..."); return -1; } if (newtimeout < -1 || newtimeout > 255) { error ("serialport: timeout value must be between [-1..255]..."); return -1; } timeout = newtimeout; newtimeout *= 1000; // Disable custom timeout, enable blocking read if (newtimeout < 0) { blocking_read = true; newtimeout = 50; } // Enable custom timeout, disable blocking read else { blocking_read = false; if (newtimeout > 50) newtimeout = 50; } timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = newtimeout; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (SetCommTimeouts (fd, &timeouts) == FALSE) { error ("serialport.timeout: error setting timeout..."); return -1; } return 1; } double octave_serialport::get_timeout (void) const { if (blocking_read) return -1; else return timeout; } int octave_serialport::set_stopbits (unsigned short stopbits) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } if (stopbits == 1) { // Set to one stop bit config.StopBits = ONESTOPBIT; } else if (stopbits == 2) { // Set to two stop bits config.StopBits = TWOSTOPBITS; } else { error ("serialport: Only 1 or 2 stop bits are supported..."); return false; } if (SetCommState (fd,&config) == FALSE) { error ("serialport: error setting stop bits: %s\n", winerror ().c_str ()); return false; } return true; } int octave_serialport::get_stopbits (void) const { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } if (config.StopBits == TWOSTOPBITS) return 2; else return 1; } int octave_serialport::set_databits (unsigned short bytesize) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } if(bytesize < 5 || bytesize > 8) { error ("serialport.databits: expecting value between [5..8]..."); return false; } config.ByteSize = bytesize; if (SetCommState (fd, &config) == FALSE) { error ("serialport: error setting data size: %s\n", winerror ().c_str ()); return false; } return true; } int octave_serialport::get_databits (void) const { if (! fd_is_valid ()) { error("serialport: Interface must be opened first..."); return -1; } return config.ByteSize; } int octave_serialport::set_baudrate (unsigned int baud) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } DWORD old_baud = config.BaudRate; config.BaudRate = baud; if (SetCommState (fd, &config) == FALSE) { error ("serialport: error setting baud rate: %s\n", winerror ().c_str ()); config.BaudRate = old_baud; return false; } return true; } int octave_serialport::get_baudrate (void) const { if (! fd_is_valid ()) { error("serialport: Interface must be opened first..."); return -1; } return config.BaudRate; } int octave_serialport::flush (unsigned short queue_selector) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } int flag; switch (queue_selector) { case 0: flag = PURGE_TXCLEAR; break; case 1: flag = PURGE_RXCLEAR; break; case 2: flag = PURGE_RXCLEAR|PURGE_TXCLEAR; break; default: error ("serialport: only [0..2] values are accepted..."); return false; } if (PurgeComm (fd,flag) == FALSE) return -1; else return true; } int octave_serialport::sendbreak (unsigned short ms) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } if (ms > 5000) ms = 5000; if(SetCommBreak(fd) == TRUE) { Sleep(ms); ClearCommBreak(fd); return true; } return false; } int octave_serialport::set_parity (const std::string &newparity) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } // Convert string to lowercase std::string parity = newparity; std::transform (parity.begin (), parity.end (), parity.begin (), ::tolower); /* * PARENB Enable parity generation on output and parity checking for input. * PARODD If set, then parity for input and output is odd; otherwise even parity is used. */ if (parity == "n" || parity == "none") { // Disable parity generation/checking config.Parity = NOPARITY; } else if (parity == "e" || parity == "even") { // Enable parity generation/checking config.Parity = EVENPARITY; } else if (parity == "o" || parity == "odd") { config.Parity = ODDPARITY; } else { error ("serialport: Only [N]one, [E]ven or [O]dd parities are supported..."); return false; } if (SetCommState (fd, &config) == FALSE) { error ("serialport: error setting parity: %s\n", winerror ().c_str ()); return false; } return true; } std::string octave_serialport::get_parity (void) const { if(config.Parity == NOPARITY) return "None"; else if(config.Parity == ODDPARITY) return "Odd"; else return "Even"; } int octave_serialport::set_flowcontrol (const std::string &newctrl) { if (! fd_is_valid ()) { error ("serialport: Interface must be opened first..."); return -1; } // Convert string to lowercase std::string ctrl = newctrl; std::transform (ctrl.begin (), ctrl.end (), ctrl.begin (), ::tolower); if (ctrl == "n" || ctrl == "none") { config.fDtrControl = DTR_CONTROL_ENABLE; config.fRtsControl = RTS_CONTROL_ENABLE; config.fOutxCtsFlow = 0; config.fOutxDsrFlow = 0; config.fOutX = 0; config.fInX = 0; } else if (ctrl == "h" || ctrl == "hardware") { config.fDtrControl = DTR_CONTROL_ENABLE; config.fRtsControl = RTS_CONTROL_HANDSHAKE; config.fOutxCtsFlow = 1; config.fOutxDsrFlow = 0; config.fOutX = 0; config.fInX = 0; } else if (ctrl == "s" || ctrl == "software") { config.fDtrControl = DTR_CONTROL_ENABLE; config.fRtsControl = RTS_CONTROL_ENABLE; config.fOutxCtsFlow = 0; config.fOutxDsrFlow = 0; config.fOutX = 1; config.fInX = 1; } else { error ("serialport.flowcontrol: Only [N]one, [s]software or [h]hardware flow contols are supported..."); return false; } return true; } std::string octave_serialport::get_flowcontrol (void) const { if (config.fOutxCtsFlow == 1) return "hardware"; else if (config.fOutX == 1) return "software"; else return "none"; } void octave_serialport::get_control_line_status (void) { if (! fd_is_valid()) { error ("serialport: Interface must be opened first..."); return; } GetCommState (fd, &config); GetCommModemStatus (fd, &status); } bool octave_serialport::get_control_line (const std::string &control_signal) { get_control_line_status (); if (control_signal == "DTR") return (config.fDtrControl == DTR_CONTROL_ENABLE); else if (control_signal == "RTS") return (config.fRtsControl == RTS_CONTROL_ENABLE); else if (control_signal == "CTS") return (status & MS_CTS_ON); else if (control_signal == "DSR") return (status & MS_DSR_ON); else if (control_signal == "CD") return (status & MS_RLSD_ON); else if (control_signal == "RI") return (status & MS_RING_ON); else error("serialport: Unknown control signal..."); return false; } void octave_serialport::set_control_line (const std::string &control_signal, bool set) { get_control_line_status (); int signal; if (control_signal == "DTR") { if(set) config.fDtrControl = DTR_CONTROL_ENABLE; else config.fDtrControl = DTR_CONTROL_DISABLE; } else if (control_signal == "RTS") { if(set) config.fRtsControl = RTS_CONTROL_ENABLE; else config.fRtsControl = RTS_CONTROL_DISABLE; } else { error("serialport: Unknown control signal..."); return; } SetCommState (fd, &config); } bool octave_serialport::fd_is_valid (void) const { return (fd != INVALID_HANDLE_VALUE); } void octave_serialport::close (void) { if (fd_is_valid ()) { CloseHandle(fd); fd = INVALID_HANDLE_VALUE; } } int octave_serialport::get_numbytesavailable (void) const { int available = 0; if (fd_is_valid ()) { COMSTAT stats; DWORD err; if (ClearCommError (fd, &err, &stats)) available = stats.cbInQue; } return available; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/serialport/serialport_class_win32.h������������������������������������0000644�0000000�0000000�00000004316�14743226261�022072� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef SERIALPORT_CLASS_WIN32_H #define SERIALPORT_CLASS_WIN32_H #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #include <string> class octave_serialport : public octave_serialport_common { public: octave_serialport(void); ~octave_serialport(void); int write(const std::string& /* buffer */); int write(uint8_t* /* buffer */, unsigned int /* buffer size */); int read(uint8_t* /* buffer */, unsigned int /* buffer size */); void open(const std::string& /* path */); void close(void); int flush(unsigned short /* stream select */); int sendbreak(unsigned short /* breaktime */); int set_timeout(double /* timeout */); double get_timeout(void) const; int set_baudrate(unsigned int /* baudrate */); int get_baudrate() const; int set_databits(unsigned short /* bytesize */); int get_databits(void) const; int set_parity(const std::string& /* parity */); std::string get_parity(void) const; int set_flowcontrol(const std::string& /* flow */); std::string get_flowcontrol() const; int set_stopbits(unsigned short /* stop bits */); int get_stopbits(void) const; bool get_control_line(const std::string &); void set_control_line(const std::string&, bool); int get_numbytesavailable(void) const; private: HANDLE fd; DWORD status; DCB config; COMMTIMEOUTS timeouts; volatile bool blocking_read; double timeout; void get_control_line_status(void); bool fd_is_valid(void) const; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/�������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013731� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/Makefile.in��������������������������������������������������������0000644�0000000�0000000�00000000331�14743226261�015773� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../spi.oct OBJ := spi.o spi_close.o spi_write.o spi_read.o spi_writeAndRead.o spi_class.o __spi_pkg_lock__.o __spi_properties__.o LFLAGS = $(LIBS) CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/__spi_pkg_lock__.cc������������������������������������������������0000644�0000000�0000000�00000002751�14743226261�017505� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__spi_pkg_lock__", "spi.oct"); // PKG_ADD: __spi_pkg_lock__(1); // PKG_DEL: __spi_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__spi_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__spi_pkg_lock__")) interp.munlock("__spi_pkg_lock__"); } return retval; } #else DEFUN_DLD(__spi_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �����������������������instrument-control-0.9.4/src/spi/__spi_properties__.cc����������������������������������������������0000644�0000000�0000000�00000006132�14743226261�020105� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_SPI # include "spi_class.h" #endif // PKG_ADD: autoload ("__spi_properties__", "spi.oct"); DEFUN_DLD (__spi_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __spi_properties__ (@var{octave_spi}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_SPI if (args.length () < 2 || args.length () > 3 || args(0).type_id () != octave_spi::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_spi* spi = &((octave_spi &)rep); std::string property = args(1).string_value (); if (args.length () == 2) // get { if (property == "name") return octave_value (spi->get_name ()); else if (property == "bitrate") return octave_value (spi->get_bitrate ()); else if (property == "clockpolarity") return octave_value (spi->get_clockpolarity ()); else if (property == "clockphase") return octave_value (spi->get_clockphase ()); else if (property == "status") return octave_value (spi->get_status ()); else if (property == "port") return octave_value (spi->get_port ()); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (spi->set_name (args(2).string_value ())); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "bitrate") return octave_value (spi->set_bitrate (args(2).int_value ())); else if (property == "clockpolarity") return octave_value (spi->set_clockpolarity (args(2).string_value ())); else if (property == "clockphase") return octave_value (spi->set_clockphase (args(2).string_value ())); else if (property == "port") (*current_liboctave_error_handler) ("can not set this property"); else (*current_liboctave_error_handler) ("invalid property name"); } #else /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the SPI interface"); #endif return octave_value(); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi.cc�������������������������������������������������������������0000644�0000000�0000000�00000012313�14743226261�015033� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SPI #include <fcntl.h> #include "spi_class.h" #endif // PKG_ADD: autoload ("spi", "spi.oct"); DEFUN_DLD (spi, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{spi} = } spi ([@var{port_path}])\n \ @deftypefnx {Loadable Function} {@var{spi} = } spi ([@var{port_path}], [@var{propname}, @var{propvalue}])\n \ \n\ Open a spi interface.\n \ \n\ @subsubheading Inputs\n \ @var{port_path} - the interface device port/path of type String. If omitted defaults to \n \ '/dev/spi-0'. @*\n \ @var{propname},@var{propvalue} - property name/value pairs.\n \ \n\ Known input properties:\n \ @table @asis\n \ @item name\n \ Name of the object\n \ @item bitrate\n \ Numeric bitrate value\n \ @item clockpolarity\n \ Clock polarity: idlehigh or idlelow.\n \ @item clockphase\n \ Clock phase value: firstedge or secondedge\n \ @end table\n \ \n\ @subsubheading Outputs\n \ @var{spi} - An instance of @var{octave_spi} class.\n \ \n\ @subsubheading Properties\n \ The spi object has the following properties:\n \ @table @asis\n \ @item name\n \ Name of the object\n \ @item status\n \ Open or closed status of object (readonly).\n \ @item bitrate\n \ Numeric bitrate value\n \ @item clockpolarity\n \ Clock polarity: idlehigh or idlelow.\n \ @item clockphase\n \ Clock phase value: firstedge or secondedge\n \ @item port\n \ The interface driver port (readonly)\n \ @end table\n \ @end deftypefn") { #ifndef BUILD_SPI error ("spi: Your system doesn't support the SPI interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values int oflags = O_RDWR; std::string path ("/dev/spi-0"); unsigned int bitrate = 0; std::string polarity = ""; std::string phase = ""; std::string objname = ""; // Parse the function arguments if (args.length () > 0) { if (args (0).is_string ()) { path = args (0).string_value (); } else { print_usage (); return octave_value (); } } if (args.length() > 1 && (args.length() & 1) == 0) { error ("Expected property name/value pairs"); return octave_value (); } for(int i=1;i<args.length();i+=2) { // first pair should be a property name if (! args (i).is_string ()) { error ("Expected property name string"); return octave_value (); } std::string name = args (i).string_value (); octave_value val = args (i+1); std::transform (name.begin (), name.end (), name.begin (), ::tolower); if (name == "bitrate") { if ((val.OV_ISINTEGER () || val.OV_ISFLOAT ()) && (val.int_value () > 0)) bitrate = val.int_value (); else { error ("bitrate must be a positive integer"); return octave_value(); } } else if (name == "clockpolarity") { if (val.is_string ()) polarity = val.string_value (); else { error ("polarity must be a string"); return octave_value(); } } else if (name == "clockphase") { if (val.is_string ()) phase = val.string_value (); else { error ("phase must be a string"); return octave_value(); } } else if (name == "name") { if (val.is_string ()) objname = val.string_value (); else { error ("name must be a string"); return octave_value(); } } else { error ("unknown property '%s'", name.c_str()); return octave_value(); } } octave_spi* retval = new octave_spi (); // Open the interface if (retval->open (path, oflags) < 0) return octave_value (); if (bitrate > 0) retval->set_bitrate (bitrate); if (objname.length() > 0) retval->set_name (objname); if (polarity.length() > 0) retval->set_clockpolarity (polarity); if (phase.length() > 0) retval->set_clockphase (phase); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "spi")) %! fail ("spi ()", "Invalid call to spi"); %! else %! fail ("spi ()", "spi: Your system doesn't support the SPI interface"); %! endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi_class.cc�������������������������������������������������������0000644�0000000�0000000�00000022610�14743226261�016221� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SPI #include <algorithm> #include <stdio.h> #include <stdlib.h> #include <string> #include <string.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include "spi_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_spi, "octave_spi", "octave_spi"); octave_spi::octave_spi (void) : fieldnames(6) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } fd = -1; mode = 0; bitrate = 250000; fieldnames[0] = "status"; fieldnames[1] = "name"; fieldnames[2] = "port"; fieldnames[3] = "bitrate"; fieldnames[4] = "clockpolarity"; fieldnames[5] = "clockphase"; } octave_spi::~octave_spi (void) { octave_spi::close (); } int octave_spi::get_fd (void) const { return fd; } void octave_spi::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_spi::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_spi::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " SPI Object " << this->get_name(); newline(os); os << " status: " << this->get_status(); newline(os); if (get_fd() > -1) { os << " bitrate: " << this->get_bitrate(); newline(os); } } int octave_spi::open (const std::string &path, int flags) { port = path; name = "SPI-" + path; fd = ::open (path.c_str (), flags, 0); if (get_fd () < 0) { error ("spi: Error opening the interface: %s\n", strerror (errno)); return -1; } __u8 dmode, dlsb, dbits; __u32 dspeed; mode = 0; if (ioctl(get_fd (), SPI_IOC_RD_MODE, &dmode) < 0) { warning ("spi: failed to read RD mode: %s\n", strerror (errno)); } else { mode = dmode; } if (ioctl(get_fd (), SPI_IOC_RD_LSB_FIRST, &dlsb) < 0) { warning ("spi: failed to read LSB mode: %s\n", strerror (errno)); } if (ioctl(get_fd (), SPI_IOC_RD_BITS_PER_WORD, &dbits) < 0) { warning ("spi: failed to read bits per word: %s\n", strerror (errno)); } bitrate = 250000; if (ioctl(get_fd (), SPI_IOC_RD_MAX_SPEED_HZ, &dspeed) < 0) { warning ("spi: failed to read speed: %s\n", strerror (errno)); } else { if (bitrate > dspeed) bitrate = dspeed; } return get_fd (); } int octave_spi::read (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("spi: Interface must be open first..."); return -1; } int retval = -1; // retval = ::read (get_fd (), buf, len); struct spi_ioc_transfer tr; memset(&tr, 0, sizeof(tr)); tr.rx_buf = (__u64)buf; //tr.tx_buf = (__u64)tbuf; tr.len = len; /* Length of command to write*/ tr.cs_change = 0; /* Keep CS activated */ tr.delay_usecs = 0; //delay in us tr.speed_hz = bitrate; //speed tr.bits_per_word = 8; // bits per word 8 retval = ioctl(get_fd (), SPI_IOC_MESSAGE(1), &tr); if (retval < 0) error ("spi: Failed to read from the spi bus: %s\n", strerror (errno)); return retval; } int octave_spi::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("spi: Interface must be open first..."); return -1; } int retval = -1; // retval = ::write (get_fd (), buf, len); struct spi_ioc_transfer tr; memset(&tr, 0, sizeof(tr)); tr.tx_buf = (__u64)buf; //tr.rx_buf = (__u64)rbuf; tr.len = len; /* Length of command to write*/ tr.cs_change = 0; /* Keep CS activated */ tr.delay_usecs = 0; //delay in us tr.speed_hz = bitrate; //speed tr.bits_per_word = 8; // bits per word 8 retval = ioctl(get_fd (), SPI_IOC_MESSAGE(1), &tr); if (retval < 0) error ("spi: Failed to write to the spi bus: %s\n", strerror (errno)); return retval; } int octave_spi::writeRead (uint8_t *wbuf, unsigned int wlen, uint8_t *rbuf) { if (get_fd () < 0) { error ("spi: Interface must be open first..."); return -1; } int retval = -1; struct spi_ioc_transfer tr; memset(&tr, 0, sizeof(tr)); tr.tx_buf = (__u64)wbuf; tr.rx_buf = (__u64)rbuf; tr.len = wlen; /* Length of command to write*/ tr.cs_change = 0; /* Keep CS activated */ tr.delay_usecs = 0; //delay in us tr.speed_hz = bitrate; //speed tr.bits_per_word = 8; // bits per word 8 retval = ioctl(get_fd (), SPI_IOC_MESSAGE(1), &tr); if (retval < 0) error ("spi: Failed to writeRead to the spi bus: %s\n", strerror (errno)); return retval; } int octave_spi::close (void) { int retval = -1; if (get_fd () > 0) { retval = ::close(get_fd ()); fd = -1; } return retval; } std::string octave_spi::get_port () const { return port; } std::string octave_spi::get_name () const { return name; } std::string octave_spi::get_clockpolarity () const { if(mode & SPI_CPOL) return "idlehigh"; else return "idlelow"; } std::string octave_spi::set_clockpolarity (const std::string &newpolarity) { std::string polarity = newpolarity; std::transform (polarity.begin (), polarity.end (), polarity.begin (), ::tolower); int newmode = mode; if(polarity == "idlelow") newmode = mode & ~SPI_CPOL; else if(polarity == "idlehigh") newmode = mode | SPI_CPOL; __u8 dmode = newmode; if(ioctl(fd, SPI_IOC_WR_MODE, &dmode) < 0) { error ("spi: failed to mode: %s\n", strerror (errno)); } else { mode = newmode; } return get_clockpolarity(); } std::string octave_spi::get_clockphase () const { if(mode & SPI_CPHA) return "secondedge"; else return "firstedge"; } std::string octave_spi::set_clockphase (const std::string &newphase) { std::string phase = newphase; std::transform (phase.begin (), phase.end (), phase.begin (), ::tolower); int newmode = mode; if(phase == "firstedge") newmode = mode & ~SPI_CPHA; else if(phase == "secondedge") newmode = mode | SPI_CPHA; __u8 dmode = newmode; if(ioctl(fd, SPI_IOC_WR_MODE, &dmode) < 0) { error ("spi: failed to mode: %s\n", strerror (errno)); } else { mode = newmode; } return get_clockphase(); } std::string octave_spi::set_name (const std::string &newname) { name = newname; return name; } unsigned long octave_spi::get_bitrate () const { return bitrate; } unsigned long octave_spi::set_bitrate (unsigned long newbitrate) { __u32 speed = newbitrate; if (ioctl(get_fd (), SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) { error ("spi: failed to set speed: %s\n", strerror (errno)); } else { bitrate = newbitrate; } return bitrate; } std::string octave_spi::get_status () const { if (get_fd () > -1) return "open"; else return "closed"; } octave_value_list octave_spi::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_spi object cannot be indexed with %c", type[0]); break; case '.': { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__spi_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_spi::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_spi object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__spi_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length() > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_spi invalid index"); } } return retval; } #endif ������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi_class.h��������������������������������������������������������0000644�0000000�0000000�00000006334�14743226261�016070� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef SPI_CLASS_H #define SPI_CLASS_H #include <octave/oct.h> #include <string> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #include <linux/spi/spidev.h> class octave_spi : public OCTAVE_BASE_CLASS { public: octave_spi (void); ~octave_spi (void); int open (const std::string& /* path */, int /* open flags */); int close (void); int get_fd (void) const; std::string get_name () const; std::string set_name (const std::string &newname); unsigned long get_bitrate () const; unsigned long set_bitrate (unsigned long rate); std::string get_status () const; std::string get_clockphase () const; std::string set_clockphase (const std::string &newphase); std::string get_clockpolarity () const; std::string set_clockpolarity (const std::string &newpolarity); std::string get_port () const; // Simple spi commands int write (uint8_t* /* buffer */, unsigned int /* buffer size */); int read (uint8_t* /* buffer */, unsigned int /* buffer size */); int writeRead (uint8_t *wbuf, unsigned int wlen, uint8_t *rbuf); // Overloaded base functions double spi_value () const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true;} // 4.4+ bool isobject (void) const { return true;} octave_base_value * unique_clone (void) { OV_COUNT++; return this;} /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); private: int fd; std::string name; std::string port; unsigned int bitrate; int mode; string_vector fieldnames; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi_close.cc�������������������������������������������������������0000644�0000000�0000000�00000003143�14743226261�016221� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SPI #include "spi_class.h" #endif // PKG_ADD: autoload ("spi_close", "spi.oct"); DEFUN_DLD (spi_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} spi_close (@var{spi})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @subsubheading Inputs\n \ @var{spi} - instance of @var{octave_spi} class.@*\ \n \ @subsubheading Outputs\n \ None\n \ @end deftypefn") { #ifndef BUILD_SPI error ("spi: Your system doesn't support the SPI interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_spi::static_type_id ()) { print_usage (); return octave_value (-1); } octave_spi* spi = NULL; const octave_base_value& rep = args (0).get_rep (); spi = &((octave_spi &)rep); spi->close (); return octave_value (); #endif } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi_read.cc��������������������������������������������������������0000644�0000000�0000000�00000005137�14743226261�016034� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/uint8NDArray.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SPI #include <errno.h> #include "spi_class.h" #endif // PKG_ADD: autoload ("spi_read", "spi.oct"); DEFUN_DLD (spi_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } spi_read (@var{spi}, @var{n})\n \ \n\ Read from spi slave device.\n \ \n\ @subsubheading Inputs\n \ @var{spi} - instance of @var{octave_spi} class.@*\ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ @subsubheading Outputs\n \ The spi_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_SPI error ("spi: Your system doesn't support the SPI interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_spi::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 1; if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } buffer_len = args (1).int_value (); } OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len +1)); if (buffer == NULL) { error ("spi_read: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } octave_spi* spi = NULL; const octave_base_value& rep = args (0).get_rep(); spi = &((octave_spi &)rep); int retval; retval = spi->read (buffer, buffer_len); octave_value_list return_list; uint8NDArray data (dim_vector (1, retval)); for (int i = 0; i < retval; i++) data (i) = buffer[i]; return_list (0) = data; return_list (1) = retval; return return_list; #endif } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi_write.cc�������������������������������������������������������0000644�0000000�0000000�00000004557�14743226261�016260� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SPI #include <errno.h> #include "spi_class.h" #endif // PKG_ADD: autoload ("spi_write", "spi.oct"); DEFUN_DLD (spi_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } spi_write (@var{spi}, @var{data})\n \ \n\ Write data to a spi slave device.\n \ \n\ @subsubheading Inputs\n \ @var{spi} - instance of @var{octave_spi} class.@*\ @var{data} - data, of type uint8, to be written to the slave device.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, spi_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_SPI error ("spi: Your system doesn't support the SPI interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_spi::static_type_id ()) { print_usage (); return octave_value (-1); } octave_spi* spi = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); spi = &((octave_spi &)rep); if (args (1).is_uint8_type ()) // uint8_t { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("spi_write: cannot allocate requested memory: %s", strerror (errno)); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data (i)); retval = spi->write (buf, data.numel()); } else { error ("spi_write: expected uint8 data"); return octave_value (-1); } return octave_value (retval); #endif } �������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/spi/spi_writeAndRead.cc������������������������������������������������0000644�0000000�0000000�00000005763�14743226261�017477� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_SPI #include <errno.h> #include "spi_class.h" #endif // PKG_ADD: autoload ("spi_writeAndRead", "spi.oct"); DEFUN_DLD (spi_writeAndRead, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{rddata} = } spi_writeAndRead (@var{spi}, @var{wrdata})\n \ \n\ Write data to a spi slave device and then read same number of values.\n \ \n\ @subsubheading Inputs\n \ @var{spi} - instance of @var{octave_spi} class.@*\ @var{wrdata} - data, of type uint8, to be written to the slave device.@*\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, spi_writeAndRead() shall return the bytes read.\n \ @end deftypefn") { #ifndef BUILD_SPI error ("spi: Your system doesn't support the SPI interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_spi::static_type_id ()) { print_usage (); return octave_value (-1); } octave_spi* spi = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); spi = &((octave_spi &)rep); if (args (1).is_uint8_type ()) // uint8_t { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("spi_writeAndRead: cannot allocate requested memory: %s", strerror (errno)); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data (i)); OCTAVE_LOCAL_BUFFER (uint8_t, rdbuffer, (data.numel () +1)); if (rdbuffer == NULL) { error ("spi_writeAndRead: cannot allocate requested read memory: %s\n", strerror (errno)); return octave_value (-1); } retval = spi->writeRead (buf, data.numel(), rdbuffer); octave_value_list return_value; if (retval >= 0) { uint8NDArray data (dim_vector (1, retval)); for (int i = 0; i < retval; i++) data (i) = rdbuffer[i]; return_value(0) = data; return return_value; } else error ("spi_writeAndRead: error reading data"); } else { error ("spi_writeAndRead: expected uint8 data"); return octave_value (); } return octave_value (); #endif } �������������instrument-control-0.9.4/src/tcp/�������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013724� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/Makefile.in��������������������������������������������������������0000644�0000000�0000000�00000000343�14743226261�015771� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../tcp.oct OBJ := tcp.o tcp_timeout.o tcp_write.o tcp_close.o tcp_read.o tcp_class.o __tcp_properties__.o __tcp_pkg_lock__.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/__tcp_pkg_lock__.cc������������������������������������������������0000644�0000000�0000000�00000002751�14743226261�017473� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__tcp_pkg_lock__", "tcp.oct"); // PKG_ADD: __tcp_pkg_lock__(1); // PKG_DEL: __tcp_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__tcp_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__tcp_pkg_lock__")) interp.munlock("__tcp_pkg_lock__"); } return retval; } #else DEFUN_DLD(__tcp_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �����������������������instrument-control-0.9.4/src/tcp/__tcp_properties__.cc����������������������������������������������0000644�0000000�0000000�00000011647�14743226261�020102� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2016 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP # include "tcp_class.h" #endif // PKG_ADD: autoload ("__tcp_properties__", "tcp.oct"); DEFUN_DLD (__tcp_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __tcp_properties__ (@var{octave_tcp}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_TCP if (args.length () < 2 || args.length () > 3 || args(0).type_id () != octave_tcp::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_tcp* tcp = &((octave_tcp &)rep); std::string property = args(1).string_value (); if (args.length () == 2) // get { if (property == "name") return octave_value (tcp->get_name ()); else if (property == "type") return octave_value (tcp->get_type ()); else if (property == "remoteport") return octave_value (tcp->get_remote_port ()); else if (property == "remotehost") return octave_value (tcp->get_remote_addr ()); else if (property == "localport") return octave_value (tcp->get_local_port ()); else if (property == "status") return octave_value (tcp->get_status ()); else if (property == "timeout") return octave_value (tcp->get_timeout ()); else if (property == "bytesavailable") return octave_value (tcp->get_bytesavailable ()); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (tcp->set_name (args(2).string_value ())); else if (property == "type") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "remoteport") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "remotehost") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "localport") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "timeout") return octave_value (tcp->set_timeout (args(2).double_value ())); else if (property == "flush") return octave_value (tcp->flush (args(2).int_value ())); else (*current_liboctave_error_handler) ("invalid property name"); } #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the TCP interface"); } #if 0 %!shared ip %! ip = resolvehost("www.octave.org", "address"); %!test %! # test get %! a = tcp (ip, 80); %! assert (__tcp_properties__ (a,"type"), "tcp"); %! assert (__tcp_properties__ (a,"remoteport"), 80); %! assert (__tcp_properties__ (a,"remotehost"), ip); %! assert (__tcp_properties__ (a,"timeout"), -1); %! assert (__tcp_properties__ (a,"status"), "open"); %! assert (__tcp_properties__ (a,"name"), ["TCP-" ip]); %! fail ("__tcp_properties__ (a,'invalid')", "invalid property name"); %! tcp_close (a); %! assert (__tcp_properties__ (a,"status"), "closed"); %!test %! # test set %! a = tcp(ip, 80); %! __tcp_properties__ (a, 'name', "mytest"); %! assert (__tcp_properties__ (a,"name"), "mytest"); %! fail ("__tcp_properties__ (a,'invalid', 1)", "invalid property name"); %! tcp_close (a); %!test %! # test flush %! a = tcp(ip, 80); %! __tcp_properties__ (a, 'flush', 0); %! __tcp_properties__ (a, 'flush', 1); %! __tcp_properties__ (a, 'flush', 2); %! fail ("__tcp_properties__ (a,'flush')", "invalid property name"); %! tcp_close (a); %!error <wrong number of arguments> __tcp_properties__ () %!error <wrong number of arguments> __tcp_properties__ (1) %!test %! a = tcp (ip, 80); %! fail ("__tcp_properties__ (a, 'name', 'test', 0)", "wrong number of arguments"); %! tcp_close (a); #endif �����������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp.cc�������������������������������������������������������������0000644�0000000�0000000�00000014501�14743226261�015022� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP # include "tcp_class.h" #endif // PKG_ADD: autoload ("tcp", "tcp.oct"); DEFUN_DLD (tcp, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{tcp} = } tcp ()\n \ @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress})\n \ @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, @var{port})\n \ @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, @var{port}, @var{timeout})\n \ @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, [@var{propertyname}, @var{propertyvalue}])\n \ @deftypefnx {Loadable Function} {@var{tcp} = } tcp (@var{ipaddress}, @var{port}, [@var{propertyname}, @var{propertyvalue}])\n \ \n\ Open tcp interface.\n \ \n\ @subsubheading Inputs\n \ @var{ipaddress} - the ip address of type String. If omitted defaults to '127.0.0.1'.@* \ @var{port} - the port number to connect. If omitted defaults to 23.@* \ @var{timeout} - the interface timeout value. If omitted defaults to blocking call.@*\n \ @var{propname},@var{propvalue} - property name/value pairs.\n \ \n \ Known input properties:\n \ @table @asis\n \ @item name\n \ name value\n \ @item timeout\n \ Numeric timeout value or -1 to wait forever\n \ @end table\n \ \n\ @subsubheading Outputs\n \ The tcp() shall return instance of @var{octave_tcp} class as the result @var{tcp}.\n \ @subsubheading Properties\n \ The tcp object has the following public properties:\n \ @table @asis\n \ @item name\n \ name assigned to the tcp object\n \ @item type\n \ instrument type 'tcp' (readonly)\n \ @item localport\n \ local port number (readonly)\n \ @item remoteport\n \ remote port number\n \ @item remotehost\n \ remote host\n \ @item status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item timeout\n \ timeout value in seconds used for waiting for data\n \ @item bytesavailable\n \ number of bytes currently available to read (readonly)\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_TCP error("tcp: Your system doesn't support the TCP interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values std::string address ("127.0.0.1"); std::string name = ""; int port = 23; double timeout = -1; // Parse the function arguments if (args.length () > 0) { if (args (0).is_string ()) { address = args (0).string_value (); } else { print_usage (); return octave_value (); } } // is_float_type() is or'ed to allow expression like ("", 123), without user // having to use ("", int32(123)), as we still only take "int_value" int property_start = -1; if (args.length () > 1) { if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { port = args (1).int_value (); } else { property_start = 1; } } if (args.length () > 2 && property_start == -1) { if (args (2).OV_ISINTEGER () || args (2).OV_ISFLOAT ()) { timeout = args (2).int_value (); } else { property_start = 2; } } if (args.length () > 3 && property_start == -1) { property_start = 2; } if (property_start != -1) { if (((args.length () - property_start) & 1) == 1) { error ("Expected property name/value pairs"); return octave_value (); } // go through the properties for(int i=property_start;i<args.length();i+=2) { std::string propname = args(i).string_value(); octave_value propval = args(i+1); std::transform (propname.begin (), propname.end (), propname.begin (), ::tolower); if (propname == "name") { if (propval.is_string ()) name = propval.string_value (); else { error ("name must be a string"); return octave_value (); } } else if (propname == "timeout") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) timeout = propval.double_value (); else { error ("timeout must be a integer or double"); return octave_value (); } } else { error ("unknown property '%s'", propname.c_str ()); return octave_value (); } } } // Open the interface and connect octave_tcp* retval = new octave_tcp (); if (retval->open (address, port) < 0) { return octave_value (); } retval->set_timeout (timeout); //retval->flush (2); if (name.length() > 0) retval->set_name (name); return octave_value (retval); #endif } #if 0 %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcp (addr, 80); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcp')); %! tcp_close (a); %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcp (addr, 80, 'name', 'test', 'timeout', 2.5); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcp')); %! assert (get(a, 'name'), 'test'); %! assert (get(a, 'timeout'), 2.5); %! tcp_close (a); %!error <Invalid call to tcp> tcp (1) %!error <Invalid call to tcp> tcp (1, 1) %!error <Invalid call to tcp> tcp ('127.0.0.1', '80', 'prop1') #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp_class.cc�������������������������������������������������������0000644�0000000�0000000�00000024376�14743226261�016222� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include <iostream> #include <string> #include <algorithm> #ifndef __WIN32__ #include <unistd.h> #include <errno.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <termios.h> #include <sys/ioctl.h> #else #include <winsock2.h> #endif #ifndef __WIN32__ #define SOCKETERR errno #define STRSOCKETERR strerror(errno) #define IOCTL_TYPE int #else #define SOCKETERR WSAGetLastError() #define STRSOCKETERR "" #define IOCTL_TYPE u_long #define ioctl ioctlsocket #define socklen_t int #endif #include "tcp_class.h" static struct timeval to_timeval(int ms) { struct timeval tv; if(ms <= 0) { tv.tv_usec = 0; tv.tv_sec = 0; } else { tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms/1000;; } return tv; } static std::string to_ip_str (const sockaddr_in *in) { u_long addr = ntohl (in->sin_addr.s_addr); int b[4]; b[0] = (addr>>24)&0xff; b[1] = (addr>>16)&0xff; b[2] = (addr>>8)&0xff; b[3] = (addr>>0)&0xff; std::stringstream n; n << b[0] << "." << b[1] << "." << b[2] << "." << b[3]; return n.str (); } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_tcp, "octave_tcp", "octave_tcp"); octave_tcp::octave_tcp (void) : fieldnames(8), fd (-1), timeout(-1), name("") { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } fieldnames[0] = "type"; fieldnames[1] = "name"; fieldnames[2] = "remoteport"; fieldnames[3] = "remotehost"; fieldnames[4] = "localport"; fieldnames[5] = "status"; fieldnames[6] = "timeout"; fieldnames[7] = "bytesavailable"; } octave_value_list octave_tcp::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_tcp object cannot be indexed with %c", type[0]); break; case '.': { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__tcp_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_tcp::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_tcp object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__tcp_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_tcp invalid index"); } } return retval; } int octave_tcp::open (const std::string &address, int port) { int sockerr; name = "TCP-" + address; #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup (wVersionRequested, &wsaData); if ( err != 0 ) { error( "could not initialize winsock library" ); return -1; } #endif memset (&remote_addr, 0, sizeof (remote_addr)); remote_addr.sin_addr.s_addr = inet_addr (address.c_str ()); remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons (port); fd = socket (AF_INET, SOCK_STREAM,0); if (fd < 0) { error ("tcp: error opening socket : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcp::close (); return -1; } // get local socket info memset (&local_addr, 0, sizeof (local_addr)); socklen_t sz = sizeof (local_addr); getsockname (fd, (struct sockaddr*)&local_addr, &sz); sockerr = connect (fd, (struct sockaddr*)&remote_addr, sizeof(struct sockaddr)); if (sockerr < 0) { error ("tcp: error on connect : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcp::close (); return -1; } return get_fd(); } octave_tcp::~octave_tcp (void) { octave_tcp::close (); } void octave_tcp::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_tcp::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_tcp::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " TCP Object " << get_name (); newline(os); os << " type: " << get_type (); newline(os); os << " status: " << get_status (); newline(os); os << " remoteport: " << get_remote_port (); newline(os); os << " remotehost: " << get_remote_addr (); newline(os); os << " localport: " << get_local_port (); newline (os); } int octave_tcp::read (uint8_t *buf, unsigned int len, double readtimeout) { struct timeval tv; fd_set readfds; if (get_fd () < 0) { error ("tcp_read: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; tv = to_timeval((readtimeout < 0 || readtimeout > 1000) ? 1000 : (int)readtimeout); FD_ZERO (&readfds); FD_SET (get_fd (), &readfds); if (::select (get_fd ()+1, &readfds, NULL, NULL, &tv) < 0) { error ("tcp_read: Error while reading/select: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } if (FD_ISSET (get_fd (), &readfds)) { read_retval = ::recv(get_fd (), reinterpret_cast<char *>((buf + bytes_read)), len - bytes_read, 0); if (read_retval < 0) { error ("tcp_read: Error while reading: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else if (read_retval == 0) { error ("tcp_read: Connection lost: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else { bytes_read += read_retval; } } else { // time out if (readtimeout >= 0) { // real timeout if (readtimeout <= 1000) break; // timed out 1 sec of an actual timeout else readtimeout -= 1000; } } } return bytes_read; } int octave_tcp::write (const std::string &str) { if (get_fd () < 0) { error ("tcp: Interface must be opened first..."); return -1; } return ::send (get_fd (), str.c_str (), str.length (), 0); } int octave_tcp::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("tcp: Interface must be opened first..."); return -1; } return ::send (get_fd (), reinterpret_cast<const char *>(buf), len, 0); } int octave_tcp::set_timeout (double newtimeout) { if (get_fd () < 0) { error ("tcp: Interface must be opened first..."); return -1; } if (newtimeout < -1 ) { error ("tcp_timeout: timeout value must be -1 or positive"); return -1; } timeout = newtimeout; return 1; } int octave_tcp::close (void) { int retval = -1; if (get_fd() > 0) { #ifndef __WIN32__ retval = ::close (get_fd ()); #else retval = ::closesocket (get_fd ()); #endif fd = -1; } return retval; } int octave_tcp::get_bytesavailable () const { IOCTL_TYPE available = 0; if (get_fd () <= 0) { return 0; } ioctl (get_fd (), FIONREAD, &available); return available; } int octave_tcp::get_remote_port (void) const { return ntohs (remote_addr.sin_port); } std::string octave_tcp::get_remote_addr (void) const { return to_ip_str (&remote_addr); } int octave_tcp::get_local_port (void) const { return ntohs (local_addr.sin_port); } std::string octave_tcp::set_name (const std::string &n) { if (n.length() == 0 ) { error ("tcp_name: value must be non empty"); } else { name = n; } return name; } bool octave_tcp::is_open (void) const { return fd > 0; } std::string octave_tcp::get_status (void) const { if (! is_open ()) { return "closed"; } else { return "open"; } } int octave_tcp::flush (int mode) { int retval = -1; if (get_fd() > 0) { uint8_t tmpbuffer[1024]; if (mode == 0 || mode == 2) { // we are sending data as we get it, so no outout // buffers to flush } if (mode == 1 || mode == 2) { while (read (tmpbuffer, 1024, 0) > 0) {} } } return retval; } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp_class.h��������������������������������������������������������0000644�0000000�0000000�00000006546�14743226261�016063� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef TCP_CLASS_H #define TCP_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> #ifndef __WIN32__ # include <netinet/in.h> #else # include <winsock2.h> #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_tcp : public OCTAVE_BASE_CLASS { public: octave_tcp (void); ~octave_tcp (void); int write (const std::string &); int write (uint8_t *, unsigned int); int read (uint8_t *, unsigned int, double); int open (const std::string &, int); int close (void); int get_fd (void) const { return fd; } int flush (int mode); int set_timeout (double); double get_timeout (void) const { return timeout; } // Overloaded base functions double tcp_value (void) const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true; } // 4.4+ bool isobject (void) const { return true; } // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } octave_base_value * unique_clone (void) { OV_COUNT++; return this; } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); int get_bytesavailable (void) const; std::string get_name (void) const { return name; } std::string set_name (const std::string &); std::string get_remote_addr (void) const; int get_remote_port (void) const; bool is_open(void) const; std::string get_type (void) const { return "tcp"; } std::string get_status (void) const; int get_local_port (void) const; private: string_vector fieldnames; int fd; double timeout; std::string name; sockaddr_in remote_addr; sockaddr_in local_addr; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp_close.cc�������������������������������������������������������0000644�0000000�0000000�00000003553�14743226261�016214� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include "tcp_class.h" #endif // PKG_ADD: autoload ("tcp_close", "tcp.oct"); DEFUN_DLD (tcp_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} tcp_close (@var{tcp})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @subsubheading Inputs\n \ @var{tcp} - instance of @var{octave_tcp} class.\n \ \n \ @subsubheading Outputs\n \ None\n \ @end deftypefn") { #ifndef BUILD_TCP error ("tcp: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_tcp::static_type_id ()) { print_usage (); return octave_value (-1); } octave_tcp* tcp = NULL; const octave_base_value& rep = args (0).get_rep (); tcp = &((octave_tcp &)rep); tcp->close (); return octave_value (); #endif } #if 0 %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcp (addr, 80); %! tcp_close (a); %!error <Invalid call to tcp_close> tcp_close (1) %!error <Invalid call to tcp_close> tcp_close () #endif �����������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp_read.cc��������������������������������������������������������0000644�0000000�0000000�00000007173�14743226261�016024� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include <octave/uint8NDArray.h> #include <errno.h> #include "tcp_class.h" #endif // PKG_ADD: autoload ("tcp_read", "tcp.oct"); DEFUN_DLD (tcp_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } tcp_read (@var{tcp}, @var{n}, @var{timeout})\n \ \n\ Read from tcp interface.\n \ \n\ @subsubheading Inputs\n \ @var{tcp} - instance of @var{octave_tcp} class.@* \ @var{n} - number of bytes to attempt to read of type Integer@* \ @var{timeout} - timeout in ms if different from default of type Integer\n \ \n\ @subsubheading Outputs\n \ @var{count} - number of bytes successfully read as an Integer@*\n \ @var{data} - data bytes themselves as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_TCP error ("tcp: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length() < 2 || args.length () > 3 || args (0).type_id () != octave_tcp::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 0; if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } if ( args.length () > 2 ) { if ( !(args (2).OV_ISINTEGER () || args (2).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } } buffer_len = args (1).int_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("tcp_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value (-1); } octave_tcp* tcp = NULL; const octave_base_value& rep = args (0).get_rep (); tcp = &((octave_tcp &)rep); double timeout = tcp->get_timeout (); if (args.length () == 3) { timeout = args (2).double_value (); } // Read data int bytes_read = tcp->read (buffer, buffer_len, timeout); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data (dim_vector (1, bytes_read) ); for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; return_list(0) = data; return_list(1) = bytes_read; return return_list; #endif } #if 0 %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcp (addr, 80); %! assert (! isnull (a)); %! # server should be waiting for us to send request %! fail ("tcp_read (a, 10, 0, 0)", "Invalid call to tcp_read"); %! %! [d,c] = tcp_read (a, 1, 0); %! assert (0, c); %! assert (isempty (d)); %! %! tic; %! [d,c] = tcp_read (a, 1, 1000); %! t = toc; %! assert (c, 0); %! assert (isempty (d)); %! assert (t, 1.0, 0.1) %! %! tcp_close (a); %!error <Invalid call to tcp_read> tcp_read (1) %!error <Invalid call to tcp_read> tcp_read (1, 10, 0) #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp_timeout.cc�����������������������������������������������������0000644�0000000�0000000�00000005675�14743226261�016604� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017,2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include "tcp_class.h" #endif // PKG_ADD: autoload ("tcp_timeout", "tcp.oct"); DEFUN_DLD (tcp_timeout, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} tcp_timeout (@var{tcp}, @var{timeout})\n \ @deftypefnx {Loadable Function} {@var{t} = } tcp_timeout (@var{tcp})\n \ \n\ Set new or get existing tcp interface timeout parameter used for tcp_read() requests. The timeout value is specified in milliseconds.\n \ \n\ @subsubheading Inputs\n \ @var{tcp} - instance of @var{octave_tcp} class.@* \ @var{timeout} - tcp_read() timeout value in milliseconds. Value of -1 means a blocking call.\n \ \n\ @subsubheading Outputs\n \ If @var{timeout} parameter is omitted, the tcp_timeout() shall return current timeout value as the result @var{t}.\n \ @end deftypefn") { #ifndef BUILD_TCP error("tcp: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_tcp::static_type_id ()) { print_usage (); return octave_value (-1); } octave_tcp* tcp = NULL; const octave_base_value& rep = args (0).get_rep (); tcp = &((octave_tcp &)rep); // Setting new timeout if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } if (args (1).double_value() >= 0.0) tcp->set_timeout (args (1).double_value ()/1000.0); else tcp->set_timeout (-1); return octave_value (); // Should it return by default? } // Returning current timeout double timeout = tcp->get_timeout (); if (timeout < 0) return octave_value (-1); else return octave_value (timeout*1000.0); #endif } #if 0 %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcp (addr, 80); %! assert(tcp_timeout(a), -1); %! a.timeout = 2.5; %! assert(tcp_timeout(a), 2500); %! a.timeout = 0; %! assert(tcp_timeout(a), 0); %! a.timeout = -1; %! assert(tcp_timeout(a), -1); %! tcp_close(a); #endif �������������������������������������������������������������������instrument-control-0.9.4/src/tcp/tcp_write.cc�������������������������������������������������������0000644�0000000�0000000�00000005731�14743226261�016241� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include "tcp_class.h" #endif // PKG_ADD: autoload ("tcp_write", "tcp.oct"); DEFUN_DLD (tcp_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } tcp_write (@var{tcp}, @var{data})\n \ \n\ Write data to a tcp interface.\n \ \n\ @subsubheading Inputs\n \ @var{tcp} - instance of @var{octave_tcp} class.@* \ @var{data} - data to be written to the tcp interface. Can be either of String or uint8 type.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, tcp_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_TCP error("tcp: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_tcp::static_type_id ()) { print_usage (); return octave_value (-1); } octave_tcp *tcp = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); tcp = &((octave_tcp &)rep); if (args (1).is_string ()) // String { retval = tcp->write (args (1).string_value ()); } else if (args (1).is_uint8_type ()) { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); // memcpy? if (buf == NULL) { error ("tcp_write: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = tcp->write (buf, data.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } #if 0 %!error <Invalid call to tcp_write> tcp_write(1, uint8([104 101 108 108 111])) %!error <Invalid call to tcp_write> tcp_write() %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcp (addr, 80); %! # call HTTP HEAD %! req = "HEAD / HTTP/1.1\r\n\r\n"; %! assert (length (req), tcp_write (a, req)); %! [d, c] = tcp_read (a, 12, 5000); %! tcp_close (a); %! assert (12, c); %! assert (c, length (d)); #endif ���������������������������������������instrument-control-0.9.4/src/tcpclient/�������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015123� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/Makefile.in��������������������������������������������������0000644�0000000�0000000�00000000373�14743226261�017173� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../tcpclient.oct OBJ := tcpclient.o __tcpclient_write__.o __tcpclient_read__.o tcpclient_class.o __tcpclient_properties__.o __tcpclient_pkg_lock__.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/__tcpclient_pkg_lock__.cc������������������������������������0000644�0000000�0000000�00000003031�14743226261�022061� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__tcpclient_pkg_lock__", "tcpclient.oct"); // PKG_ADD: __tcpclient_pkg_lock__(1); // PKG_DEL: __tcpclient_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__tcpclient_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__tcpclient_pkg_lock__")) interp.munlock("__tcpclient_pkg_lock__"); } return retval; } #else DEFUN_DLD(__tcpclient_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/__tcpclient_properties__.cc����������������������������������0000644�0000000�0000000�00000016712�14743226261�022476� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP # include "tcpclient_class.h" #endif static octave_value_list get_terminator (octave_tcpclient* tcp) { // may have a single terminator or a start and stop octave_value in = tcp->get_input_terminator (); octave_value out = tcp->get_output_terminator (); if(in.is_string() && out.is_string() && in.string_value() == out.string_value()) return in; else if(in.is_scalar_type() && out.is_scalar_type() && in.int_value() == out.int_value()) return in; else { Cell ret = Cell(dim_vector(1, 2)); ret(0) = in; ret(1) = out; return octave_value (ret); } } static octave_value set_terminator(octave_tcpclient* tcp, const octave_value_list& args) { if (args.length () == 1) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a number or string"); tcp->set_input_terminator (args (0)); tcp->set_output_terminator (args (0)); return octave_value (); // Should it return by default? } else if (args.length () == 2) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a number or string"); if ( !(args (1).is_string ()) && !(args (1).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a number or string"); tcp->set_input_terminator (args (0)); tcp->set_output_terminator (args (1)); return octave_value (); // Should it return by default? } else if (args.length () > 2) (*current_liboctave_error_handler) ("wrong number of arguments"); return octave_value(); } // PKG_ADD: autoload ("__tcpclient_properties__", "tcpclient.oct"); DEFUN_DLD (__tcpclient_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __tcpclient_properties__ (@var{octave_tcpclient}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_TCP if (args.length () < 2 || args(0).type_id () != octave_tcpclient::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_tcpclient* tcpclient = &((octave_tcpclient &)rep); std::string property = args(1).string_value (); std::transform (property.begin (), property.end (), property.begin (), ::tolower); int maxinputs = 3; if (property == "terminator") maxinputs = 4; if (args.length () > maxinputs) (*current_liboctave_error_handler) ("wrong number of arguments"); if (args.length () == 2) // get { if (property == "name") return octave_value (tcpclient->get_name ()); else if (property == "type") return octave_value (tcpclient->get_type ()); else if (property == "port") return octave_value (tcpclient->get_port ()); else if (property == "address") return octave_value (tcpclient->get_address ()); else if (property == "status") return octave_value (tcpclient->get_status ()); else if (property == "timeout") return octave_value (tcpclient->get_timeout ()); else if (property == "numbytesavailable") return octave_value (tcpclient->get_numbytesavailable ()); else if (property == "numbyteswritten") return octave_value (tcpclient->get_numbyteswritten ()); else if (property == "byteorder") return octave_value (tcpclient->get_byteorder ()); else if (property == "userdata") return octave_value (tcpclient->get_userdata ()); else if (property == "terminator") return get_terminator (tcpclient); else if (property == "enabletransferdelay") return octave_value(tcpclient->get_enabletransferdelay ()); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (tcpclient->set_name (args(2).string_value ())); else if (property == "type") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "port") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "address") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "timeout") return octave_value (tcpclient->set_timeout (args(2).double_value ())); else if (property == "userdata") { tcpclient->set_userdata (args(2)); return octave_value (); } else if (property == "byteorder") return octave_value (tcpclient->set_byteorder (args(2).string_value ())); else if (property == "flush") return octave_value (tcpclient->flush (args(2).int_value ())); else if (property == "terminator") return set_terminator (tcpclient, args.slice (2, args.length ()-2)); else if (property == "enabletransferdelay") (*current_liboctave_error_handler) ("can not set this property"); else (*current_liboctave_error_handler) ("invalid property name"); } #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the TCP interface"); } #if 0 %!shared ip %! ip = resolvehost("www.octave.org", "address"); %!test %! # test get %! a = tcpclient (ip, 80); %! assert (__tcpclient_properties__ (a,"type"), "tcpclient"); %! assert (__tcpclient_properties__ (a,"port"), 80); %! assert (__tcpclient_properties__ (a,"address"), ip); %! assert (__tcpclient_properties__ (a,"timeout"), -1); %! assert (__tcpclient_properties__ (a,"status"), "open"); %! assert (__tcpclient_properties__ (a,"name"), ["TCP-" ip]); %! fail ("__tcpclient_properties__ (a,'invalid')", "invalid property name"); %! clear a %!test %! # test set %! a = tcpclient(ip, 80); %! __tcpclient_properties__ (a, 'name', "mytest"); %! assert (__tcpclient_properties__ (a,"name"), "mytest"); %! fail ("__tcpclient_properties__ (a,'invalid', 1)", "invalid property name"); %! clear a %!test %! # test flush %! a = tcpclient(ip, 80); %! __tcpclient_properties__ (a, 'flush', 0); %! __tcpclient_properties__ (a, 'flush', 1); %! __tcpclient_properties__ (a, 'flush', 2); %! fail ("__tcpclient_properties__ (a,'flush')", "invalid property name"); %! clear a %!error <wrong number of arguments> __tcpclient_properties__ () %!error <wrong number of arguments> __tcpclient_properties__ (1) %!test %! a = tcpclient (ip, 80); %! fail ("__tcpclient_properties__ (a, 'name', 'test', 0)", "wrong number of arguments"); %! clear a #endif ������������������������������������������������������instrument-control-0.9.4/src/tcpclient/__tcpclient_read__.cc����������������������������������������0000644�0000000�0000000�00000007335�14743226261�021216� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include <octave/uint8NDArray.h> #include <errno.h> #include "tcpclient_class.h" #endif // PKG_ADD: autoload ("__tcpclient_read__", "tcpclient.oct"); DEFUN_DLD (__tcpclient_read__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } __tcpclient_read__ (@var{tcpclient}, @var{n}, @var{timeout})\n \ \n\ Private function t read from tcpclient interface.\n \ \n\ @subsubheading Inputs\n \ @var{tcpclient} - instance of @var{octave_tcpclient} class.@* \ @var{n} - number of bytes to attempt to read of type Integer@* \ @var{timeout} - timeout in ms if different from default of type Integer\n \ \n\ @subsubheading Outputs\n \ @var{count} - number of bytes successfully read as an Integer@*\n \ @var{data} - data bytes themselves as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_TCP error ("tcpclient: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length() < 2 || args.length () > 3 || args (0).type_id () != octave_tcpclient::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 0; if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } if ( args.length () > 2 ) { if ( !(args (2).OV_ISINTEGER () || args (2).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } } buffer_len = args (1).int_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("tcpclient_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value (-1); } octave_tcpclient* tcpclient = NULL; const octave_base_value& rep = args (0).get_rep (); tcpclient = &((octave_tcpclient &)rep); double timeout = tcpclient->get_timeout () * 1000; if (args.length () == 3) { timeout = args (2).double_value (); } // Read data int bytes_read = tcpclient->read (buffer, buffer_len, timeout); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data (dim_vector (1, bytes_read) ); for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; return_list(0) = data; return_list(1) = bytes_read; return return_list; #endif } #if 0 %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcpclient (addr, 80); %! assert (! isnull (a)); %! # server should be waiting for us to send request %! fail ("__tcpclient_read__ (a, 10, 0, 0)", "Invalid call to __tcpclient_read__"); %! %! [d,c] = __tcpclient_read__ (a, 1, 0); %! assert (0, c); %! assert (isempty (d)); %! %! tic; %! [d,c] = __tcpclient_read__ (a, 1, 1000); %! t = toc; %! assert (c, 0); %! assert (isempty (d)); %! assert (t, 1.0, 0.1) %! %! clear a %!error <Invalid call to __tcpclient_read__> __tcpclient_read__ (1) %!error <Invalid call to __tcpclient_read__> __tcpclient_read__ (1, 10, 0) #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/__tcpclient_write__.cc���������������������������������������0000644�0000000�0000000�00000006060�14743226261�021427� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include "tcpclient_class.h" #endif // PKG_ADD: autoload ("__tcpclient_write__", "tcpclient.oct"); DEFUN_DLD (__tcpclient_write__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } __tcpclient_write__ (@var{tcpclient}, @var{data})\n \ \n\ Private function to write data to a tcpclient interface.\n \ \n\ @subsubheading Inputs\n \ @var{tcpclient} - instance of @var{octave_tcpclient} class.@* \ @var{data} - data to be written to the tcpclient interface. Can be either of String or uint8 type.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, __tcpclient_write__() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_TCP error("tcpclient: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_tcpclient::static_type_id ()) { print_usage (); return octave_value (-1); } octave_tcpclient *tcpclient = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); tcpclient = &((octave_tcpclient &)rep); if (args (1).is_string ()) // String { retval = tcpclient->write (args (1).string_value ()); } else if (args (1).is_uint8_type ()) { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); // memcpy? if (buf == NULL) { error ("tcpclient_write: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = tcpclient->write (buf, data.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } #if 0 %!error <Invalid call to __tcpclient_write> __tcpclient_write__(1, uint8([104 101 108 108 111])) %!error <Invalid call to __tcpclient_write__> __tcpclient_write__() %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcpclient (addr, 80);; %! # call HTTP HEAD %! req = "HEAD / HTTP/1.1\r\n\r\n"; %! assert (length (req), __tcpclient_write__ (a, req)); %! [d, c] = __tcpclient_read__ (a, 12, 5000); %! clear a %! assert (12, c); %! assert (c, length (d)); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/tcpclient.cc�������������������������������������������������0000644�0000000�0000000�00000015402�14743226261�017421� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/Matrix.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP # include "tcpclient_class.h" #endif // PKG_ADD: autoload ("tcpclient", "tcpclient.oct"); DEFUN_DLD (tcpclient, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{tcpclient} = } tcpclient (@var{ipaddress}, @var{port})\n \ @deftypefnx {Loadable Function} {@var{tcpclient} = } tcpclient (@var{ipaddress}, @var{port}, [@var{propertyname}, @var{propertyvalue}])\n \ \n\ Open tcpclient interface.\n \ \n\ @subsubheading Inputs\n \ @var{ipaddress} - the ip address of type String.@* \ @var{port} - the port number to connect.@* \ @var{propname},@var{propvalue} - property name/value pairs.\n \ \n \ Known input properties:\n \ @table @asis\n \ @item Name\n \ name value\n \ @item Timeout\n \ Numeric timeout value or -1 to wait forever\n \ @item EnableTransferDelay\n \ Boolean to enable or disable the nagle algorithm for delay transfer.\n \ @item UserData\n \ User data value.\n \ @end table\n \ \n\ @subsubheading Outputs\n \ The tcpclient() shall return instance of @var{octave_tcpclient} class as the result @var{tcpclient}.\n \ \n \ @subsubheading Properties\n \ The tcpclient object has the following public properties:\n \ @table @asis\n \ @item Name\n \ name assigned to the tcpclient object\n \ @item Type\n \ instrument type 'tcpclient' (readonly)\n \ @item Port\n \ remote port number (Readonly)\n \ @item Address\n \ remote host address (Readonly)\n \ @item Status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item Timeout\n \ timeout value in seconds used for waiting for data\n \ @item NumBytesAvailable\n \ number of bytes currently available to read (readonly)\n \ @item NumBytesWritten\n \ number of bytes currently available to read (readonly)\n \ @item ByteOrder\n \ Byte order for data (currently not used)\n \ @item Terminator\n \ Terminator value used for string data (currently not used)\n \ @item UserData\n \ User data\n \ @item EnableTransferDelay\n \ Bool for whether transfer delay is enabled. (Read only)\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_TCP error("tcpclient: Your system doesn't support the TCP interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values std::string address ("127.0.0.1"); std::string name = ""; int port = 23; double timeout = -1; int ndelay = 1; octave_value userdata = Matrix(); // Parse the function arguments if (args.length () < 2) { print_usage (); return octave_value (); } if (args (0).is_string ()) { address = args (0).string_value (); } else { error ("Expected address as a string"); return octave_value (); } if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { port = args (1).int_value (); } else { error ("Expected port as a number"); return octave_value (); } if (args.length () > 2) { if ((args.length () & 1) == 1) { error ("Expected property name/value pairs"); return octave_value (); } // go through the properties for(int i=2;i<args.length();i+=2) { std::string propname = args(i).string_value(); octave_value propval = args(i+1); std::transform (propname.begin (), propname.end (), propname.begin (), ::tolower); if (propname == "name") { if (propval.is_string ()) name = propval.string_value (); else { error ("name must be a string"); return octave_value (); } } else if (propname == "timeout") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) timeout = propval.double_value (); else { error ("timeout must be a integer or double"); return octave_value (); } } else if (propname == "enabletransferdelay") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) { ndelay = propval.int_value (); if (ndelay != 0 && ndelay != 1) { error ("enabletranfserdelay should be 0 or 1"); return octave_value (); } } else if (propval.OV_ISLOGICAL ()) { if (! propval.bool_value()) ndelay = 0; } else { error ("enabletranfserdelay should be 0 or 1"); return octave_value (); } } else if (propname == "userdata") { userdata = propval; } else { error ("unknown property '%s'", propname.c_str ()); return octave_value (); } } } // Open the interface and connect octave_tcpclient* retval = new octave_tcpclient (); if (retval->open (address, port, ndelay) < 0) { return octave_value (); } retval->set_timeout (timeout); //retval->flush (2); if (name.length() > 0) retval->set_name (name); retval->set_userdata (userdata); return octave_value (retval); #endif } #if 0 %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcpclient (addr, 80); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcpclient')); %! clear a %!test %! addr = resolvehost ('gnu.org', 'address'); %! a = tcpclient (addr, 80, 'name', 'test', 'timeout', 2.5); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcpclient')); %! assert (get(a, 'Name'), 'test'); %! assert (get(a, 'Timeout'), 2.5); %! clear a %!error <Invalid call to tcpclient> tcpclient (1) %!error <Invalid call to tcpclient> tcpclient (1, 1) %!error <Invalid call to tcpclient> tcpclient ('127.0.0.1', '80', 'prop1') #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/tcpclient_class.cc�������������������������������������������0000644�0000000�0000000�00000033260�14743226261�020610� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include <iostream> #include <string> #include <algorithm> #ifndef __WIN32__ #include <unistd.h> #include <errno.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <termios.h> #include <sys/ioctl.h> #else #include <winsock2.h> #endif #ifndef __WIN32__ #define SOCKETERR errno #define STRSOCKETERR strerror(errno) #define IOCTL_TYPE int #else #define SOCKETERR WSAGetLastError() #define STRSOCKETERR "" #define IOCTL_TYPE u_long #define ioctl ioctlsocket #define socklen_t int #endif #include "tcpclient_class.h" #include <octave/Matrix.h> static struct timeval to_timeval(int ms) { struct timeval tv; if(ms <= 0) { tv.tv_usec = 0; tv.tv_sec = 0; } else { tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms/1000;; } return tv; } static std::string to_ip_str (const sockaddr_in *in) { u_long addr = ntohl (in->sin_addr.s_addr); int b[4]; b[0] = (addr>>24)&0xff; b[1] = (addr>>16)&0xff; b[2] = (addr>>8)&0xff; b[3] = (addr>>0)&0xff; std::stringstream n; n << b[0] << "." << b[1] << "." << b[2] << "." << b[3]; return n.str (); } static bool lookup_addr (const std::string &ip, sockaddr_in *in) { in->sin_addr.s_addr = inet_addr (ip.c_str()); if (in->sin_addr.s_addr == INADDR_NONE) { struct hostent * host = gethostbyname (ip.c_str()); if (!host) return false; memcpy(&in->sin_addr, host->h_addr_list[0], host->h_length); } return true; } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_tcpclient, "octave_tcpclient", "octave_tcpclient"); octave_tcpclient::octave_tcpclient (void) : fieldnames(12), fd (-1), timeout(-1), name("") { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } userData = Matrix (); byteswritten = 0; byteOrder = "little-endian"; interminator = octave_value("lf"); outterminator = octave_value("lf"); fieldnames[0] = "Type"; fieldnames[1] = "Name"; fieldnames[2] = "Port"; fieldnames[3] = "Address"; fieldnames[4] = "Status"; fieldnames[5] = "Timeout"; fieldnames[6] = "NumBytesAvailable"; fieldnames[7] = "NumBytesWritten"; fieldnames[8] = "ByteOrder"; fieldnames[9] = "UserData"; fieldnames[10] = "Terminator"; fieldnames[11] = "EnableTransferDelay"; } bool octave_tcpclient::has_property(const std::string &name) const { for (octave_idx_type i=0; i<fieldnames.numel(); i++) { if (fieldnames[i] == name) return true; } return false; } octave_value_list octave_tcpclient::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_tcpclient object cannot be indexed with %c", type[0]); return retval; case '.': { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__tcpclient_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_tcpclient::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_tcpclient object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__tcpclient_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_tcpclient invalid index"); } } return retval; } int octave_tcpclient::open (const std::string &address, int port, int nd) { int sockerr; name = "TCP-" + address; #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup (wVersionRequested, &wsaData); if ( err != 0 ) { error( "could not initialize winsock library" ); return -1; } #endif memset (&remote_addr, 0, sizeof (remote_addr)); if( !lookup_addr (address, &remote_addr)) { error ("tcp: error looking up remote host : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpclient::close (); return -1; } remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons (port); fd = socket (AF_INET, SOCK_STREAM,0); if (fd < 0) { error ("tcpclient: error opening socket : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpclient::close (); return -1; } ndelay = nd; #ifdef __WIN32__ DWORD sockval = nd; #else int sockval = nd; #endif socklen_t valsz = sizeof(sockval); setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&sockval, valsz); // get local socket info memset (&local_addr, 0, sizeof (local_addr)); socklen_t sz = sizeof (local_addr); getsockname (fd, (struct sockaddr*)&local_addr, &sz); sockerr = connect (fd, (struct sockaddr*)&remote_addr, sizeof(struct sockaddr)); if (sockerr < 0) { error ("tcpclient: error on connect : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpclient::close (); return -1; } return get_fd(); } octave_tcpclient::~octave_tcpclient (void) { octave_tcpclient::close (); } void octave_tcpclient::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_tcpclient::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_tcpclient::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " TCP Client Object " << get_name (); newline(os); os << " Address: " << get_address (); newline(os); os << " Port: " << get_port (); newline(os); } int octave_tcpclient::read (uint8_t *buf, unsigned int len, double readtimeout) { struct timeval tv; fd_set readfds; if (get_fd () < 0) { error ("tcpclient_read: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; tv = to_timeval((readtimeout < 0 || readtimeout > 1000) ? 1000 : (int)readtimeout); FD_ZERO (&readfds); FD_SET (get_fd (), &readfds); if (::select (get_fd ()+1, &readfds, NULL, NULL, &tv) < 0) { error ("tcpclient_read: Error while reading/select: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } if (FD_ISSET (get_fd (), &readfds)) { read_retval = ::recv(get_fd (), reinterpret_cast<char *>((buf + bytes_read)), len - bytes_read, 0); if (read_retval < 0) { error ("tcpclient_read: Error while reading: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else if (read_retval == 0) { error ("tcpclient_read: Connection lost: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else { bytes_read += read_retval; } } else { // time out if (readtimeout >= 0) { // real timeout if (readtimeout <= 1000) break; // timed out 1 sec of an actual timeout else readtimeout -= 1000; } } } return bytes_read; } int octave_tcpclient::write (const std::string &str) { if (get_fd () < 0) { error ("tcpclient: Interface must be opened first..."); return -1; } int wrote = ::send (get_fd (), str.c_str (), str.length (), 0); if(wrote > 0) byteswritten += wrote; return wrote; } int octave_tcpclient::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("tcpclient: Interface must be opened first..."); return -1; } int wrote = ::send (get_fd (), reinterpret_cast<const char *>(buf), len, 0); if(wrote > 0) byteswritten += wrote; return wrote; } int octave_tcpclient::set_timeout (double newtimeout) { if (get_fd () < 0) { error ("tcpclient: Interface must be opened first..."); return -1; } if (newtimeout < -1 ) { error ("tcpclient_timeout: timeout value must be -1 or positive"); return -1; } timeout = newtimeout; return 1; } int octave_tcpclient::close (void) { int retval = -1; if (get_fd() > 0) { #ifndef __WIN32__ retval = ::close (get_fd ()); #else retval = ::closesocket (get_fd ()); #endif fd = -1; } return retval; } int octave_tcpclient::get_numbytesavailable () const { IOCTL_TYPE available = 0; if (get_fd () <= 0) { return 0; } ioctl (get_fd (), FIONREAD, &available); return available; } int octave_tcpclient::get_port (void) const { return ntohs (remote_addr.sin_port); } std::string octave_tcpclient::get_address (void) const { return to_ip_str (&remote_addr); } std::string octave_tcpclient::set_name (const std::string &n) { if (n.length() == 0 ) { error ("tcpclient_name: value must be non empty"); } else { name = n; } return name; } bool octave_tcpclient::is_open (void) const { return fd > 0; } std::string octave_tcpclient::get_status (void) const { if (! is_open ()) { return "closed"; } else { return "open"; } } int octave_tcpclient::flush (int mode) { int retval = -1; if (get_fd() > 0) { uint8_t tmpbuffer[1024]; if (mode == 0 || mode == 2) { // we are sending data as we get it, so no outout // buffers to flush } if (mode == 1 || mode == 2) { while (read (tmpbuffer, 1024, 0) > 0) {} } } return retval; } int octave_tcpclient::set_byteorder(const std::string& neworder) { std::string order = neworder; std::transform (order.begin (), order.end (), order.begin (), ::tolower); if (order == "big" || order == "big-endian") byteOrder = "big-endian"; else if (order == "little" || order == "little-endian") byteOrder = "little-endian"; else error ("octave_tcpclient invalid byteorder"); return 1; } int octave_tcpclient::set_input_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_tcpclient invalid input terminator"); else interminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_tcpclient invalid input terminator"); } else { interminator = octave_value(x); } } else error ("octave_tcpclient invalid input terminator"); return 1; } int octave_tcpclient::set_output_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_tcpclient invalid output terminator"); else outterminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_tcpclient invalid output terminator"); } else { outterminator = octave_value(x); } } else error ("octave_tcpclient invalid output terminator"); return 1; } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpclient/tcpclient_class.h��������������������������������������������0000644�0000000�0000000�00000010211�14743226261�020441� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef TCP_CLASS_H #define TCP_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> #ifndef __WIN32__ # include <netinet/in.h> #else # include <winsock2.h> #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_tcpclient : public OCTAVE_BASE_CLASS { public: octave_tcpclient (void); ~octave_tcpclient (void); int write (const std::string &); int write (uint8_t *, unsigned int); int read (uint8_t *, unsigned int, double); int open (const std::string &, int, int); int close (void); int get_fd (void) const { return fd; } int flush (int mode); // Overloaded base functions double tcpclient_value (void) const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_map (void) const { return true; } bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true; } // 4.4+ bool isobject (void) const { return true; } // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } octave_base_value * unique_clone (void) { OV_COUNT++; return this; } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); int get_numbytesavailable (void) const; unsigned int get_numbyteswritten (void) const { return byteswritten; } std::string get_name (void) const { return name; } std::string set_name (const std::string &); int set_timeout (double); double get_timeout (void) const { return timeout; } std::string get_address (void) const; int get_port (void) const; bool is_open(void) const; std::string get_type (void) const { return "tcpclient"; } std::string get_status (void) const; octave_value get_userdata () const { return userData; } void set_userdata (const octave_value &newv) { userData = newv; } int set_byteorder(const std::string& /* order */); std::string get_byteorder() const { return byteOrder; } int set_input_terminator(const octave_value& /* term */); int set_output_terminator(const octave_value& /* term */); octave_value get_input_terminator() const { return interminator; } octave_value get_output_terminator() const { return outterminator; } bool get_enabletransferdelay (void) const { return ndelay; } private: bool has_property(const std::string &name) const; string_vector fieldnames; int fd; double timeout; std::string name; sockaddr_in remote_addr; sockaddr_in local_addr; octave_value userData; std::string byteOrder; unsigned int byteswritten; octave_value interminator; octave_value outterminator; int ndelay; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/�������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�015153� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/Makefile.in��������������������������������������������������0000644�0000000�0000000�00000000373�14743226261�017223� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../tcpserver.oct OBJ := tcpserver.o __tcpserver_write__.o __tcpserver_read__.o tcpserver_class.o __tcpserver_properties__.o __tcpserver_pkg_lock__.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/__tcpserver_pkg_lock__.cc������������������������������������0000644�0000000�0000000�00000003031�14743226261�022141� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__tcpserver_pkg_lock__", "tcpserver.oct"); // PKG_ADD: __tcpserver_pkg_lock__(1); // PKG_DEL: __tcpserver_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__tcpserver_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__tcpserver_pkg_lock__")) interp.munlock("__tcpserver_pkg_lock__"); } return retval; } #else DEFUN_DLD(__tcpserver_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/__tcpserver_properties__.cc����������������������������������0000644�0000000�0000000�00000017606�14743226261�022561� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP # include "tcpserver_class.h" #endif static octave_value_list get_terminator (octave_tcpserver* tcp) { // may have a single terminator or a start and stop octave_value in = tcp->get_input_terminator (); octave_value out = tcp->get_output_terminator (); if(in.is_string() && out.is_string() && in.string_value() == out.string_value()) return in; else if(in.is_scalar_type() && out.is_scalar_type() && in.int_value() == out.int_value()) return in; else { Cell ret = Cell(dim_vector(1, 2)); ret(0) = in; ret(1) = out; return octave_value (ret); } } static octave_value set_terminator(octave_tcpserver* tcp, const octave_value_list& args) { if (args.length () == 1) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a number or string"); tcp->set_input_terminator (args (0)); tcp->set_output_terminator (args (0)); return octave_value (); // Should it return by default? } else if (args.length () == 2) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a string"); if ( !(args (1).is_string ()) && !(args (1).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a string"); tcp->set_input_terminator (args (0)); tcp->set_output_terminator (args (1)); return octave_value (); // Should it return by default? } else if (args.length () > 2) (*current_liboctave_error_handler) ("wrong number of arguments"); return octave_value(); } // PKG_ADD: autoload ("__tcpserver_properties__", "tcpserver.oct"); DEFUN_DLD (__tcpserver_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __tcpserver_properties__ (@var{octave_tcpserver}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_TCP if (args.length () < 2 || args(0).type_id () != octave_tcpserver::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_tcpserver* tcpserver = &((octave_tcpserver &)rep); std::string property = args(1).string_value (); std::transform (property.begin (), property.end (), property.begin (), ::tolower); int maxinputs = 3; if (property == "terminator") maxinputs = 4; if (args.length () > maxinputs) (*current_liboctave_error_handler) ("wrong number of arguments"); if (args.length () == 2) // get { if (property == "name") return octave_value (tcpserver->get_name ()); else if (property == "type") return octave_value (tcpserver->get_type ()); else if (property == "serverport") return octave_value (tcpserver->get_port ()); else if (property == "serveraddress") return octave_value (tcpserver->get_address ()); else if (property == "clientport") return octave_value (tcpserver->get_client_port ()); else if (property == "clientaddress") return octave_value (tcpserver->get_client_address ()); else if (property == "status") return octave_value (tcpserver->get_status ()); else if (property == "connected") return octave_value (tcpserver->get_connected ()); else if (property == "timeout") return octave_value (tcpserver->get_timeout ()); else if (property == "numbytesavailable") return octave_value (tcpserver->get_numbytesavailable ()); else if (property == "numbyteswritten") return octave_value (tcpserver->get_numbyteswritten ()); else if (property == "byteorder") return octave_value (tcpserver->get_byteorder ()); else if (property == "userdata") return octave_value (tcpserver->get_userdata ()); else if (property == "terminator") return get_terminator (tcpserver); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (tcpserver->set_name (args(2).string_value ())); else if (property == "type") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "serverport") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "serveraddress") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "clientport") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "clientaddress") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "connected") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "timeout") return octave_value (tcpserver->set_timeout (args(2).double_value ())); else if (property == "userdata") { tcpserver->set_userdata (args(2)); return octave_value (); } else if (property == "byteorder") return octave_value (tcpserver->set_byteorder (args(2).string_value ())); else if (property == "flush") return octave_value (tcpserver->flush (args(2).int_value ())); else if (property == "terminator") return set_terminator (tcpserver, args.slice (2, args.length ()-2)); else (*current_liboctave_error_handler) ("invalid property name"); } #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the TCP interface"); } #if 0 %!test %! # test get %! a = tcpserver (0); %! assert (__tcpserver_properties__ (a,"Type"), "tcpserver"); %! assert (__tcpserver_properties__ (a,"ServerPort") > 0); %! assert (! isempty(__tcpserver_properties__ (a,"ServerAddress"))); %! assert (__tcpserver_properties__ (a,"Timeout"), -1); %! assert (__tcpserver_properties__ (a,"Status"), "open"); %! assert (! isempty(__tcpserver_properties__ (a,"Name"))); %! assert (__tcpserver_properties__ (a,"Connected"), false); %! fail ("__tcpserver_properties__ (a,'invalid')", "invalid property name"); %! clear a %!test %! # test set %! a = tcpserver(0); %! __tcpserver_properties__ (a, 'Name', "mytest"); %! assert (__tcpserver_properties__ (a,"Name"), "mytest"); %! assert (a.Name, "mytest"); %! fail ("__tcpserver_properties__ (a,'invalid', 1)", "invalid property name"); %! clear a %!test %! # test flush %! a = tcpserver(0); %! __tcpserver_properties__ (a, 'flush', 0); %! __tcpserver_properties__ (a, 'flush', 1); %! __tcpserver_properties__ (a, 'flush', 2); %! fail ("__tcpserver_properties__ (a,'flush')", "invalid property name"); %! clear a %!error <wrong number of arguments> __tcpserver_properties__ () %!error <wrong number of arguments> __tcpserver_properties__ (1) %!test %! a = tcpserver (0); %! fail ("__tcpserver_properties__ (a, 'Name', 'test', 0)", "wrong number of arguments"); %! clear a #endif ��������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/__tcpserver_read__.cc����������������������������������������0000644�0000000�0000000�00000010156�14743226261�021271� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include <octave/uint8NDArray.h> #include <errno.h> #include "tcpserver_class.h" #endif // PKG_ADD: autoload ("__tcpserver_read__", "tcpserver.oct"); DEFUN_DLD (__tcpserver_read__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } __tcpserver_read__ (@var{tcpserver}, @var{n}, @var{timeout})\n \ \n\ Private function t read from tcpserver interface.\n \ \n\ @subsubheading Inputs\n \ @var{tcpserver} - instance of @var{octave_tcpserver} class.@* \ @var{n} - number of bytes to attempt to read of type Integer@* \ @var{timeout} - timeout in ms if different from default of type Integer\n \ \n\ @subsubheading Outputs\n \ @var{count} - number of bytes successfully read as an Integer@*\n \ @var{data} - data bytes themselves as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_TCP error ("tcpserver: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length() < 2 || args.length () > 3 || args (0).type_id () != octave_tcpserver::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 0; if ( !(args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } if ( args.length () > 2 ) { if ( !(args (2).OV_ISINTEGER () || args (2).OV_ISFLOAT ())) { print_usage (); return octave_value (-1); } } buffer_len = args (1).int_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("tcpserver_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value (-1); } octave_tcpserver* tcpserver = NULL; const octave_base_value& rep = args (0).get_rep (); tcpserver = &((octave_tcpserver &)rep); double timeout = tcpserver->get_timeout () * 1000; if (args.length () == 3) { timeout = args (2).double_value (); } // Read data int bytes_read = tcpserver->read (buffer, buffer_len, timeout); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data (dim_vector (1, bytes_read) ); for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; return_list(0) = data; return_list(1) = bytes_read; return return_list; #endif } #if 0 %!test %! a = tcpserver (0); %! assert (! isnull (a)); %! assert (a.Connected == false); %! b = tcpclient ("127.0.0.1", a.ServerPort); %! assert (! isnull (b)); %! # server should be waiting for %! pause(0.5); %! assert (a.Connected == true); %! # try read when nothing %! fail ("__tcpserver_read__ (a, 10, 0, 0)", "Invalid call to __tcpserver_read__"); %! %! assert (a.Connected == true); %! [d,c] = __tcpserver_read__ (a, 1, 0); %! assert (0, c); %! assert (isempty (d)); %! %! tic; %! [d,c] = __tcpserver_read__ (a, 1, 1000); %! t = toc; %! assert (c, 0); %! assert (isempty (d)); %! assert (t, 1.0, 0.1) %! %! # write some data from ciient %! __tcpclient_write__(b, "hello"); %! [d,c] = __tcpserver_read__ (a, 5, 1000); %! assert (5, c); %! %! clear b %! [d,c] = __tcpserver_read__ (a, 1, 0); %! assert (0, c); %! %! pause(0.5); %! assert (a.Connected == false); %! %! clear a %!error <Invalid call to __tcpserver_read__> __tcpserver_read__ (1) %!error <Invalid call to __tcpserver_read__> __tcpserver_read__ (1, 10, 0) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/__tcpserver_write__.cc���������������������������������������0000644�0000000�0000000�00000006167�14743226261�021517� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include "tcpserver_class.h" #endif // PKG_ADD: autoload ("__tcpserver_write__", "tcpserver.oct"); DEFUN_DLD (__tcpserver_write__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } __tcpserver_write__ (@var{tcpserver}, @var{data})\n \ \n\ Private function to write data to a tcpserver interface.\n \ \n\ @subsubheading Inputs\n \ @var{tcpserver} - instance of @var{octave_tcpserver} class.@* \ @var{data} - data to be written to the tcpserver interface. Can be either of String or uint8 type.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, __tcpserver_write__() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_TCP error("tcpserver: Your system doesn't support the TCP interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_tcpserver::static_type_id ()) { print_usage (); return octave_value (-1); } octave_tcpserver *tcpserver = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); tcpserver = &((octave_tcpserver &)rep); if (args (1).is_string ()) // String { retval = tcpserver->write (args (1).string_value ()); } else if (args (1).is_uint8_type ()) { NDArray data = args (1).array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); // memcpy? if (buf == NULL) { error ("tcpserver_write: cannot allocate requested memory"); return octave_value (-1); } for (int i = 0; i < data.numel (); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = tcpserver->write (buf, data.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } #if 0 %!error <Invalid call to __tcpserver_write> __tcpserver_write__(1, uint8([104 101 108 108 111])) %!error <Invalid call to __tcpserver_write__> __tcpserver_write__() %!test %! a = tcpserver (0); %! b = tcpclient ("127.0.0.1", a.ServerPort); %! pause(0.5); %! assert (a.Connected == true); %! req = "hello"; %! assert (length(req), __tcpserver_write__(a, req)); %! # did it write so client can read it ? %! [d, c] = __tcpclient_read__ (b, length(req), 5000); %! clear a %! clear b %! assert (length(req), c); %! assert (c, length (d)); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/tcpserver.cc�������������������������������������������������0000644�0000000�0000000�00000014605�14743226261�017505� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/Matrix.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_TCP # include "tcpserver_class.h" #endif // PKG_ADD: autoload ("tcpserver", "tcpserver.oct"); DEFUN_DLD (tcpserver, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{tcpserver} = } tcpserver (@var{ipaddress}, @var{port})\n \ @deftypefnx {Loadable Function} {@var{tcpserver} = } tcpserver (@var{port})\n \ @deftypefnx {Loadable Function} {@var{tcpserver} = } tcpserver (@dots{}, [@var{propertyname}, @var{propertyvalue}])\n \ \n\ Open tcpserver interface.\n \ \n\ @subsubheading Inputs\n \ @var{ipaddress} - the ip address of type String.@* \ @var{port} - the port number to bind.@* \ @var{propname},@var{propvalue} - property name/value pairs.\n \ \n \ Known input properties:\n \ @table @asis\n \ @item Name\n \ name value\n \ @item Timeout\n \ Numeric timeout value or -1 to wait forever\n \ @item UserData\n \ User data value.\n \ @end table\n \ \n\ @subsubheading Outputs\n \ The tcpserver() shall return instance of @var{octave_tcpserver} class as the result @var{tcpserver}.\n \ \n \ @subsubheading Properties\n \ The tcpserver object has the following public properties:\n \ @table @asis\n \ @item Connected\n \ boolean flag for when connected to a client (Readonly)\n \ @item ClientPort\n \ connected client port number (Readonly)\n \ @item ClientAddress\n \ connected client address (Readonly)\n \ @item Name\n \ name assigned to the tcpserver object\n \ @item Type\n \ instrument type 'tcpserver' (readonly)\n \ @item ServerPort\n \ server port number (Readonly)\n \ @item ServerAddress\n \ server address (Readonly)\n \ @item Status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item Timeout\n \ timeout value in seconds used for waiting for data\n \ @item NumBytesAvailable\n \ number of bytes currently available to read (readonly)\n \ @item NumBytesWritten\n \ number of bytes currently available to read (readonly)\n \ @item ByteOrder\n \ Byte order for data (currently not used)\n \ @item Terminator\n \ Terminator value used for string data (currently not used)\n \ @item UserData\n \ User data\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_TCP error("tcpserver: Your system doesn't support the TCP interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values std::string address (""); std::string name = ""; int port = 23; double timeout = -1; octave_value userdata = Matrix(); int property_start = -1; // Parse the function arguments - needs at least 1 arg if (args.length () < 1) { print_usage (); return octave_value (); } // either first arg is an address, or a port to user if (args (0).is_string ()) { address = args (0).string_value (); if (args.length() < 2) { error ("Expected port after address"); return octave_value (); } else if (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) { port = args (1).int_value (); } else { error ("Expected port as a number"); return octave_value (); } property_start = 2; } else if (args (0).OV_ISINTEGER () || args (0).OV_ISFLOAT ()) { port = args (0).int_value (); property_start = 1; } else { error ("Expected address as a string or port number"); return octave_value (); } // properties if (((args.length () - property_start) & 1) == 1) { error ("Expected property name/value pairs"); return octave_value (); } // go through the properties for(int i=property_start;i<args.length();i+=2) { std::string propname = args(i).string_value(); octave_value propval = args(i+1); std::transform (propname.begin (), propname.end (), propname.begin (), ::tolower); if (propname == "name") { if (propval.is_string ()) name = propval.string_value (); else { error ("name must be a string"); return octave_value (); } } else if (propname == "timeout") { if (propval.OV_ISINTEGER () || propval.OV_ISFLOAT ()) timeout = propval.double_value (); else { error ("timeout must be a integer or double"); return octave_value (); } } else if (propname == "userdata") { userdata = propval; } else { error ("unknown property '%s'", propname.c_str ()); return octave_value (); } } // Open the interface and connect octave_tcpserver* retval = new octave_tcpserver (); if (retval->open (address, port) < 0) { return octave_value (); } retval->set_timeout (timeout); //retval->flush (2); if (name.length() > 0) retval->set_name (name); retval->set_userdata (userdata); return octave_value (retval); #endif } #if 0 %!test %! a = tcpserver ("", 0); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcpserver')); %! clear a %!test %! a = tcpserver (0); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcpserver')); %! clear a %!test %! a = tcpserver (0, 'Name', 'test', 'Timeout', 2.5); %! assert (! isnull (a)); %! assert (isa (a, 'octave_tcpserver')); %! assert (get(a, 'Name'), 'test'); %! assert (get(a, 'Timeout'), 2.5); %! clear a %!error <Invalid call to tcpserver> tcpserver (1, 1) %!error <Invalid call to tcpserver> tcpserver ('127.0.0.1', '80') %!error <Invalid call to tcpserver> tcpserver ('127.0.0.1', 80, 'prop1') #endif ���������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/tcpserver_class.cc�������������������������������������������0000644�0000000�0000000�00000040453�14743226261�020672� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_TCP #include <iostream> #include <string> #include <algorithm> #ifndef __WIN32__ #include <unistd.h> #include <errno.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <termios.h> #include <sys/ioctl.h> #else #include <winsock2.h> #endif #ifndef __WIN32__ #define SOCKETERR errno #define STRSOCKETERR strerror(errno) #define IOCTL_TYPE int #else #define SOCKETERR WSAGetLastError() #define STRSOCKETERR "" #define IOCTL_TYPE u_long #define ioctl ioctlsocket #define socklen_t int #endif #include "tcpserver_class.h" #include <octave/Matrix.h> static struct timeval to_timeval(int ms) { struct timeval tv; if(ms <= 0) { tv.tv_usec = 0; tv.tv_sec = 0; } else { tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms/1000;; } return tv; } static std::string to_ip_str (const sockaddr_in *in) { u_long addr = ntohl (in->sin_addr.s_addr); int b[4]; b[0] = (addr>>24)&0xff; b[1] = (addr>>16)&0xff; b[2] = (addr>>8)&0xff; b[3] = (addr>>0)&0xff; std::stringstream n; n << b[0] << "." << b[1] << "." << b[2] << "." << b[3]; return n.str (); } static bool lookup_addr (const std::string &ip, sockaddr_in *in) { in->sin_addr.s_addr = inet_addr (ip.c_str()); if (in->sin_addr.s_addr == INADDR_NONE) { struct hostent * host = gethostbyname (ip.c_str()); if (!host) return false; memcpy(&in->sin_addr, host->h_addr_list[0], host->h_length); } return true; } static std::string num2str(int num) { std::stringstream n; n << num; return n.str (); } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_tcpserver, "octave_tcpserver", "octave_tcpserver"); octave_tcpserver::octave_tcpserver (void) : fieldnames(14), fd (-1), clientfd(-1), timeout(-1), name("") { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } userData = Matrix (); byteswritten = 0; byteOrder = "little-endian"; interminator = octave_value("lf"); outterminator = octave_value("lf"); fieldnames[0] = "Type"; fieldnames[1] = "Name"; fieldnames[2] = "ServerPort"; fieldnames[3] = "ServerAddress"; fieldnames[4] = "ClientPort"; fieldnames[5] = "ClientAddress"; fieldnames[6] = "Connected"; fieldnames[7] = "Status"; fieldnames[8] = "Timeout"; fieldnames[9] = "NumBytesAvailable"; fieldnames[10] = "NumBytesWritten"; fieldnames[11] = "ByteOrder"; fieldnames[12] = "UserData"; fieldnames[13] = "Terminator"; } bool octave_tcpserver::has_property(const std::string &name) const { for (octave_idx_type i=0; i<fieldnames.numel(); i++) { if (fieldnames[i] == name) return true; } return false; } octave_value_list octave_tcpserver::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_tcpserver object cannot be indexed with %c", type[0]); return retval; case '.': { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } // check connections if (property == "Connected") check_for_connections(); octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__tcpserver_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_tcpserver::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_tcpserver object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__tcpserver_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_tcpserver invalid index"); } } return retval; } int octave_tcpserver::open (const std::string &address, int port) { int sockerr; name = "TCPServer-" + num2str(port); #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup (wVersionRequested, &wsaData); if ( err != 0 ) { error( "could not initialize winsock library" ); return -1; } #endif // 1. bind to address/port // 2. start listending // 3. in read ? or somewhere else? need check for incomming connections ? memset (&local_addr, 0, sizeof (local_addr)); if (address == "0.0.0.0" || address == "::" or address == "") local_addr.sin_addr.s_addr = htonl (INADDR_ANY); else { if (! lookup_addr(address, &local_addr)) { error ("tcpserver: error looking up remote host : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpserver::close (); return -1; } } local_addr.sin_family = AF_INET; local_addr.sin_port = htons (port); memset (&remote_addr, 0, sizeof (remote_addr)); //remote_addr.sin_family = AF_INET; //remote_addr.sin_port = htons (port); fd = socket (AF_INET, SOCK_STREAM,0); if (fd < 0) { error ("tcpserver: error opening socket : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpserver::close (); return -1; } sockerr = bind (fd, (struct sockaddr*)&local_addr, sizeof (local_addr)); if (sockerr < 0) { error ("tcpserver: error on bind : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpserver::close (); return -1; } // get local socket info //memset (&local_addr, 0, sizeof (local_addr)); socklen_t sz = sizeof (local_addr); getsockname (fd, (struct sockaddr*)&local_addr, &sz); sockerr = listen (fd, 1); if (sockerr < 0) { error ("tcpserver: error on listen : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_tcpserver::close (); return -1; } return get_fd(); } octave_tcpserver::~octave_tcpserver (void) { octave_tcpserver::close (); } void octave_tcpserver::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_tcpserver::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_tcpserver::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " TCP Server Object " << get_name (); newline(os); os << "ServerAddress: " << get_address (); newline(os); os << " ServerPort: " << get_port (); newline(os); os << " Connected: " << get_connected (); newline(os); } int octave_tcpserver::read (uint8_t *buf, unsigned int len, double readtimeout) { struct timeval tv; fd_set readfds; if (get_fd () < 0) { error ("tcpserver_read: Interface must be opened first..."); return 0; } if (this->clientfd < 0) { error ("tcpserver_read: Not connected"); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; tv = to_timeval((readtimeout < 0 || readtimeout > 1000) ? 1000 : (int)readtimeout); FD_ZERO (&readfds); FD_SET (this->clientfd, &readfds); if (::select (this->clientfd+1, &readfds, NULL, NULL, &tv) < 0) { error ("tcpserver_read: Error while reading/select: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } if (FD_ISSET (this->clientfd, &readfds)) { read_retval = ::recv(this->clientfd, reinterpret_cast<char *>((buf + bytes_read)), len - bytes_read, 0); if (read_retval < 0) { error ("tcpserver_read: Error while reading: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else if (read_retval == 0) { //error ("tcpserver_read: Connection lost: %d - %s\n", SOCKETERR, STRSOCKETERR); this->clientfd = -1; // TODO: call back for disconnected break; } else { bytes_read += read_retval; } } else { // time out if (readtimeout >= 0) { // real timeout if (readtimeout <= 1000) break; // timed out 1 sec of an actual timeout else readtimeout -= 1000; } } } return bytes_read; } int octave_tcpserver::write (const std::string &str) { if (get_fd () < 0) { error ("tcpserver: Interface must be opened first..."); return -1; } if (this->clientfd < 0) { error ("tcpserver_read: Not connected"); return 0; } int wrote = ::send (this->clientfd, str.c_str (), str.length (), 0); if(wrote > 0) byteswritten += wrote; return wrote; } int octave_tcpserver::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("tcpserver: Interface must be opened first..."); return -1; } if (this->clientfd < 0) { error ("tcpserver_read: Not connected"); return 0; } int wrote = ::send (this->clientfd, reinterpret_cast<const char *>(buf), len, 0); if(wrote > 0) byteswritten += wrote; return wrote; } int octave_tcpserver::check_for_connections () { if (get_fd () < 0) { return -1; } fd_set ready; struct timeval tv; FD_ZERO (&ready); FD_SET (get_fd (), &ready); tv.tv_sec = 0; tv.tv_usec = 0; if (::select (get_fd ()+1, &ready, NULL, NULL, &tv) < 0) { error ("tcpserver_read: Error while reading/select: %d - %s\n", SOCKETERR, STRSOCKETERR); return -1; } if (FD_ISSET (get_fd (), &ready)) { socklen_t sz = sizeof (remote_addr); int client = accept(get_fd(), (sockaddr*)&remote_addr, &sz); if(client < 0) { // shouldnt happen ? } else if(this->clientfd >= 0) { // already have a connection so just close this one #ifndef __WIN32__ ::close (client); #else ::closesocket (client); #endif return 0; } else { this->clientfd = client; //warning ("Connected new socket %d", client); //TODO: connected call back ? return 1; } } return 0; } int octave_tcpserver::set_timeout (double newtimeout) { if (get_fd () < 0) { error ("tcpserver: Interface must be opened first..."); return -1; } if (newtimeout < -1 ) { error ("tcpserver_timeout: timeout value must be -1 or positive"); return -1; } timeout = newtimeout; return 1; } int octave_tcpserver::close (void) { int retval = -1; if(this->clientfd) { #ifndef __WIN32__ retval = ::close (this->clientfd); #else retval = ::closesocket (this->clientfd); #endif clientfd = -1; } if (get_fd() > 0) { #ifndef __WIN32__ retval = ::close (get_fd ()); #else retval = ::closesocket (get_fd ()); #endif fd = -1; } return retval; } int octave_tcpserver::get_numbytesavailable () const { IOCTL_TYPE available = 0; if (this->clientfd < 0) { return 0; } ioctl (this->clientfd, FIONREAD, &available); return available; } int octave_tcpserver::get_port (void) const { return ntohs (local_addr.sin_port); } std::string octave_tcpserver::get_address (void) const { return to_ip_str (&local_addr); } int octave_tcpserver::get_client_port (void) const { return ntohs (remote_addr.sin_port); } std::string octave_tcpserver::get_client_address (void) const { return to_ip_str (&remote_addr); } bool octave_tcpserver::get_connected (void) const { return clientfd != -1; } std::string octave_tcpserver::set_name (const std::string &n) { if (n.length() == 0 ) { error ("tcpserver_name: value must be non empty"); } else { name = n; } return name; } bool octave_tcpserver::is_open (void) const { return fd > 0; } std::string octave_tcpserver::get_status (void) const { if (! is_open ()) { return "closed"; } else { return "open"; } } int octave_tcpserver::flush (int mode) { int retval = -1; if (this->clientfd > 0) { uint8_t tmpbuffer[1024]; if (mode == 0 || mode == 2) { // we are sending data as we get it, so no outout // buffers to flush } if (mode == 1 || mode == 2) { while (read (tmpbuffer, 1024, 0) > 0) {} } } return retval; } int octave_tcpserver::set_byteorder(const std::string& neworder) { std::string order = neworder; std::transform (order.begin (), order.end (), order.begin (), ::tolower); if (order == "big" || order == "big-endian") byteOrder = "big-endian"; else if (order == "little" || order == "little-endian") byteOrder = "little-endian"; else error ("octave_tcpserver invalid byteorder"); return 1; } int octave_tcpserver::set_input_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_tcpserver invalid input terminator"); else interminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_tcpserver invalid input terminator"); } else { interminator = octave_value(x); } } else error ("octave_tcpserver invalid input terminator"); return 1; } int octave_tcpserver::set_output_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_tcpserver invalid output terminator"); else outterminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_tcpserver invalid output terminator"); } else { outterminator = octave_value(x); } } else error ("octave_tcpserver invalid output terminator"); return 1; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/tcpserver/tcpserver_class.h��������������������������������������������0000644�0000000�0000000�00000010327�14743226261�020531� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2022 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef TCP_CLASS_H #define TCP_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> #ifndef __WIN32__ # include <netinet/in.h> #else # include <winsock2.h> #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_tcpserver : public OCTAVE_BASE_CLASS { public: octave_tcpserver (void); ~octave_tcpserver (void); int write (const std::string &); int write (uint8_t *, unsigned int); int read (uint8_t *, unsigned int, double); int open (const std::string &, int); int close (void); int get_fd (void) const { return fd; } int flush (int mode); int check_for_connections (); // Overloaded base functions double tcpserver_value (void) const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_map (void) const { return true; } bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool is_object (void) const { return true; } // 4.4+ bool isobject (void) const { return true; } // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } octave_base_value * unique_clone (void) { OV_COUNT++; return this; } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); int get_numbytesavailable (void) const; unsigned int get_numbyteswritten (void) const { return byteswritten; } std::string get_name (void) const { return name; } std::string set_name (const std::string &); int set_timeout (double); double get_timeout (void) const { return timeout; } std::string get_address (void) const; int get_port (void) const; std::string get_client_address (void) const; int get_client_port (void) const; bool is_open(void) const; bool get_connected (void) const; std::string get_type (void) const { return "tcpserver"; } std::string get_status (void) const; octave_value get_userdata () const { return userData; } void set_userdata (const octave_value &newv) { userData = newv; } int set_byteorder(const std::string& /* order */); std::string get_byteorder() const { return byteOrder; } int set_input_terminator(const octave_value& /* term */); int set_output_terminator(const octave_value& /* term */); octave_value get_input_terminator() const { return interminator; } octave_value get_output_terminator() const { return outterminator; } private: bool has_property(const std::string &name) const; string_vector fieldnames; int fd; int clientfd; double timeout; std::string name; sockaddr_in remote_addr; sockaddr_in local_addr; octave_value userData; std::string byteOrder; unsigned int byteswritten; octave_value interminator; octave_value outterminator; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/�������������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�013726� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/Makefile.in��������������������������������������������������������0000644�0000000�0000000�00000000342�14743226261�015772� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../udp.oct OBJ := udp.o udp_timeout.o udp_write.o udp_close.o udp_read.o __udp_properties__.o udp_class.o __udp_pkg_lock__.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/__udp_pkg_lock__.cc������������������������������������������������0000644�0000000�0000000�00000002751�14743226261�017477� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__udp_pkg_lock__", "udp.oct"); // PKG_ADD: __udp_pkg_lock__(1); // PKG_DEL: __udp_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__udp_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__udp_pkg_lock__")) interp.munlock("__udp_pkg_lock__"); } return retval; } #else DEFUN_DLD(__udp_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �����������������������instrument-control-0.9.4/src/udp/__udp_properties__.cc����������������������������������������������0000644�0000000�0000000�00000012474�14743226261�020105� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // Copyright (C) 2014 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2016 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udp_class.h" #endif // PKG_ADD: autoload ("__udp_properties__", "udp.oct"); DEFUN_DLD (__udp_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __udp_properties__ (@var{octave_udp}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_UDP if (args.length () < 2 || args.length () > 3 || args(0).type_id () != octave_udp::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_udp* udp = &((octave_udp &)rep); std::string property = args(1).string_value (); if (args.length () == 2) // get { if (property == "name") return octave_value (udp->get_name ()); else if (property == "type") return octave_value (udp->get_type ()); else if (property == "remoteport") return octave_value (udp->get_remote_port ()); else if (property == "remotehost") return octave_value (udp->get_remote_addr ()); else if (property == "localport") return octave_value (udp->get_local_port ()); else if (property == "localhost") return octave_value (udp->get_local_addr ()); else if (property == "status") return octave_value (udp->get_status ()); else if (property == "timeout") return octave_value (udp->get_timeout ()); else if (property == "bytesavailable") return octave_value (udp->get_bytesavailable ()); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (udp->set_name (args(2).string_value ())); else if (property == "type") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "remoteport") return octave_value (udp->set_remote_port (args(2).int_value ())); else if (property == "remotehost") return octave_value (udp->set_remote_addr (args(2).string_value ())); else if (property == "localport") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "localhost") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "timeout") return octave_value (udp->set_timeout (args(2).double_value ())); else if (property == "flush") return octave_value (udp->flush (args(2).int_value ())); else (*current_liboctave_error_handler) ("invalid property name"); } #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the UDP interface"); } #if 0 %!test %! # test get %! a = udp (); %! assert (__udp_properties__ (a,"type"), "udp"); %! assert (__udp_properties__ (a,"remoteport"), 23); %! assert (__udp_properties__ (a,"remotehost"), "127.0.0.1"); %! assert (__udp_properties__ (a,"timeout"), -1); %! assert (__udp_properties__ (a,"status"), "open"); %! assert (__udp_properties__ (a,"name"), "UDP-127.0.0.1"); %! fail ("__udp_properties__ (a,'invalid')", "invalid property name"); %! udp_close (a); %! assert (__udp_properties__ (a,"status"), "closed"); %!test %! # test set %! a = udp(); %! __udp_properties__ (a, 'name', "mytest"); %! assert (__udp_properties__ (a,"name"), "mytest"); %! fail ("__udp_properties__ (a,'invalid', 1)", "invalid property name"); %! udp_close (a); %!test %! # test flush %! a = udp(); %! __udp_properties__ (a, 'flush', 0); %! __udp_properties__ (a, 'flush', 1); %! __udp_properties__ (a, 'flush', 2); %! fail ("__udp_properties__ (a,'flush')", "invalid property name"); %! udp_close (a); %!test %! # test subsref and get/set %! a = udp (); %! a.name = "test1"; %! assert (isa(a, "octave_udp")); %! assert (a.name, "test1"); %! assert (get(a, 'name'), "test1"); %! %! set (a, "name", "test2"); %! assert (a.name, "test2"); %! assert (get(a, 'name'), "test2"); %!error <wrong number of arguments> __udp_properties__ () %!error <wrong number of arguments> __udp_properties__ (1) %!test %! a = udp (); %! fail ("__udp_properties__ (a, 'name', 'test', 0)", "wrong number of arguments"); %! udp_close (a); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp.cc�������������������������������������������������������������0000644�0000000�0000000�00000014113�14743226261�015025� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udp_class.h" #endif // PKG_ADD: autoload ("udp", "udp.oct"); DEFUN_DLD (udp, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{udp} = } udp ()\n \ @deftypefnx {Loadable Function} {@var{udp} = } udp (@var{remoteipaddress}, @var{remoteport})\n \ @deftypefnx {Loadable Function} {@var{udp} = } udp (@var{remoteipaddress}, @var{remoteport}, [@var{propertyname}, @var{propertyvalue} ...])\n \ \n\ Open udp interface.\n \ \n\ @subsubheading Inputs\n \ @var{remoteipaddress} - the ip address of type String. If omitted defaults to '127.0.0.1'.@* \n \ @var{remoteport} - the port number to connect. If omitted defaults to 23.@* \n \ @var{localport} - the local port number to bind. If omitted defaults to 0@* \n \ @var{propertyname}, @var{propertyvalue} - property name/value pair\n \ \n\ @subsubheading Outputs\n \ The udp() shall return instance of @var{octave_udp} class as the result @var{udp}.\n \ \n \ @subsubheading Properties\n \ The udp object has the following public properties:\n \ @table @asis\n \ @item name\n \ name assigned to the udp object\n \ @item type\n \ instrument type 'udp' (readonly)\n \ @item localport\n \ local port number (readonly)\n \ @item localhost\n \ local host address (readonly)\n \ @item remoteport\n \ remote port number\n \ @item remotehost\n \ remote host\n \ @item status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item timeout\n \ timeout value in seconds used for waiting for data\n \ @item bytesavailable\n \ number of bytes currently available to read (readonly)\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_UDP error("udp: Your system doesn't support the UDP interface"); return octave_value(); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage(); return octave_value(); } // Default values std::string name = ""; std::string address("127.0.0.1"); int port = 23; double timeout = -1; int localport = 0; // Parse the function arguments if (args.length() > 0) { if (args(0).is_string()) { address = args(0).string_value(); } else { print_usage(); return octave_value(); } } // is_float_type() is or'ed to allow expression like ("", 123), without user // having to use ("", int32(123)), as we still only take "int_value" if (args.length() > 1) { if (args(1).OV_ISINTEGER() || args(1).OV_ISFLOAT()) { port = args(1).int_value(); } else { print_usage(); return octave_value(); } } if (args.length() > 2 && ((args.length() & 1) == 1)) { error ("Expected property name/value pairs"); return octave_value (); } if (args.length() > 2) { // go through the properties for(int i=2;i<args.length();i+=2) { if (!args(i).is_string()) { error ("Expected property name as a string"); return octave_value (); } std::string pname = args(i).string_value(); octave_value pval = args(i+1); std::transform (pname.begin (), pname.end (), pname.begin (), ::tolower); if (pname == "localport") { if (pval.OV_ISINTEGER () || pval.OV_ISFLOAT ()) localport = pval.int_value (); else { error ("localport must be a integer"); return octave_value(); } } else if (pname == "timeout") { if (pval.OV_ISINTEGER () || pval.OV_ISFLOAT ()) timeout = pval.double_value (); else { error ("timeout must be a integer or double"); return octave_value(); } } else if (pname == "name") { if (pval.is_string ()) name = pval.string_value (); else { error ("name must be a string"); return octave_value(); } } else { error ("unknown property '%s'", pname.c_str()); return octave_value(); } } } // Open the interface and connect octave_udp* retval = new octave_udp(); if (retval->open(address, port, localport) < 0) { return octave_value(); } retval->set_timeout(timeout); if(name.length() > 0) retval->set_name(name); return octave_value(retval); #endif } #if 0 %!test %! # can create default udp object %! a = udp (); %! assert (! isnull (a)); %! assert (isa (a, 'octave_udp')); %! udp_close (a); %!error <Invalid call to udp> a = udp (1) %!error <Expected property name/value pairs> a = udp ("127.0.0.1", 23, 0) %!error <Expected property name as a string> a = udp ("127.0.0.1", 23, 0, 0) %!test %! a = udp ('127.0.0.1', 23); %! assert (! isnull (a)); %! udp_close (a); %!test %! a = udp ('127.0.0.1', 23, "name", "test", "timeout", 2.5); %! assert (! isnull (a)); %! assert (a.name, "test"); %! assert (a.timeout, 2.5); %! udp_close (a); %!error <Invalid call to udp> udp ('127.0.0.1', 23,0,0,0) #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp_class.cc�������������������������������������������������������0000644�0000000�0000000�00000033132�14743226261�016214� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_UDP #include <iostream> #include <string> #include <algorithm> #include <sstream> #ifndef __WIN32__ # include <unistd.h> # include <errno.h> # include <netinet/in.h> # include <sys/socket.h> # include <netdb.h> # include <arpa/inet.h> # include <termios.h> # include <sys/ioctl.h> # define IOCTL_TYPE int #else # include <winsock2.h> # define IOCTL_TYPE u_long # define ioctl ioctlsocket #endif #include "udp_class.h" #ifndef __WIN32__ # define SOCKETERR errno # define STRSOCKETERR strerror(errno) #else # define SOCKETERR WSAGetLastError() # define STRSOCKETERR "" # define socklen_t int #endif static struct timeval to_timeval(int ms) { struct timeval tv; if(ms <= 0) { tv.tv_usec = 0; tv.tv_sec = 0; } else { tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms/1000;; } return tv; } static std::string to_ip_str (const sockaddr_in *in) { u_long addr = ntohl (in->sin_addr.s_addr); int b[4]; b[0] = (addr>>24)&0xff; b[1] = (addr>>16)&0xff; b[2] = (addr>>8)&0xff; b[3] = (addr>>0)&0xff; std::stringstream n; n << b[0] << "." << b[1] << "." << b[2] << "." << b[3]; return n.str (); } static bool lookup_addr (const std::string &ip, sockaddr_in *in) { in->sin_addr.s_addr = inet_addr (ip.c_str()); if (in->sin_addr.s_addr == INADDR_NONE) { struct hostent * host = gethostbyname (ip.c_str()); if (!host) return false; memcpy(&in->sin_addr, host->h_addr_list[0], host->h_length); } return true; } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_udp, "octave_udp", "octave_udp"); octave_udp::octave_udp (void) : buffer_len(0), fd(-1), timeout(-1), name(""), fieldnames(9) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } fieldnames[0] = "type"; fieldnames[1] = "name"; fieldnames[2] = "remoteport"; fieldnames[3] = "remotehost"; fieldnames[4] = "localport"; fieldnames[5] = "status"; fieldnames[6] = "timeout"; fieldnames[7] = "bytesavailable"; fieldnames[8] = "localhost"; } octave_value_list octave_udp::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_udp object cannot be indexed with %c", type[0]); break; case '.': { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__udp_properties__"), ovl, 1); } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_udp::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_udp object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__udp_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_udp invalid index"); } } return retval; } int octave_udp::open (const std::string &address, int port, int localport) { int sockerr; name = "UDP-" + address; #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup (wVersionRequested, &wsaData ); if ( err != 0 ) { error( "could not initialize winsock library" ); return -1; } #endif memset (&remote_addr, 0, sizeof (remote_addr)); if( !lookup_addr (address, &remote_addr)) { error ("udp: error looking up remote host : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_udp::close (); return -1; } // default size for now input_buffer = new uint8_t[1024]; buffer_len = 1024; buffer_pos = 0; remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(port); fd = socket (AF_INET, SOCK_DGRAM, 0); if (fd < 0) { error ("udp: error opening socket : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_udp::close (); return -1; } memset (&local_addr, 0, sizeof (local_addr)); local_addr.sin_addr.s_addr = htonl (INADDR_ANY); local_addr.sin_family = AF_INET; local_addr.sin_port = htons (localport); sockerr = bind (fd, (struct sockaddr*)&local_addr, sizeof (local_addr)); if (sockerr < 0) { error ("udp: error on bind : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_udp::close (); return -1; } else if (localport == 0) { // if said port, 0, lookup actual port it used socklen_t sz = sizeof (local_addr); getsockname (fd, (struct sockaddr*)&local_addr, &sz); } return get_fd(); } octave_udp::~octave_udp (void) { close(); } void octave_udp::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_udp::print (std::ostream& os, bool pr_as_read_syntax) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_udp::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " UDP Object " << get_name (); newline(os); os << " type: " << get_type (); newline(os); os << " status: " << get_status (); newline(os); os << " remoteport: " << get_remote_port (); newline(os); os << " remotehost: " << get_remote_addr (); newline(os); os << " localport: " << get_local_port (); newline (os); } int octave_udp::get_bytesavailable () const { IOCTL_TYPE available = 0; if (get_fd () < 0) { return 0; } if (buffer_pos > 0) return buffer_pos; ioctl (get_fd (), FIONREAD, &available); return available; } int octave_udp::read (uint8_t *buf, unsigned int len, double readtimeout) { struct sockaddr_in addr; socklen_t addrlen = sizeof (addr); struct timeval tv; fd_set readfds; if (get_fd () < 0) { error ("udp_read: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; // need get some data in the buffer if (buffer_pos == 0) { // need read some data first tv = to_timeval((readtimeout < 0 || readtimeout > 1000) ? 1000 : readtimeout); FD_ZERO (&readfds); FD_SET (get_fd (), &readfds); if (::select(get_fd ()+1, &readfds, NULL, NULL, &tv) < 0) { error("udp_read: Error while reading/select: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } if (FD_ISSET (get_fd (), &readfds)) { int available = get_bytesavailable(); // alloc new buffer if (available > buffer_len) { // get nearest 1k over if can if (available + 1024 > 0) { available = (available + 1023); available &= ~0x3ff; } delete [] input_buffer; input_buffer = 0; input_buffer = new uint8_t[available]; buffer_len = available; } addrlen = sizeof (addr); read_retval = ::recvfrom (get_fd (), reinterpret_cast<char *>(input_buffer), buffer_len, 0, (struct sockaddr*)&addr, &addrlen); if (read_retval < 0) { error ("udp_read: Error while reading: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else if (read_retval == 0) { error ("udp_read: Connection lost: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else { //bytes_read += read_retval; buffer_pos = read_retval; } } else { // Timeout if (readtimeout >= 0) { // real timeout if (readtimeout <= 1000) break; // timed out 1 sec of an actual timeout else readtimeout -= 1000; } } } // buffered data can read ? if (buffer_pos > 0) { if (len - bytes_read < buffer_pos) { read_retval = len - bytes_read; memcpy(&buf[bytes_read], input_buffer, read_retval); memmove(&input_buffer[0], &input_buffer[read_retval], buffer_pos-read_retval); buffer_pos -= read_retval; } else { read_retval = buffer_pos; memcpy(&buf[bytes_read], input_buffer, buffer_pos); buffer_pos = 0; } bytes_read += read_retval; } } return bytes_read; } int octave_udp::write (const std::string &str) { return ::sendto (get_fd (), str.c_str(), str.length(), 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)); } int octave_udp::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error("udp: Interface must be opened first..."); return -1; } return ::sendto (get_fd(), reinterpret_cast<const char *>(buf), len, 0, (struct sockaddr *)&remote_addr, sizeof (remote_addr)); } int octave_udp::set_timeout (double newtimeout) { if (get_fd () < 0) { error ("udp: Interface must be opened first..."); return -1; } if (newtimeout < -1 ) { error ("udp_timeout: timeout value must be -1 or positive"); return -1; } timeout = newtimeout; return 1; } int octave_udp::get_remote_port (void) const { return ntohs (remote_addr.sin_port); } int octave_udp::set_remote_port (int port) { if (port < 0 ) { error ("udp_remote_port: value must be positive"); return -1; } remote_addr.sin_port = htons(port); return get_remote_port(); } std::string octave_udp::get_remote_addr (void) const { return to_ip_str (&remote_addr); } std::string octave_udp::set_remote_addr (const std::string &addr) { if (addr.length() == 0 ) { error ("udp_remote_addr: value must be non empty"); } else if ( !lookup_addr(addr, &remote_addr)) { error ("udp: error looking up remote host : %d - %s\n", SOCKETERR, STRSOCKETERR); } return to_ip_str (&remote_addr); } int octave_udp::get_local_port (void) const { return ntohs (local_addr.sin_port); } std::string octave_udp::get_local_addr (void) const { return to_ip_str (&local_addr); } std::string octave_udp::set_name (const std::string &n) { if (n.length() == 0 ) { error ("udp_name: value must be non empty"); } else { name = n; } return name; } bool octave_udp::is_open (void) const { return fd >= 0; } std::string octave_udp::get_status (void) const { if (! is_open ()) { return "closed"; } else { return "open"; } } int octave_udp::close (void) { int retval = -1; if (get_fd() > 0) { #ifndef __WIN32__ retval = ::close (get_fd ()); #else retval = ::closesocket (get_fd ()); #endif fd = -1; } if (buffer_len) { delete [] input_buffer; buffer_len = 0; } return retval; } int octave_udp::flush (int mode) { int retval = -1; if (get_fd() > 0) { uint8_t tmpbuffer[1024]; if (mode == 0 || mode == 2) { // we are sending data as we get it, so no outout // buffers to flush } if (mode == 1 || mode == 2) { while (read (tmpbuffer, 1024, 0) > 0) {} buffer_pos = 0; } } return retval; } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp_class.h��������������������������������������������������������0000644�0000000�0000000�00000007220�14743226261�016055� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef UDP_CLASS_H #define UDP_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> #ifndef __WIN32__ # include <netinet/in.h> #else # include <winsock2.h> #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_udp : public OCTAVE_BASE_CLASS { public: octave_udp (void); ~octave_udp (void); int write (const std::string &str); int write (uint8_t *buf, unsigned int len); int read (uint8_t *buf, unsigned int len, double readtimeout); int open (const std::string &address, int port, int localport); int close (void); int get_fd (void) const { return fd; } int get_bytesavailable (void) const; // Overloaded base functions double udp_value (void) const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true; } bool is_defined (void) const { return true; } // < 4.4 bool is_object (void) const { return true; } // 4.4 + bool isobject (void) const { return true; } // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } // use single copy of each udp socket octave_base_value * unique_clone (void) { OV_COUNT++; return this; } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); std::string get_name (void) const { return name; } std::string set_name (const std::string &); std::string get_remote_addr (void) const; std::string set_remote_addr (const std::string &); int get_remote_port (void) const; int set_remote_port (int); int get_local_port (void) const; std::string get_local_addr (void) const; bool is_open(void) const; std::string get_type (void) const { return "udp"; } std::string get_status (void) const; int set_timeout (double); double get_timeout (void) const { return timeout; } int flush(int mode); private: uint8_t *input_buffer; int buffer_len; int buffer_pos; int fd; double timeout; std::string name; sockaddr_in remote_addr; sockaddr_in local_addr; string_vector fieldnames; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp_close.cc�������������������������������������������������������0000644�0000000�0000000�00000003565�14743226261�016223� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_UDP #include "udp_class.h" #endif // PKG_ADD: autoload ("udp_close", "udp.oct"); DEFUN_DLD (udp_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} udp_close (@var{udp})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @subsubheading Inputs\n \ @var{udp} - instance of @var{octave_udp} class.\n \ \n\ @subsubheading Inputs\n \ None\n \ @end deftypefn") { #ifndef BUILD_UDP error ("udp: Your system doesn't support the UDP interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_udp::static_type_id ()) { print_usage(); return octave_value (-1); } octave_udp* udp = NULL; const octave_base_value& rep = args(0).get_rep(); udp = &((octave_udp &)rep); udp->close (); return octave_value (); #endif } #if 0 %!test %! a = udp(); %! udp_close(a); %!error <Invalid call to udp_close> udp_close(1) %!error <Invalid call to udp_close> udp_close() #endif �������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp_read.cc��������������������������������������������������������0000644�0000000�0000000�00000007125�14743226261�016025� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2016-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP #include <octave/uint8NDArray.h> #include <errno.h> #include "udp_class.h" #endif // PKG_ADD: autoload ("udp_read", "udp.oct"); DEFUN_DLD (udp_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } udp_read (@var{udp}, @var{n}, @var{timeout})\n \ \n\ Read from udp interface.\n \ \n\ @subsubheading Inputs\n \ @var{udp} - instance of @var{octave_udp} class.@* \ @var{n} - number of bytes to attempt to read of type Integer@* \ @var{timeout} - timeout in ms if different from default of type Integer\n \ \n\ @subsubheading Outputs\n \ The udp_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_UDP error("udp: Your system doesn't support the UDP interface"); return octave_value(); #else if (args.length() < 2 || args.length() > 3 || args(0).type_id() != octave_udp::static_type_id()) { print_usage(); return octave_value(-1); } unsigned int buffer_len = 0; if ( !(args(1).OV_ISINTEGER() || args(1).OV_ISFLOAT())) { print_usage(); return octave_value(-1); } if ( args.length() > 2 ) { if ( !(args(2).OV_ISINTEGER() || args(2).OV_ISFLOAT())) { print_usage(); return octave_value(-1); } } buffer_len = args(1).int_value(); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error("udp_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value(-1); } octave_udp* udp = NULL; const octave_base_value& rep = args(0).get_rep(); udp = &((octave_udp &)rep); double timeout = udp->get_timeout() * 1000; if (args.length() == 3) { timeout = args(2).double_value(); } // Read data int bytes_read = udp->read(buffer, buffer_len, timeout); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data( dim_vector(1, bytes_read) ); for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; return_list(0) = data; return_list(1) = bytes_read; return return_list; #endif } #if 0 %!test %! a = udp (); %! assert (! isnull (a)); %! [d,c] = udp_read (a, 1, 0); %! assert (c == 0); %! assert (isempty (d)); %! udp_close (a); %!error <Invalid call to udp_read> udp_read(1, 10, 0) %!test %! a = udp (); %! fail ("udp_read (a, 10, 0, 0)", "Invalid call to udp_read"); %! udp_close (a); %!test %! # does read wait %! a = udp (); %! assert (! isnull (a)); %! tic; %! [d,c] = udp_read (a, 1, 1000); %! t = toc; %! assert (c, 0); %! assert (isempty (d)); %! assert (t, 1.0, 0.1) %! udp_close (a); #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp_timeout.cc�����������������������������������������������������0000644�0000000�0000000�00000006111�14743226261�016572� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2017-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udp_class.h" #endif // PKG_ADD: autoload ("udp_timeout", "udp.oct"); DEFUN_DLD (udp_timeout, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} udp_timeout (@var{udp}, @var{timeout})\n \ @deftypefnx {Loadable Function} {@var{t} = } udp_timeout (@var{udp})\n \ \n\ Set new or get existing udp interface timeout parameter used for udp_read() requests. The timeout value is specified in milliseconds.\n \ \n\ @subsubheading Inputs\n \ @var{udp} - instance of @var{octave_udp} class.@* \ @var{timeout} - udp_read() timeout value in milliseconds. Value of -1 means a blocking call.\n \ \n\ @subsubheading Outputs\n \ If @var{timeout} parameter is omitted, the udp_timeout() shall return current timeout value as the result @var{t}.\n \ @end deftypefn") { #ifndef BUILD_UDP error("udp: Your system doesn't support the UDP interface"); return octave_value(); #else if (args.length() < 1 || args.length() > 2 || args(0).type_id() != octave_udp::static_type_id()) { print_usage(); return octave_value(-1); } octave_udp* udp = NULL; const octave_base_value& rep = args(0).get_rep(); udp = &((octave_udp &)rep); // Setting new timeout if (args.length() > 1) { if ( !(args(1).OV_ISINTEGER() || args(1).OV_ISFLOAT()) ) { print_usage(); return octave_value(-1); } if(args(1).double_value() >= 0) udp->set_timeout(args(1).double_value()/1000.0); else udp->set_timeout(-1); return octave_value(); // Should it return by default? } // Returning current timeout in ms double timeout = udp->get_timeout(); if(timeout < 0) return octave_value(-1); else return octave_value(timeout*1000.0); #endif } #if 0 %!test %! a = udp(); %! assert(udp_timeout(a), -1); %! udp_timeout(a, 103); %! assert(udp_timeout(a), 103); %! udp_close(a); %!test %! a = udp(); %! assert(udp_timeout(a), -1); %! a.timeout = 2; %! assert(udp_timeout(a), 2000); %! a.timeout = 0; %! assert(udp_timeout(a), 0); %! a.timeout = -1; %! assert(udp_timeout(a), -1); %!error <Invalid call to udp_timeout> udp_timeout() %!error <Invalid call to udp_timeout> udp_timeout(1) #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udp/udp_write.cc�������������������������������������������������������0000644�0000000�0000000�00000006366�14743226261�016252� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018-2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udp_class.h" #endif // PKG_ADD: autoload ("udp_write", "udp.oct"); DEFUN_DLD (udp_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } udp_write (@var{udp}, @var{data})\n \ \n\ Write data to a udp interface.\n \ \n\ @subsubheading Inputs\n \ @var{udp} - instance of @var{octave_udp} class.@* \ @var{data} - data to be written to the udp interface. Can be either of String or uint8 type.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, udp_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_UDP error("udp: Your system doesn't support the UDP interface"); return octave_value(); #else if (args.length() != 2 || args(0).type_id() != octave_udp::static_type_id()) { print_usage(); return octave_value(-1); } octave_udp *udp = NULL; int retval; const octave_base_value& rep = args(0).get_rep(); udp = &((octave_udp &)rep); if (args(1).is_string()) // String { retval = udp->write(args(1).string_value()); } else if (args(1).is_uint8_type ()) { NDArray data = args(1).array_value(); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); // memcpy? if (buf == NULL) { error("udp_write: cannot allocate requested memory"); return octave_value(-1); } for (int i = 0; i < data.numel(); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = udp->write(buf, data.numel()); } else { print_usage(); return octave_value(-1); } return octave_value(retval); #endif } #if 0 %!test %! a = udp (); %! b = udp (); %! p = get (a, 'localport'); %! set (b, 'remoteport', p); %! p = get (b, 'localport'); %! set (a, 'remoteport', p); %! assert (5, udp_write (a, uint8 ([104 101 108 108 111]))); %! [d, c] = udp_read (b, 5, 1000); %! assert (c, 5); %! assert (d, uint8 ([104 101 108 108 111])); %! udp_close (a); %! udp_close (b); %!error <Invalid call to udp_write> udp_write (1, uint8([104 101 108 108 111])) %!error <Invalid call to udp_write> udp_write () %!test %! a = udp (); %! fail ("udp_write (a, uint8([104 101 108 108 111]), 0)", "Invalid call to udp_write") %! udp_close (a); %!test %! a = udp (); %! fail ("udp_write (a)", "Invalid call to udp_write") %! udp_close (a); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/���������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014633� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/Makefile.in����������������������������������������������������0000644�0000000�0000000�00000000354�14743226261�016702� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../udpport.oct OBJ := udpport.o __udpport_write__.o __udpport_read__.o __udpport_properties__.o udpport_class.o __udpport_pkg_lock__.o LFLAGS = $(LIBS) @TCPLIBS@ CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/__udpport_pkg_lock__.cc����������������������������������������0000644�0000000�0000000�00000003011�14743226261�021277� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__udpport_pkg_lock__", "udpport.oct"); // PKG_ADD: __udpport_pkg_lock__(1); // PKG_DEL: __udpport_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__udpport_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__udpport_pkg_lock__")) interp.munlock("__udpport_pkg_lock__"); } return retval; } #else DEFUN_DLD(__udpport_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/__udpport_properties__.cc��������������������������������������0000644�0000000�0000000�00000021075�14743226261�021714� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov-struct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udpport_class.h" #endif static octave_value_list get_terminator (octave_udpport* udp) { // may have a single terminator or a start and stop octave_value in = udp->get_input_terminator (); octave_value out = udp->get_output_terminator (); if(in.is_string() && out.is_string() && in.string_value() == out.string_value()) return in; else if(in.is_scalar_type() && out.is_scalar_type() && in.int_value() == out.int_value()) return in; else { //octave_value_list ret; Cell ret = Cell(dim_vector(1, 2)); ret(0) = in; ret(1) = out; return octave_value (ret); } } static octave_value set_terminator(octave_udpport* udp, const octave_value_list& args) { if (args.length () == 1) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a number or string"); udp->set_input_terminator (args (0)); udp->set_output_terminator (args (0)); return octave_value (); // Should it return by default? } else if (args.length () == 2) { if ( !(args (0).is_string ()) && !(args (0).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a string"); if ( !(args (1).is_string ()) && !(args (1).is_scalar_type ())) (*current_liboctave_error_handler) ("argument must be a string"); udp->set_input_terminator (args (0)); udp->set_output_terminator (args (1)); return octave_value (); // Should it return by default? } else if (args.length () > 2) (*current_liboctave_error_handler) ("wrong number of arguments"); return octave_value(); } // PKG_ADD: autoload ("__udpport_properties__", "udpport.oct"); DEFUN_DLD (__udpport_properties__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {varargout =} __udpport_properties__ (@var{octave_udpport}, @var{property}, @var{varargin})\n\ Undocumented internal function.\n\ @end deftypefn") { #ifdef BUILD_UDP if (args.length () < 2 || args(0).type_id () != octave_udpport::static_type_id () || !args(1).is_string ()) (*current_liboctave_error_handler) ("wrong number of arguments"); const octave_base_value& rep = args(0).get_rep (); octave_udpport* udpport = &((octave_udpport &)rep); std::string property = args(1).string_value (); std::transform (property.begin (), property.end (), property.begin (), ::tolower); int maxinputs = 3; if (property == "terminator") maxinputs = 4; if (args.length () > maxinputs) (*current_liboctave_error_handler) ("wrong number of arguments"); if (args.length () == 2) // get { if (property == "name") return octave_value (udpport->get_name ()); else if (property == "type") return octave_value (udpport->get_type ()); else if (property == "remoteport") return octave_value (udpport->get_remote_port ()); else if (property == "remotehost") return octave_value (udpport->get_remote_addr ()); else if (property == "localport") return octave_value (udpport->get_local_port ()); else if (property == "localhost") return octave_value (udpport->get_local_addr ()); else if (property == "status") return octave_value (udpport->get_status ()); else if (property == "timeout") return octave_value (udpport->get_timeout ()); else if (property == "numbytesavailable") return octave_value (udpport->get_bytesavailable ()); else if (property == "numbyteswritten") return octave_value (udpport->get_byteswritten ()); else if (property == "userdata") return octave_value (udpport->get_userdata ()); else if (property == "terminator") return get_terminator (udpport); else if (property == "multicastgroup") return octave_value (udpport->get_multicastgroup ()); else if (property == "enablemulticast") return octave_value (udpport->get_multicastgroup ().length () > 0 ? 1 : 0); else if (property == "enablemulticastloopback") return octave_value (udpport->get_multicastloopback ()); else if (property == "enableportsharing") return octave_value (udpport->get_enableportsharing ()); else if (property == "enablebroadcast") return octave_value (udpport->get_enablebroadcast ()); else if (property == "ipaddressversion") return octave_value (udpport->get_ipaddressversion ()); else if (property == "byteorder") return octave_value (udpport->get_byteorder ()); else (*current_liboctave_error_handler) ("invalid property name"); } else // set { if (property == "name") return octave_value (udpport->set_name (args(2).string_value ())); else if (property == "type") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "localport") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "localhost") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "status") (*current_liboctave_error_handler) ("can not set this property"); else if (property == "timeout") return octave_value (udpport->set_timeout (args(2).double_value ())); else if (property == "flush") return octave_value (udpport->flush (args(2).int_value ())); else if (property == "terminator") return set_terminator (udpport, args.slice (2, args.length ()-2)); else if (property == "userdata") { udpport->set_userdata (args(2)); return octave_value(); } else if (property == "multicastgroup") return octave_value (udpport->set_multicastgroup (args(2).string_value ())); else if (property == "byteorder") return octave_value (udpport->set_byteorder (args(2).string_value ())); else if (property == "enablemulticastloopback") return octave_value (udpport->set_multicastloopback (args(2).int_value ())); else if (property == "enablebroadcast") return octave_value (udpport->set_enablebroadcast (args(2).int_value ())); else (*current_liboctave_error_handler) ("invalid property name"); } #endif /* never reached in normal operation */ (*current_liboctave_error_handler) ("Your system doesn't support the UDP interface"); } #if 0 %!test %! # test get %! a = udpport (); %! assert (__udpport_properties__ (a,"type"), "udpport"); %! assert (__udpport_properties__ (a,"timeout"), -1); %! assert (__udpport_properties__ (a,"status"), "open"); %! assert (__udpport_properties__ (a,"name"), "UDP-0.0.0.0"); %! fail ("__udpport_properties__ (a,'invalid')", "invalid property name"); %! clear a; %!test %! # test set %! a = udpport(); %! __udpport_properties__ (a, 'name', "mytest"); %! assert (__udpport_properties__ (a,"name"), "mytest"); %! fail ("__udpport_properties__ (a,'invalid', 1)", "invalid property name"); %! clear a; %!test %! # test flush %! a = udpport(); %! __udpport_properties__ (a, 'flush', 0); %! __udpport_properties__ (a, 'flush', 1); %! __udpport_properties__ (a, 'flush', 2); %! fail ("__udpport_properties__ (a,'flush')", "invalid property name"); %! clear a; %!test %! # test subsref and get/set %! a = udpport (); %! a.Name = "test1"; %! assert (isa(a, "octave_udpport")); %! assert (a.Name, "test1"); %! assert (get(a, 'Name'), "test1"); %! %! set (a, "Name", "test2"); %! assert (a.Name, "test2"); %! assert (get(a, 'Name'), "test2"); %! assert (__udpport_properties__ (a,"Name"), "test2"); %! clear a %!error <wrong number of arguments> __udpport_properties__ () %!error <wrong number of arguments> __udpport_properties__ (1) %!test %! a = udpport (); %! fail ("__udpport_properties__ (a, 'Name', 'test', 0)", "wrong number of arguments"); %! clear a; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/__udpport_read__.cc��������������������������������������������0000644�0000000�0000000�00000010137�14743226261�020430� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP #include <octave/uint8NDArray.h> #include <errno.h> #include "udpport_class.h" #endif // PKG_ADD: autoload ("__udpport_read__", "udpport.oct"); DEFUN_DLD (__udpport_read__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } __udpport_read__ (@var{udpport}, @var{n}, @var{timeout})\n \ @deftypefnx {Loadable Function} {[@var{data}, @var{count}. @var{srcip}, @var{srcport}] = } __udpport_read__ (@var{udpport}, @var{n}, @var{timeout})\n \ \n\ Provate function to read from udpport interface.\n \ \n\ @subsubheading Inputs\n \ @var{udpport} - instance of @var{octave_udpport} class.@* \ @var{n} - number of bytes to attempt to read of type Integer@* \n \ @var{timeout} - timeout in ms if different from default of type Integer\n \ \n\ @subsubheading Outputs\n \ The __udpport_read__() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ Optional outputs are provided for the source ip address and port of the read data.\n \ @end deftypefn") { #ifndef BUILD_UDP error("udpport: Your system doesn't support the UDP interface"); return octave_value(); #else if (args.length() < 2 || args.length() > 3 || args(0).type_id() != octave_udpport::static_type_id()) { print_usage(); return octave_value(-1); } unsigned int buffer_len = 0; sockaddr_in addr; if ( !(args(1).OV_ISINTEGER() || args(1).OV_ISFLOAT())) { print_usage(); return octave_value(-1); } if ( args.length() > 2 ) { if ( !(args(2).OV_ISINTEGER() || args(2).OV_ISFLOAT())) { print_usage(); return octave_value(-1); } } buffer_len = args(1).int_value(); OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error("udpport_read: cannot allocate requested memory: %s\n", strerror(errno)); return octave_value(-1); } octave_udpport* udpport = NULL; const octave_base_value& rep = args(0).get_rep(); udpport = &((octave_udpport &)rep); double timeout = udpport->get_timeout() * 1000; if (args.length() == 3) { timeout = args(2).double_value(); } // Read data int bytes_read = udpport->read(buffer, buffer_len, timeout, &addr); // Convert data to octave type variables octave_value_list return_list; uint8NDArray data( dim_vector(1, bytes_read) ); for (int i = 0; i < bytes_read; i++) data(i) = buffer[i]; return_list(0) = data; return_list(1) = bytes_read; if (nargout > 2) { int port = 0; std::string ip = ""; if (bytes_read > 0) to_ip_port(&addr, ip, port); return_list(2) = ip; if (nargout > 3) return_list(3) = port; } return return_list; #endif } #if 0 %!test %! a = udpport (); %! assert (! isnull (a)); %! [d,c] = __udpport_read__ (a, 1, 0); %! assert (c == 0); %! assert (isempty (d)); %! clear a; %!error <Invalid call to __udpport_read__> __udpport_read__(1, 10, 0) %!test %! a = udpport (); %! fail ("__udpport_read__ (a, 10, 0, 0)", "Invalid call to __udpport_read__"); %! clear a; %!test %! # does read wait %! a = udpport (); %! assert (! isnull (a)); %! tic; %! [d,c] = __udpport_read__ (a, 1, 1000); %! t = toc; %! assert (c, 0); %! assert (isempty (d)); %! assert (t, 1.0, 0.1) %! clear a; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/__udpport_write__.cc�������������������������������������������0000644�0000000�0000000�00000010250�14743226261�020643� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udpport_class.h" #endif // PKG_ADD: autoload ("__udpport_write__", "udpport.oct"); DEFUN_DLD (__udpport_write__, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } __udpport_write__ (@var{udpport}, @var{data})\n \ @deftypefnx {Loadable Function} {@var{n} = } __udpport_write__ (@var{udpport}, @var{data}, @var{destipaddress}, @var{destport})\n \ \n\ Provate function to write data to a udpport interface.\n \ \n\ @subsubheading Inputs\n \ @var{udpport} - instance of @var{octave_udpport} class.@* \ @var{data} - data to be written to the udpport interface. Can be either of String or uint8 type.\n \ @var{destipaddress} - ip address to write to.@* \ @var{destport} - port number to write to.\n \ \n\ If @var{destipaddress}, @var{destport} is not provided, write will go to the address configure from the udpport\n \ creation or last used for write.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, __udpport_write__() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_UDP error("udpport: Your system doesn't support the UDP interface"); return octave_value(); #else if ((args.length() != 2 && args.length() != 4) || args(0).type_id() != octave_udpport::static_type_id()) { print_usage(); return octave_value(-1); } octave_udpport *udpport = NULL; int retval; const octave_base_value& rep = args(0).get_rep(); udpport = &((octave_udpport &)rep); std::string destip = ""; int destport = 0; if (args.length() == 4) { if (!args(2).is_string()) { error("udpport_write: expected destipaddress as a string"); return octave_value(-1); } if ( !(args(3).OV_ISINTEGER() || args(3).OV_ISFLOAT())) { error("udpport_write: expected destport as a integer"); return octave_value(-1); } destip = args(2).string_value(); destport = args(3).int_value(); } if (args(1).is_string()) // String { retval = udpport->write(args(1).string_value(), destip, destport); } else if (args(1).is_uint8_type ()) { NDArray data = args(1).array_value(); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); // memcpy? if (buf == NULL) { error("udpport_write: cannot allocate requested memory"); return octave_value(-1); } for (int i = 0; i < data.numel(); i++) buf[i] = static_cast<uint8_t>(data(i)); retval = udpport->write(buf, data.numel(), destip, destport); } else { print_usage(); return octave_value(-1); } return octave_value(retval); #endif } #if 0 %!test %! a = udpport (); %! b = udpport (); %! port = get (b, 'LocalPort'); %! assert (5, __udpport_write__ (a, uint8 ([104 101 108 108 111]), "127.0.0.1", port)); %! [d, c] = __udpport_read__ (b, 5, 1000); %! assert (c, 5); %! assert (d, uint8 ([104 101 108 108 111])); %! clear a; %! clear b; %!error <Invalid call to __udpport_write__> __udpport_write__ (1, uint8([104 101 108 108 111])) %!error <Invalid call to __udpport_write__> __udpport_write__ () %!test %! a = udpport (); %! fail ("__udpport_write__ (a, uint8([104 101 108 108 111]), 0)", "Invalid call to __udpport_write__") %! clear a; %!test %! a = udpport (); %! fail ("__udpport_write__ (a)", "Invalid call to __udpport_write__") %! clear a; #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/udpport.cc�����������������������������������������������������0000644�0000000�0000000�00000013771�14743226261�016650� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef BUILD_UDP # include "udpport_class.h" #endif // PKG_ADD: autoload ("udpport", "udpport.oct"); DEFUN_DLD (udpport, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{udp} = } udpport ()\n \ @deftypefnx {Loadable Function} {@var{udp} = } udpport (@var{propertyname}, @var{propertyvalue} ...)\n \ \n\ Open udpport interface.\n \ \n\ @subsubheading Inputs\n \ @var{propertyname}, @var{propertyvalue} - property name/value pair\n \ \n\ Known input properties:\n \ @table @asis\n \ @item Name\n \ name assigned to the udp object\n \ @item LocalPort\n \ local port number\n \ @item LocalHost\n \ local host address\n \ @item Timeout\n \ timeout value in seconds used for waiting for data\n \ @item EnablePortSharing\n \ Boolean if the socket has port sharing enabled (readonly)\n \ @end table \n \ \n\ @subsubheading Outputs\n \ The udpport() shall return instance of @var{octave_udp} class as the result @var{udp}.\n \ \n \ @subsubheading Properties\n \ The udp object has the following public properties:\n \ @table @asis\n \ @item Name\n \ name assigned to the udp object\n \ @item Type\n \ instrument type 'udpport' (readonly)\n \ @item LocalPort\n \ local port number (readonly)\n \ @item LocalHost\n \ local host address (readonly)\n \ @item Status\n \ status of the object 'open' or 'closed' (readonly)\n \ @item Timeout\n \ timeout value in seconds used for waiting for data\n \ @item NumBytesAvailable\n \ number of bytes currently available to read (readonly)\n \ @item MulticastGroup\n \ multicast group socket is subscribed to (readonly)\n \ @item EnableMultcast\n \ Boolean if the socket has any multicast group it is subscribed to (readonly)\n \ @item EnablePortSharing\n \ Boolean if the socket has port sharing enabled (readonly)\n \ @item Terminator\n \ Terminator value used for string data (currently not used)\n \ @end table \n \ @end deftypefn") { #ifndef BUILD_UDP error("udpport: Your system doesn't support the UDPPORT interface"); return octave_value(); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage(); return octave_value(); } // Default values std::string name = ""; std::string localhost("0.0.0.0"); int localport = 0; double timeout = -1; int portshare = 0; if (args.length() > 0 && ((args.length() & 1) == 1)) { error ("Expected property name/value pairs"); return octave_value (); } if (args.length() > 0) { // go through the properties for(int i=0;i<args.length();i+=2) { if (!args(i).is_string()) { error ("Expected property name as a string"); return octave_value (); } std::string pname = args(i).string_value(); octave_value pval = args(i+1); std::transform (pname.begin (), pname.end (), pname.begin (), ::tolower); if (pname == "localport") { if (pval.OV_ISINTEGER () || pval.OV_ISFLOAT ()) localport = pval.int_value (); else { error ("localport must be a integer"); return octave_value(); } } else if (pname == "localhost") { if (pval.is_string ()) localhost = pval.string_value (); else { error ("localhost must be a string"); return octave_value(); } } else if (pname == "timeout") { if (pval.OV_ISINTEGER () || pval.OV_ISFLOAT ()) timeout = pval.double_value (); else { error ("timeout must be a integer or double"); return octave_value(); } } else if (pname == "enableportsharing") { if (pval.OV_ISINTEGER () || pval.OV_ISFLOAT () || pval.OV_ISLOGICAL ()) portshare = pval.int_value (); else { error ("enableportsharing must be a integer or logical type"); return octave_value(); } } else if (pname == "name") { if (pval.is_string ()) name = pval.string_value (); else { error ("name must be a string"); return octave_value(); } } else { error ("unknown property '%s'", pname.c_str()); return octave_value(); } } } // Open the interface and connect octave_udpport* retval = new octave_udpport(); if (retval->open(localhost, localport, portshare) < 0) { return octave_value(); } retval->set_timeout(timeout); if(name.length() > 0) retval->set_name(name); return octave_value(retval); #endif } #if 0 %!test %! # can create default udp object %! a = udpport (); %! assert (! isnull (a)); %! assert (isa (a, 'octave_udpport')); %! clear a; %!error <Expected property name/value pairs> a = udpport (1) %!test %! a = udpport ("Name", "test", "Timeout", 2.5); %! assert (! isnull (a)); %! assert (a.Name, "test"); %! assert (a.Timeout, 2.5); %! clear a; #endif �������instrument-control-0.9.4/src/udpport/udpport_class.cc�����������������������������������������������0000644�0000000�0000000�00000052117�14743226261�020032� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2020 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_UDP #include <iostream> #include <string> #include <algorithm> #include <sstream> #ifndef __WIN32__ # include <unistd.h> # include <errno.h> # include <netinet/in.h> # include <sys/socket.h> # include <netdb.h> # include <arpa/inet.h> # include <termios.h> # include <sys/ioctl.h> # define IOCTL_TYPE int #else # include <winsock2.h> # include <ws2tcpip.h> # define IOCTL_TYPE u_long # define ioctl ioctlsocket #endif #include "udpport_class.h" #include <octave/Matrix.h> #ifndef __WIN32__ # define SOCKETERR errno # define STRSOCKETERR strerror(errno) #else # define SOCKETERR WSAGetLastError() # define STRSOCKETERR "" # define socklen_t int #endif static struct timeval to_timeval(int ms) { struct timeval tv; if(ms <= 0) { tv.tv_usec = 0; tv.tv_sec = 0; } else { tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms/1000;; } return tv; } static std::string to_ip_str (const sockaddr_in *in) { u_long addr = ntohl (in->sin_addr.s_addr); int b[4]; b[0] = (addr>>24)&0xff; b[1] = (addr>>16)&0xff; b[2] = (addr>>8)&0xff; b[3] = (addr>>0)&0xff; std::stringstream n; n << b[0] << "." << b[1] << "." << b[2] << "." << b[3]; return n.str (); } static bool lookup_addr (const std::string &ip, sockaddr_in *in) { in->sin_addr.s_addr = inet_addr (ip.c_str()); if (in->sin_addr.s_addr == INADDR_NONE) { struct hostent * host = gethostbyname (ip.c_str()); if (!host) return false; memcpy(&in->sin_addr, host->h_addr_list[0], host->h_length); } return true; } int to_ip_port (const sockaddr_in *in, std::string &ip, int &port) { port = ntohs (in->sin_port); ip = to_ip_str(in); return 1; } DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_udpport, "octave_udpport", "octave_udpport"); octave_udpport::octave_udpport (void) : buffer_len(0), fd(-1), timeout(-1), name(""), fieldnames(17) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } userData = Matrix (); byteswritten = 0; byteOrder = "little-endian"; enableportsharing = 0; enablemulticastloopback = 0; enablebroadcast = 0; interminator = octave_value("lf"); outterminator = octave_value("lf"); fieldnames[0] = "Type"; fieldnames[1] = "Name"; fieldnames[2] = "LocalPort"; fieldnames[3] = "LocalHost"; fieldnames[4] = "Status"; fieldnames[5] = "Timeout"; fieldnames[6] = "NumBytesAvailable"; fieldnames[7] = "NumBytesWritten"; fieldnames[8] = "ByteOrder"; fieldnames[9] = "UserData"; fieldnames[10] = "MulticastGroup"; fieldnames[11] = "EnableMulticast"; fieldnames[12] = "EnableMulticastLoopback"; fieldnames[13] = "EnableBroadcast"; fieldnames[14] = "EnablePortSharing"; fieldnames[15] = "IPAddressVersion"; fieldnames[16] = "Terminator"; } bool octave_udpport::has_property(const std::string &name) const { for (octave_idx_type i=0; i<fieldnames.numel(); i++) { if (fieldnames[i] == name) return true; } return false; } octave_value_list octave_udpport::subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; switch (type[0]) { default: error ("octave_udpport object cannot be indexed with %c", type[0]); return retval; case '.': { std::string property = (idx.front ()) (0).string_value (); if (!has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } else { octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); retval = OCTAVE__FEVAL (std::string ("__udpport_properties__"), ovl, 1); } } break; } if (idx.size () > 1 && type.length () > 1) retval = retval (0).next_subsref (nargout, type, idx, skip); return retval; } octave_value octave_udpport::subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs) { octave_value retval; switch (type[0]) { default: error ("octave_udpport object cannot be indexed with %c", type[0]); break; case '.': if (type.length () == 1) { std::string property = (idx.front ()) (0).string_value (); if (! has_property(property)) { error ("Unknown property '%s'", property.c_str()); return retval; } octave_value_list ovl; // inc ref count as assign this to octave_value OV_COUNT++; ovl (0) = octave_value (this); ovl (1) = (idx.front ()) (0); ovl (2) = rhs; OCTAVE__FEVAL (std::string ("__udpport_properties__"), ovl, 0); OV_COUNT++; retval = octave_value (this); } else if (type.length () > 1 && type[1] == '.') { // pass along any further assignments octave_value_list u = subsref (type.substr (0, 1), idx, 1); if (u.length () > 0) { std::list<octave_value_list> next_idx (idx); next_idx.erase (next_idx.begin ()); u (0).subsasgn(type.substr (1), next_idx, rhs); OV_COUNT++; retval = octave_value (this); } } else { error ("octave_udpport invalid index"); } } return retval; } int octave_udpport::open (const std::string &address, int port, int portshare) { int sockerr; name = "UDP-" + address; #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup (wVersionRequested, &wsaData ); if ( err != 0 ) { error( "could not initialize winsock library" ); return -1; } #endif // default size for now input_buffer = new uint8_t[1024]; buffer_len = 1024; buffer_pos = 0; memset (&read_addr, 0, sizeof (read_addr)); memset (&remote_addr, 0, sizeof (remote_addr)); remote_addr.sin_family = AF_INET; remote_addr.sin_port = 0; remote_addr.sin_addr.s_addr = htonl (INADDR_ANY); fd = socket (AF_INET, SOCK_DGRAM, 0); if (fd < 0) { error ("udpport: error opening socket : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_udpport::close (); return -1; } // port sharing enableportsharing = portshare; if(portshare) { #ifdef SO_REUSEPORT setsockopt(SOL_SOCKET, SO_REUSEPORT, (void*)&portshare, sizeof(portshare)); #else setsockopt(SOL_SOCKET, SO_REUSEADDR, (void*)&portshare, sizeof(portshare)); #endif } memset (&local_addr, 0, sizeof (local_addr)); if (address == "0.0.0.0") local_addr.sin_addr.s_addr = htonl (INADDR_ANY); else { lookup_addr(address, &local_addr); } local_addr.sin_family = AF_INET; local_addr.sin_port = htons (port); sockerr = bind (fd, (struct sockaddr*)&local_addr, sizeof (local_addr)); if (sockerr < 0) { error ("udpport: error on bind : %d - %s\n", SOCKETERR, STRSOCKETERR); octave_udpport::close (); return -1; } else if (port == 0) { // if said port, 0, lookup actual port it used socklen_t sz = sizeof (local_addr); getsockname (fd, (struct sockaddr*)&local_addr, &sz); } return get_fd(); } octave_udpport::~octave_udpport (void) { close(); } void octave_udpport::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_udpport::print (std::ostream& os, bool pr_as_read_syntax) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_udpport::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << " UDPPort Object " << get_name (); newline(os); os << " Type: " << get_type (); newline(os); os << " Status: " << get_status (); newline(os); os << " LocalHost: " << get_local_addr (); newline(os); os << " LocalPort: " << get_local_port (); newline (os); } int octave_udpport::get_bytesavailable () const { IOCTL_TYPE available = 0; if (get_fd () < 0) { return 0; } if (buffer_pos > 0) return buffer_pos; ioctl (get_fd (), FIONREAD, &available); return available; } int octave_udpport::getsockopt (int level, int opt, void *buf, socklen_t *len) { #ifndef __WIN32__ return ::getsockopt(get_fd(), level, opt, buf, len); #else return ::getsockopt(get_fd(), level, opt, (char *)buf, len); #endif } int octave_udpport::setsockopt (int level, int opt, const void *buf, socklen_t len) { #ifndef __WIN32__ return ::setsockopt(get_fd(), level, opt, buf, len); #else return ::setsockopt(get_fd(), level, opt, (const char *)buf, len); #endif } int octave_udpport::read (uint8_t *buf, unsigned int len, double readtimeout, sockaddr_in *rdinfo) { //struct sockaddr_in addr; socklen_t addrlen = sizeof (read_addr); struct timeval tv; fd_set readfds; if (get_fd () < 0) { error ("udpport_read: Interface must be opened first..."); return 0; } size_t bytes_read = 0; ssize_t read_retval = -1; // While not interrupted in blocking mode while (bytes_read < len) { OCTAVE_QUIT; // need get some data in the buffer if (buffer_pos == 0) { // need read some data first tv = to_timeval((readtimeout < 0 || readtimeout > 1000) ? 1000 : readtimeout); FD_ZERO (&readfds); FD_SET (get_fd (), &readfds); if (::select(get_fd ()+1, &readfds, NULL, NULL, &tv) < 0) { error("udpport_read: Error while reading/select: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } if (FD_ISSET (get_fd (), &readfds)) { int available = get_bytesavailable(); // alloc new buffer if (available > buffer_len) { // get nearest 1k over if can if (available + 1024 > 0) { available = (available + 1023); available &= ~0x3ff; } delete [] input_buffer; input_buffer = 0; input_buffer = new uint8_t[available]; buffer_len = available; } addrlen = sizeof (read_addr); read_retval = ::recvfrom (get_fd (), reinterpret_cast<char *>(input_buffer), buffer_len, 0, (struct sockaddr*)&read_addr, &addrlen); if (read_retval < 0) { error ("udpport_read: Error while reading: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else if (read_retval == 0) { error ("udpport_read: Connection lost: %d - %s\n", SOCKETERR, STRSOCKETERR); break; } else { buffer_pos = read_retval; } } else { // Timeout if (readtimeout >= 0) { // real timeout if (readtimeout <= 1000) break; // timed out 1 sec of an actual timeout else readtimeout -= 1000; } } } if (buffer_pos > 0) { if (len - bytes_read < buffer_pos) { read_retval = len - bytes_read; memcpy(&buf[bytes_read], input_buffer, read_retval); memmove(&input_buffer[0], &input_buffer[read_retval], buffer_pos-read_retval); buffer_pos -= read_retval; } else { read_retval = buffer_pos; memcpy(&buf[bytes_read], input_buffer, buffer_pos); buffer_pos = 0; } if (rdinfo) *rdinfo = read_addr; bytes_read += read_retval; } } return bytes_read; } int octave_udpport::write (const std::string &str, const std::string &destip, int destport) { if (get_fd () < 0) { error("udpport: Interface must be opened first..."); return -1; } if (destip.length() > 0) { sockaddr_in in; memset (&in, 0, sizeof (in)); in.sin_family = AF_INET; lookup_addr (destip, &in); in.sin_port = htons(destport); remote_addr = in; } else { if (remote_addr.sin_port == 0) { error("udpport: No destination address/port previously set"); return -1; } } int wrote = ::sendto (get_fd (), str.c_str(), str.length(), 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)); if(wrote > 0) byteswritten += wrote; return wrote; } int octave_udpport::write (uint8_t *buf, unsigned int len, const std::string &destip, int destport) { if (get_fd () < 0) { error("udpport: Interface must be opened first..."); return -1; } if (destip.length() > 0) { sockaddr_in in; memset (&in, 0, sizeof (in)); in.sin_family = AF_INET; lookup_addr (destip, &in); in.sin_port = htons(destport); remote_addr = in; } else { if (remote_addr.sin_port == 0) { error("udpport: No destination address/port previously set"); return -1; } } int wrote = ::sendto (get_fd(), reinterpret_cast<const char *>(buf), len, 0, (struct sockaddr *)&remote_addr, sizeof (remote_addr)); if(wrote > 0) byteswritten += wrote; return wrote; } int octave_udpport::set_timeout (double newtimeout) { if (get_fd () < 0) { error ("udpport: Interface must be opened first..."); return -1; } if (newtimeout < -1 ) { error ("udpport_timeout: timeout value must be -1 or positive"); return -1; } timeout = newtimeout; return 1; } int octave_udpport::get_remote_port (void) const { return ntohs (remote_addr.sin_port); } int octave_udpport::set_remote_port (int port) { if (port < 0 ) { error ("udpport_remote_port: value must be positive"); return -1; } remote_addr.sin_port = htons(port); return get_remote_port(); } std::string octave_udpport::get_remote_addr (void) const { return to_ip_str (&remote_addr); } std::string octave_udpport::set_remote_addr (const std::string &addr) { if (addr.length() == 0 ) { error ("udpport_remote_addr: value must be non empty"); } else if ( !lookup_addr(addr, &remote_addr)) { error ("udpport: error looking up remote host : %d - %s\n", SOCKETERR, STRSOCKETERR); } return to_ip_str (&remote_addr); } int octave_udpport::get_local_port (void) const { return ntohs (local_addr.sin_port); } std::string octave_udpport::get_local_addr (void) const { return to_ip_str (&local_addr); } std::string octave_udpport::set_name (const std::string &n) { if (n.length() == 0 ) { error ("udpport_name: value must be non empty"); } else { name = n; } return name; } bool octave_udpport::is_open (void) const { return fd >= 0; } std::string octave_udpport::get_status (void) const { if (! is_open ()) { return "closed"; } else { return "open"; } } int octave_udpport::close (void) { int retval = -1; if (get_fd() > 0) { #ifndef __WIN32__ retval = ::close (get_fd ()); #else retval = ::closesocket (get_fd ()); #endif fd = -1; } if (buffer_len) { delete [] input_buffer; buffer_len = 0; } return retval; } int octave_udpport::flush (int mode) { int retval = -1; if (get_fd() > 0) { uint8_t tmpbuffer[1024]; if (mode == 0 || mode == 2) { // we are sending data as we get it, so no outout // buffers to flush } if (mode == 1 || mode == 2) { while (read (tmpbuffer, 1024, 0) > 0) {} buffer_pos = 0; } } return retval; } int octave_udpport::set_enablebroadcast (int enable) { if (get_fd () < 0) { error ("udpport: Interface must be opened first..."); return -1; } enablebroadcast = enable; return setsockopt(SOL_SOCKET, SO_BROADCAST, (void*)&enable, sizeof(enable)); } int octave_udpport::set_multicastloopback (int enable) { if (get_fd () < 0) { error ("udpport: Interface must be opened first..."); return -1; } enablemulticastloopback = enable; return setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&enable, sizeof(enable)); } std::string octave_udpport::get_multicastgroup () const { if (multicastaddr.size() > 0) { sockaddr_in in = multicastaddr[0]; return to_ip_str (&in); } else return ""; } int octave_udpport::set_multicastgroup (const std::string &addr) { int retval = -1; if (get_fd() > 0) { if (addr == "off") { sockaddr_in in; for (int i=0; i<(int)multicastaddr.size (); i++) { struct ip_mreq multicastRequest; /* Multicast address join structure */ in = multicastaddr[i]; memcpy(&multicastRequest.imr_multiaddr, &in.sin_addr, sizeof(multicastRequest.imr_multiaddr)); multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*) &multicastRequest, sizeof(multicastRequest)); } multicastaddr.erase(multicastaddr.begin(), multicastaddr.end()); } else { sockaddr_in in; if (! lookup_addr (addr, &in)) { error ("Could not resolve address %s", addr.c_str()); } else { struct ip_mreq multicastRequest; /* Multicast address join structure */ memcpy(&multicastRequest.imr_multiaddr, &in.sin_addr, sizeof(multicastRequest.imr_multiaddr)); multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); /* Join the multicast address */ if ( setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &multicastRequest, sizeof(multicastRequest)) != 0 ) { error ("Failed to add address"); } else { // store address multicastaddr.push_back(in); retval = 1; } } } } return retval; } int octave_udpport::set_byteorder(const std::string& neworder) { std::string order = neworder; std::transform (order.begin (), order.end (), order.begin (), ::tolower); if (order == "big" || order == "big-endian") byteOrder = "big-endian"; else if (order == "little" || order == "little-endian") byteOrder = "little-endian"; else error ("octave_udpport invalid byteorder"); return 1; } int octave_udpport::set_input_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_udpport invalid input terminator"); else interminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_udpport invalid input terminator"); } else { interminator = octave_value(x); } } else error ("octave_udpport invalid input terminator"); return 1; } int octave_udpport::set_output_terminator(const octave_value& t) { if(t.is_string()) { std::string term = t.string_value(); std::transform (term.begin (), term.end (), term.begin (), ::tolower); if (term != "lf" && term != "cr" && term != "cr/lf") error ("octave_udpport invalid output terminator"); else outterminator = term; } else if(t.is_scalar_type()) { int x = t.int_value(); if(x < 0 || x > 255) { error ("octave_udpport invalid output terminator"); } else { outterminator = octave_value(x); } } else error ("octave_udpport invalid output terminator"); return 1; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/udpport/udpport_class.h������������������������������������������������0000644�0000000�0000000�00000012415�14743226261�017671� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2021 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #ifndef UDPPORT_CLASS_H #define UDPPORT_CLASS_H #include <octave/oct.h> #include <octave/ov-int32.h> #include <string> #include <vector> #ifndef __WIN32__ # include <netinet/in.h> #else # include <winsock2.h> typedef int socklen_t; #endif #ifdef HAVE_CONFIG_H # include "../config.h" #endif int to_ip_port (const sockaddr_in *in, std::string &ip, int &port); class octave_udpport : public OCTAVE_BASE_CLASS { public: octave_udpport (void); ~octave_udpport (void); int write (const std::string &str, const std::string &destip="", int destport=0); int write (uint8_t *buf, unsigned int len, const std::string &destip="", int destport=0); int read (uint8_t *buf, unsigned int len, double readtimeout, sockaddr_in *rdinfo=0); int getsockopt (int level, int opt, void *buf, socklen_t *len); int setsockopt (int level, int opt, const void *buf, socklen_t len); int open (const std::string &address, int port, int portshare); int close (void); int get_fd (void) const { return fd; } int get_bytesavailable (void) const; unsigned int get_byteswritten (void) const { return byteswritten; } // Overloaded base functions double udpport_value (void) const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true; } bool is_defined (void) const { return true; } // < 4.4 bool is_object (void) const { return true; } // 4.4 + bool isobject (void) const { return true; } // required to use subsasn string_vector map_keys (void) const { return fieldnames; } dim_vector dims (void) const { static dim_vector dv(1, 1); return dv; } // use single copy of each udpport socket octave_base_value * unique_clone (void) { OV_COUNT++; return this; } /** * overloaded methods to get properties */ octave_value_list subsref (const std::string& type, const std::list<octave_value_list>& idx, int nargout); octave_value subsref (const std::string& type, const std::list<octave_value_list>& idx) { octave_value_list retval = subsref (type, idx, 1); return (retval.length () > 0 ? retval(0) : octave_value ()); } octave_value subsasgn (const std::string& type, const std::list<octave_value_list>& idx, const octave_value& rhs); std::string get_name (void) const { return name; } std::string set_name (const std::string &); std::string get_remote_addr (void) const; std::string set_remote_addr (const std::string &); int get_remote_port (void) const; int set_remote_port (int); int get_local_port (void) const; std::string get_local_addr (void) const; bool is_open(void) const; std::string get_type (void) const { return "udpport"; } std::string get_status (void) const; int set_timeout (double); double get_timeout (void) const { return timeout; } int flush(int mode); int set_multicastgroup (const std::string &); std::string get_multicastgroup () const; int get_enableportsharing() const { return enableportsharing; } int get_enablebroadcast() const { return enablebroadcast; } int set_enablebroadcast (int enable); int get_multicastloopback() const { return enablemulticastloopback; } int set_multicastloopback (int enable); octave_value get_userdata () const { return userData; } void set_userdata (const octave_value &newv) { userData = newv; } std::string get_ipaddressversion () const { return "IPV4"; } int set_byteorder(const std::string& /* order */); std::string get_byteorder() const { return byteOrder; } int set_input_terminator(const octave_value& /* term */); int set_output_terminator(const octave_value& /* term */); octave_value get_input_terminator() const { return interminator; } octave_value get_output_terminator() const { return outterminator; } private: bool has_property(const std::string &name) const; uint8_t *input_buffer; int buffer_len; int buffer_pos; sockaddr_in read_addr; int fd; double timeout; std::string name; sockaddr_in remote_addr; sockaddr_in local_addr; string_vector fieldnames; std::vector<sockaddr_in> multicastaddr; octave_value userData; int enableportsharing; int enablemulticastloopback; int enablebroadcast; std::string byteOrder; unsigned int byteswritten; octave_value interminator; octave_value outterminator; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/undef-ah-octave.h������������������������������������������������������0000644�0000000�0000000�00000000706�14743226261�016260� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* To be included at the top of config.h (by autoheader). Avoid warnings for redefining AH-generated preprocessor symbols of Octave. */ #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_URL #undef PACKAGE_URL #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif ����������������������������������������������������������instrument-control-0.9.4/src/usbtmc/����������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014433� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/Makefile.in�����������������������������������������������������0000644�0000000�0000000�00000000306�14743226261�016477� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OCT := ../usbtmc.oct OBJ := usbtmc.o usbtmc_close.o usbtmc_write.o usbtmc_read.o usbtmc_class.o __usbtmc_pkg_lock__.o LFLAGS = $(LIBS) CFLAGS = $(CXXFLAGS) $(CPPFLAGS) @DEFS@ include ../common.mk ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/__usbtmc_pkg_lock__.cc������������������������������������������0000644�0000000�0000000�00000003001�14743226261�020676� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__usbtmc_pkg_lock__", "usbtmc.oct"); // PKG_ADD: __usbtmc_pkg_lock__(1); // PKG_DEL: __usbtmc_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__usbtmc_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__usbtmc_pkg_lock__")) interp.munlock("__usbtmc_pkg_lock__"); } return retval; } #else DEFUN_DLD(__usbtmc_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/usbtmc.cc�������������������������������������������������������0000644�0000000�0000000�00000004702�14743226261�016242� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John DOnoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_USBTMC #include <fcntl.h> #include "usbtmc_class.h" #endif // PKG_ADD: autoload ("usbtmc", "usbtmc.oct"); DEFUN_DLD (usbtmc, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{usbtmc} = } usbtmc (@var{path})\n \ \n\ Open usbtmc interface.\n \ \n\ @subsubheading Inputs\n \ @var{path} - the interface path of type String. If omitted defaults to '/dev/usbtmc0'.\n \ \n\ @subsubheading Outputs\n \ The usbtmc() shall return instance of @var{octave_usbtmc} class as the result @var{usbtmc}.\n \ @end deftypefn") { #ifndef BUILD_USBTMC error ("usbtmc: Your system doesn't support the USBTMC interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values int oflags = O_RDWR; std::string path ("/dev/usbtmc0"); // Parse the function arguments if (args.length () > 0) { if (args (0).is_string ()) { path = args (0).string_value (); } else { print_usage (); return octave_value (); } } octave_usbtmc* retval = new octave_usbtmc (); // Open the interface if (retval->open (path, oflags) < 0) return octave_value (); return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "usbtmc")) %! fail ("usbtmc ()", "Invalid call to usbtmc"); %! else %! fail ("usbtmc ()", "usbtmc: Your system doesn't support the USBTMC interface"); %! endif #endif ��������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/usbtmc_class.cc�������������������������������������������������0000644�0000000�0000000�00000005363�14743226261�017433� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_USBTMC #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <string> #include "usbtmc_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_usbtmc, "octave_usbtmc", "octave_usbtmc"); octave_usbtmc::octave_usbtmc (void) : fd (-1) { static bool type_registered = false; if (! type_registered) { type_registered = true; register_type (); } } octave_usbtmc::~octave_usbtmc (void) { octave_usbtmc::close(); } int octave_usbtmc::get_fd() const { return fd; } void octave_usbtmc::print (std::ostream& os, bool pr_as_read_syntax) { print_raw(os, pr_as_read_syntax); newline(os); } void octave_usbtmc::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw(os, pr_as_read_syntax); newline(os); } void octave_usbtmc::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << fd; } int octave_usbtmc::open (const std::string &path, int flags) { fd = ::open (path.c_str (), flags, 0); if (get_fd () < 0) { error ("usbtmc: Error opening the interface: %s\n", strerror (errno)); return -1; } return get_fd (); } int octave_usbtmc::read (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("usbtmc: Interface must be open first..."); return -1; } int retval = ::read (get_fd (), buf, len); if (retval < 0) error ("usbtmc: Failed to read from the usbtmc bus: %s\n", strerror (errno)); return retval; } int octave_usbtmc::write (uint8_t *buf, unsigned int len) { if (get_fd () < 0) { error ("usbtmc: Interface must be open first..."); return -1; } int retval = ::write (get_fd (), buf, len); if (retval < 0) error("usbtmc: Failed to write to the usbtmc bus: %s\n", strerror(errno)); return retval; } int octave_usbtmc::close (void) { int retval = -1; if (get_fd () > 0) { retval = ::close(get_fd ()); fd = -1; } return retval; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/usbtmc_class.h��������������������������������������������������0000644�0000000�0000000�00000003460�14743226261�017271� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef USBTMC_CLASS_H #define USBTMC_CLASS_H #include <octave/oct.h> #include <string> #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_usbtmc : public OCTAVE_BASE_CLASS { public: octave_usbtmc (void); ~octave_usbtmc(void); int open(const std::string&, int); int close(void); int get_fd(void) const; // Simple usbtmc commands int write(uint8_t*, unsigned int); int read(uint8_t*, unsigned int); // Overloaded base functions double usbtmc_value(void) const { return (double)fd; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)fd; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool print_as_scalar (void) const { return true;} private: int fd; DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/usbtmc_close.cc�������������������������������������������������0000644�0000000�0000000�00000003415�14743226261�017427� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John DOnoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_USBTMC #include "usbtmc_class.h" #endif // PKG_ADD: autoload ("usbtmc_close", "usbtmc.oct"); DEFUN_DLD (usbtmc_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} usbtmc_close (@var{usbtmc})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @subsubheading Inputs\n \ @var{usbtmc} - instance of @var{octave_usbtmc} class.\n \ @subsubheading Outputs\n \ None\n \ @end deftypefn") { #ifndef BUILD_USBTMC error ("usbtmc: Your system doesn't support the USBTMC interface"); return octave_value (); #else if (args.length () != 1 || args (0).type_id () != octave_usbtmc::static_type_id ()) { print_usage (); return octave_value (-1); } octave_usbtmc* usbtmc = NULL; const octave_base_value& rep = args (0).get_rep (); usbtmc = &((octave_usbtmc &)rep); usbtmc->close (); return octave_value (); #endif } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/usbtmc/usbtmc_read.cc��������������������������������������������������0000644�0000000�0000000�00000005750�14743226261�017241� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2017 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_USBTMC #include <octave/uint8NDArray.h> #include <errno.h> #include "usbtmc_class.h" #endif // PKG_ADD: autoload ("usbtmc_read", "usbtmc.oct"); DEFUN_DLD (usbtmc_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } usbtmc_read (@var{usbtmc}, @var{n})\n \ \n\ Read from usbtmc slave device.\n \ \n\ @subsubheading Inputs\n \ @var{usbtmc} - instance of @var{octave_usbtmc} class.@* \ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ @subsubheading Outputs\n \ @var{count} - the number of bytes successfully read as an Integer.@*\n \ @var{data} - the read bytes as a uint8 array.\n \ @end deftypefn") { #ifndef BUILD_USBTMC error ("usbtmc: Your system doesn't support the USBTMC interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_usbtmc::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 1; if (args.length () > 1) { if (! (args (1).OV_ISINTEGER () || args (1).OV_ISFLOAT ()) ) { print_usage (); return octave_value (-1); } buffer_len = args(1).int_value(); } OCTAVE_LOCAL_BUFFER (uint8_t, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("usbtmc_read: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } octave_usbtmc* usbtmc = NULL; const octave_base_value& rep = args (0).get_rep (); usbtmc = &((octave_usbtmc &)rep); int retval; retval = usbtmc->read (buffer, buffer_len); if (retval < 0) { // read has already displayed a message, so just exit return octave_value (-1); } octave_value_list return_list; uint8NDArray data (dim_vector (1, retval)); for (int i = 0; i < retval; i++) data (i) = buffer[i]; return_list (0) = data; return_list (1) = retval; return return_list; #endif } ������������������������instrument-control-0.9.4/src/usbtmc/usbtmc_write.cc�������������������������������������������������0000644�0000000�0000000�00000005421�14743226261�017453� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_USBTMC #include <errno.h> #include "usbtmc_class.h" #endif // PKG_ADD: autoload ("usbtmc_write", "usbtmc.oct"); DEFUN_DLD (usbtmc_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } usbtmc_write (@var{usbtmc}, @var{data})\n \ \n\ Write data to a usbtmc slave device.\n \ \n\ @subsubheading Inputs\n \ @var{usbtmc} - instance of @var{octave_usbtmc} class.@* \ @var{data} - data, of type uint8, to be written to the slave device.\n \ \n\ @subsubheading Outputs\n \ Upon successful completion, usbtmc_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_USBTMC error ("usbtmc: Your system doesn't support the USBTMC interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_usbtmc::static_type_id ()) { print_usage (); return octave_value (-1); } octave_usbtmc* usbtmc = NULL; int retval; const octave_base_value& rep = args (0).get_rep (); usbtmc = &((octave_usbtmc &)rep); const octave_base_value& data = args (1).get_rep (); if (data.is_string()) { std::string buf = data.string_value (); retval = usbtmc->write ((uint8_t*)buf.c_str (), buf.length ()); } else if (data.is_uint8_type ()) { NDArray dtmp = data.array_value (); OCTAVE_LOCAL_BUFFER (uint8_t, buf, (data.numel ())); if (buf == NULL) { error ("usbtmc_write: cannot allocate requested memory: %s\n", strerror (errno)); return octave_value (-1); } for (int i = 0; i < dtmp.numel (); i++) buf[i] = static_cast<uint8_t>(dtmp (i)); retval = usbtmc->write (buf, dtmp.numel ()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/�����������������������������������������������������������������0000755�0000000�0000000�00000000000�14743226261�014106� 5����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/Makefile.in������������������������������������������������������0000644�0000000�0000000�00000001344�14743226261�016155� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������VXI := vxi11_clnt.o vxi11_xdr.o OBJ := vxi11.o vxi11_write.o vxi11_close.o vxi11_read.o __vxi11_pkg_lock__.o OCT := ../vxi11.oct VXCLASS := vxi11_class.o RPCGEN ?= @RPCGEN@ RPCGENOPTS ?= @RPCGENOPTS@ LFLAGS = $(LIBS) CFLAGS += $(CPPFLAGS) @DEFS@ BUILD_VXI11 = @BUILD_VXI11@ RPC_GENERATED_FILES := vxi11.h vxi11_clnt.c vxi11_xdr.c ifneq (X$(BUILD_VXI11),X1) VXI = VXCLASS = else CFLAGS += @RPCINCLUDE@ LFLAGS += @RPCLIBS@ endif OBJ += $(VXI) $(VXCLASS) default: all $(RPC_GENERATED_FILES): vxi11.x $(RPCGEN) $(RPCGENOPTS) vxi11.x include ../common.mk extraclean: distclean rm -f $(RPC_GENERATED_FILES) ifeq (X$(BUILD_VXI11),X1) prebuild: $(RPC_GENERATED_FILES) else prebuild: endif .PHONY: prebuild extraclean ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/__vxi11_pkg_lock__.cc��������������������������������������������0000644�0000000�0000000�00000002771�14743226261�020041� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2019 John Donoghue <john.donoghue@ieee.org> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #include <octave/ov.h> #include <octave/defun-dld.h> #ifdef HAVE_CONFIG_H # include "../config.h" #endif #ifdef HAVE_OCTAVE_INTERPRETER_H # include <octave/interpreter.h> #endif // PKG_ADD: autoload ("__vxi11_pkg_lock__", "vxi11.oct"); // PKG_ADD: __vxi11_pkg_lock__(1); // PKG_DEL: __vxi11_pkg_lock__(0); #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (__vxi11_pkg_lock__, interp, args, , "internal function") { octave_value retval; if (args.length () >= 1) { if (args(0).int_value () == 1) interp.mlock(); else if (args(0).int_value () == 0 && interp.mislocked("__vxi11_pkg_lock__")) interp.munlock("__vxi11_pkg_lock__"); } return retval; } #else DEFUN_DLD(__vxi11_pkg_lock__, args, , "internal function") { octave_value retval; return retval; } #endif �������instrument-control-0.9.4/src/vxi11/vxi11.cc���������������������������������������������������������0000644�0000000�0000000�00000005255�14743226261�015374� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_VXI11 #include <errno.h> using std::string; #include "vxi11_class.h" #endif // PKG_ADD: autoload ("vxi11", "vxi11.oct"); DEFUN_DLD (vxi11, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{vxi11} = } vxi11 (@var{ip},@var{instr})\n \ \n\ Open vxi11 interface.\n \ \n\ @var{ip} - the ip address of type String. If omitted defaults to '127.0.0.1'.\n \ @var{instr} - the instrument name of type String. If omitted defaults to 'inst0'.\n \ \n\ The vxi11() shall return instance of @var{octave_vxi11} class as the result @var{vxi11}.\n \ @end deftypefn") { #ifndef BUILD_VXI11 error ("vxi11: Your system doesn't support the VXI11 interface"); return octave_value (); #else // Do not open interface if return value is not assigned if (nargout != 1) { print_usage (); return octave_value (); } // Default values string path ("127.0.0.1"); string device ("inst0"); // Parse the function arguments if (args.length () > 0) { if (args(0).is_string ()) { path = args (0).string_value (); if (args.length () > 1) { if (args(1).is_string ()) { device = args (1).string_value (); } } } else { print_usage (); return octave_value (); } } // Open the interface octave_vxi11* retval = new octave_vxi11; if (retval->open (path, device) < 0) { error("vxi11: Error opening the interface: %s\n", strerror (errno)); return octave_value (); } return octave_value (retval); #endif } #if 0 %!test %! if any(strcmp(instrhwinfo().SupportedInterfaces, "vxi11")) %! fail ("vxi11 ()", "Invalid call to vxi11"); %! else %! fail ("vxi11 ()", "vxi11: Your system doesn't support the VXI11 interface"); %! endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/vxi11.x����������������������������������������������������������0000644�0000000�0000000�00000013730�14743226261�015253� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% %/* VXI-11 RPCL definitions. Taken from appendix C of the VXI-11 specfication. % * See http://www.vxi.org % */ %#include <strings.h> %#include <stdlib.h> % %/* VXI-11 flags */ %#define VXI11_FLAG_WAITLOCK 0x01 %#define VXI11_FLAG_ENDW 0x08 %#define VXI11_FLAG_TERMCHRSET 0x80 % %/* VXI-11 device_docmd 'cmd' values */ %#define VXI11_DOCMD_SEND_COMMAND 0x020000 %#define VXI11_DOCMD_BUS_STATUS 0x020001 %#define VXI11_DOCMD_ATN_CONTROL 0x020002 %#define VXI11_DOCMD_REN_CONTROL 0x020003 %#define VXI11_DOCMD_PASS_CONTROL 0x020004 %#define VXI11_DOCMD_BUS_ADDRESS 0x02000A %#define VXI11_DOCMD_IFC_CONTROL 0x020010 % %/* VXI-11 device_docmd Bus Status values */ %#define VXI11_DOCMD_STAT_REMOTE 1 %#define VXI11_DOCMD_STAT_SRQ 2 %#define VXI11_DOCMD_STAT_NDAC 3 %#define VXI11_DOCMD_STAT_SYS_CTRLR 4 %#define VXI11_DOCMD_STAT_CTRLR_CHRG 5 %#define VXI11_DOCMD_STAT_TALKER 6 %#define VXI11_DOCMD_STAT_LISTENER 7 %#define VXI11_DOCMD_STAT_BUSADDR 8 % %/* VXI-11 device_read 'reason' bits */ %#define VXI11_REASON_REQCNT 1 /* requested number of bytes read */ %#define VXI11_REASON_CHR 2 /* read terminated by eos character */ %#define VXI11_REASON_END 4 /* read terminated by EOI */ % %/* VXI-11 errors */ %#define VXI11_ERR_SUCCESS 0 %#define VXI11_ERR_SYNTAX 1 %#define VXI11_ERR_NODEVICE 3 %#define VXI11_ERR_LINKINVAL 4 %#define VXI11_ERR_PARAMETER 5 %#define VXI11_ERR_NOCHAN 6 %#define VXI11_ERR_NOTSUPP 8 %#define VXI11_ERR_RESOURCES 9 %#define VXI11_ERR_LOCKED 11 %#define VXI11_ERR_NOLOCK 12 %#define VXI11_ERR_IOTIMEOUT 15 %#define VXI11_ERR_IOERROR 17 %#define VXI11_ERR_ADDRINVAL 21 %#define VXI11_ERR_ABORT 23 %#define VXI11_ERR_CHANEST 29 /* Types */ typedef long Device_Link; enum Device_AddrFamily { /* used by interrupts */ DEVICE_TCP, DEVICE_UDP }; typedef long Device_Flags; /* Error types */ typedef long Device_ErrorCode; struct Device_Error { Device_ErrorCode error; }; struct Create_LinkParms { long clientId; /* implementation specific value */ bool lockDevice; /* attempt to lock the device */ unsigned long lock_timeout; /* time to wait on a lock */ string device<>; /* name of device */ }; struct Create_LinkResp { Device_ErrorCode error; Device_Link lid; unsigned short abortPort; /* for the abort RPC */ unsigned long maxRecvSize; /* specifies max data size in bytes device will accept on a write */ }; struct Device_WriteParms { Device_Link lid; /* link id from create_link */ unsigned long io_timeout; /* time to wait for I/O */ unsigned long lock_timeout; /* time to wait for lock */ Device_Flags flags; opaque data<>; /* the data length and the data itself */ }; struct Device_WriteResp { Device_ErrorCode error; unsigned long size; /* Number of bytes written */ }; struct Device_ReadParms { Device_Link lid; /* link id from create_link */ unsigned long requestSize; /* Bytes requested */ unsigned long io_timeout; /* time to wait for I/O */ unsigned long lock_timeout; /* time to wait for lock */ Device_Flags flags; char termChar; /* valid if flags & termchrset */ }; struct Device_ReadResp { Device_ErrorCode error; long reason; /* Reason(s) read completed */ opaque data<>; /* data.len and data.val */ }; struct Device_ReadStbResp { Device_ErrorCode error; /* error code */ unsigned char stb; /* the returned status byte */ }; struct Device_GenericParms { Device_Link lid; /* Device_Link id from connect call */ Device_Flags flags; /* flags with options */ unsigned long lock_timeout; /* time to wait for lock */ unsigned long io_timeout; /* time to wait for I/O */ }; struct Device_RemoteFunc { unsigned long hostAddr; /* Host servicing Interrupt */ unsigned short hostPort; /* valid port # on client */ unsigned long progNum; /* DEVICE_INTR */ unsigned long progVers; /* DEVICE_INTR_VERSION */ Device_AddrFamily progFamily; /* DEVICE_UDP | DEVICE_TCP */ }; struct Device_EnableSrqParms { Device_Link lid; bool enable; /* Enable or disable interrupts */ opaque handle<40>; /* Host specific data */ }; struct Device_LockParms { Device_Link lid; /* link id from create_link */ Device_Flags flags; /* Contains the waitlock flag */ unsigned long lock_timeout; /* time to wait to acquire lock */ }; struct Device_DocmdParms { Device_Link lid; /* link id from create_link */ Device_Flags flags; /* flags specifying various options */ unsigned long io_timeout; /* time to wait for I/O to complete */ unsigned long lock_timeout; /* time to wait on a lock */ long cmd; /* which command to execute */ bool network_order; /* client's byte order */ long datasize; /* size of individual data elements */ opaque data_in<>; /* docmd data parameters */ }; struct Device_DocmdResp { Device_ErrorCode error; /* returned status */ opaque data_out<>; /* returned data parameter */ }; program DEVICE_ASYNC{ version DEVICE_ASYNC_VERSION { Device_Error device_abort (Device_Link) = 1; } = 1; } = 0x0607B0; program DEVICE_CORE { version DEVICE_CORE_VERSION { Create_LinkResp create_link (Create_LinkParms) = 10; Device_WriteResp device_write (Device_WriteParms) = 11; Device_ReadResp device_read (Device_ReadParms) = 12; Device_ReadStbResp device_readstb (Device_GenericParms) = 13; Device_Error device_trigger (Device_GenericParms) = 14; Device_Error device_clear (Device_GenericParms) = 15; Device_Error device_remote (Device_GenericParms) = 16; Device_Error device_local (Device_GenericParms) = 17; Device_Error device_lock (Device_LockParms) = 18; Device_Error device_unlock (Device_Link) = 19; Device_Error device_enable_srq (Device_EnableSrqParms) = 20; Device_DocmdResp device_docmd (Device_DocmdParms) = 22; Device_Error destroy_link (Device_Link) = 23; Device_Error create_intr_chan (Device_RemoteFunc) = 25; Device_Error destroy_intr_chan (void) = 26; } = 1; } = 0x0607AF; ����������������������������������������instrument-control-0.9.4/src/vxi11/vxi11_class.cc���������������������������������������������������0000644�0000000�0000000�00000024277�14743226261�016566� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. // // VXI11 functions are copied from Steve D. Sharples VXI11 library // see http://optics.eee.nottingham.ac.uk/vxi11/ // #include <octave/oct.h> #include <string> #include <cstring> // open or close vxi11 session only on call of vxi11 or vxi11_close #define OPENONCE using std::string; #include "vxi11_class.h" DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_vxi11, "octave_vxi11", "octave_vxi11"); #define VXI11_DEFAULT_TIMEOUT 10000 /* in ms */ #define VXI11_READ_TIMEOUT 2000 /* in ms */ #define VXI11_MAX_CLIENTS 256 /* maximum no of unique IP addresses/clients */ #define VXI11_NULL_READ_RESP 50 /* vxi11_receive() return value if a query * times out ON THE INSTRUMENT (and so we have * to resend the query again) */ #define VXI11_NULL_WRITE_RESP 51 /* vxi11_send() return value if a sent command * times out ON THE INSTURMENT. */ octave_vxi11::octave_vxi11 (void) { static bool type_registered = false; this->ip = ""; if (! type_registered) { type_registered = true; register_type (); } } octave_vxi11::~octave_vxi11 (void) { this->close (); } void octave_vxi11::print (std::ostream& os, bool pr_as_read_syntax) { print_raw (os, pr_as_read_syntax); newline (os); } void octave_vxi11::print (std::ostream& os, bool pr_as_read_syntax ) const { print_raw (os, pr_as_read_syntax); newline (os); } void octave_vxi11::print_raw (std::ostream& os, bool pr_as_read_syntax) const { os << this->ip; } int octave_vxi11::open (string ip, string inst) { this->ip=ip; this->inst=inst; #ifdef OPENONCE if (this->openvxi (this->ip.c_str(),&this->client,&this->link,this->inst.c_str())) { error ("vxi11: Cannot open VXI11..."); return -1; } #endif return 0; } int octave_vxi11::read(char *buf, unsigned int len) { CLIENT *client; Create_LinkResp *link; unsigned long timeout = VXI11_READ_TIMEOUT; if (this->ip.empty()) { error("vxi11: setup ip first"); return -1; } #ifdef OPENONCE client = this->client; link = this->link; #else //std::string inst="inst0"; if (this->openvxi(this->ip.c_str(),&client,&link,this->inst.c_str())) { error("vxi11: Cannot open VXI11..."); return -1; } #endif #define RCV_END_BIT 0x04 // An end indicator has been read #define RCV_CHR_BIT 0x02 // A termchr is set in flags and a character which matches termChar is transferred #define RCV_REQCNT_BIT 0x01 // requestSize bytes have been transferred. This includes a request size of zero. //long vxi11_receive(CLIENT *client, VXI11_LINK *link, char *buffer, unsigned long len, unsigned long timeout) { Device_ReadParms read_parms; Device_ReadResp read_resp; unsigned int curr_pos = 0; read_parms.lid = link->lid; read_parms.requestSize = len; read_parms.io_timeout = timeout; /* in ms */ read_parms.lock_timeout = timeout; /* in ms */ read_parms.flags = 0; read_parms.termChar = 0; do { memset(&read_resp, 0, sizeof(read_resp)); read_resp.data.data_val = buf + curr_pos; read_parms.requestSize = len - curr_pos; // Never request more total data than originally specified in len if(device_read_1(&read_parms, &read_resp, client) != RPC_SUCCESS) { error ("vxi11: cannot read"); return -1; /* there is nothing to read. Usually occurs after sending a query which times out on the instrument. If we don't check this first, then the following line causes a seg fault */ } if (read_resp.error != 0) { /* Read failed for reason specified in error code. * (From published VXI-11 protocol, section B.5.2) * 0 no error * 1 syntax error * 3 device not accessible * 4 invalid link identifier * 5 parameter error * 6 channel not established * 8 operation not supported * 9 out of resources * 11 device locked by another link * 12 no lock held by this link * 15 I/O timeout * 17 I/O error * 21 invalid address * 23 abort * 29 channel already established */ error ("vxi11: cannot read: %d",(int)read_resp.error); return -1; } if ((curr_pos + read_resp.data.data_len) <= len) { curr_pos += read_resp.data.data_len; } if( (read_resp.reason & RCV_END_BIT) || (read_resp.reason & RCV_CHR_BIT) ) { break; } else if( curr_pos == len ) { error ("xvi11: read error: buffer too small. Read %d bytes without hitting terminator.", (int)curr_pos ); return -1; } } while (1); #ifndef OPENONCE // close VXI11 session if (this->closevxi (this->ip.c_str (),client,link)) { error ("vxi11:Cannot close VXI11..."); return -1; } #endif return curr_pos; } int octave_vxi11::write (const char *buf, int len) { CLIENT *client; Create_LinkResp *link; if (this->ip.empty ()) { error ("vxi11: setup ip first"); return -1; } #ifdef OPENONCE client = this->client; link = this->link; #else //std::string inst="inst0"; if (this->openvxi (this->ip.c_str (),&client,&link,this->inst.c_str ())) { error ("vxi11: Cannot open VXI11..."); return -1; } #endif //int vxi11_send(CLIENT *client, VXI11_LINK *link, const char *cmd, unsigned long len) { Device_WriteParms write_parms; unsigned int bytes_left = len; char *send_cmd; send_cmd = new char[len]; memcpy (send_cmd, buf, len); write_parms.lid = link->lid; write_parms.io_timeout = VXI11_DEFAULT_TIMEOUT; write_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; /* We can only write (link->maxRecvSize) bytes at a time, so we sit in a loop, * writing a chunk at a time, until we're done. */ do { Device_WriteResp write_resp; memset(&write_resp, 0, sizeof(write_resp)); if (bytes_left <= link->maxRecvSize) { write_parms.flags = 8; write_parms.data.data_len = bytes_left; } else { write_parms.flags = 0; /* We need to check that maxRecvSize is a sane value (ie >0). Believe it * or not, on some versions of Agilent Infiniium scope firmware the scope * returned "0", which breaks Rule B.6.3 of the VXI-11 protocol. Nevertheless * we need to catch this, otherwise the program just hangs. */ if (link->maxRecvSize > 0) { write_parms.data.data_len = link->maxRecvSize; } else { write_parms.data.data_len = 4096; /* pretty much anything should be able to cope with 4kB */ } } write_parms.data.data_val = send_cmd + (len - bytes_left); if(device_write_1 (&write_parms, &write_resp, client) != RPC_SUCCESS) { delete[] send_cmd; error ("vxi11: cannot write"); return -VXI11_NULL_WRITE_RESP; /* The instrument did not acknowledge the write, just completely dropped it. There was no vxi11 comms error as such, the instrument is just being rude. Usually occurs when the instrument is busy. If we don't check this first, then the following line causes a seg fault */ } if (write_resp.error != 0) { error("vxi11_user: write error: %d", (int)write_resp.error); delete[] send_cmd; return -(write_resp.error); } bytes_left -= write_resp.size; } while (bytes_left > 0); delete[] send_cmd; #ifndef OPENONCE // close VXI11 session if (this->closevxi (this->ip.c_str (),client,link)) { error ("vxi11:Cannot close VXI11..."); return -1; } #endif return 0; } int octave_vxi11::close (void) { int retval = 0; #ifdef OPENONCE // close VXI11 session if (!this->ip.empty()) { if (this->closevxi (this->ip.c_str (),this->client,this->link)) { error ("vxi11:Cannot close VXI11..."); return -1; } } #endif this->ip = ""; return retval; } int octave_vxi11::openvxi (const char *ip, CLIENT **client, Create_LinkResp **link, const char *device) { #ifdef CONST_CLNT_SUPPORT const char * tmpip = ip; #else char tmpip[256]; strncpy(tmpip, ip, 250); tmpip[250] = '\0'; #endif *client = clnt_create(tmpip, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp"); if (*client == NULL) { clnt_pcreateerror (tmpip); error ("vxi11: Error creating client..."); return -1; } Create_LinkParms link_parms; /* Set link parameters */ link_parms.clientId = (long) *client; link_parms.lockDevice = 0; link_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; link_parms.device = (char *) device; *link = (Create_LinkResp *) calloc (1, sizeof(Create_LinkResp)); if (create_link_1 (&link_parms, *link, *client) != RPC_SUCCESS) { clnt_perror (*client, tmpip); error ("vxi11: Error creating client..."); return -2; } return 0; } int octave_vxi11::closevxi (const char *ip, CLIENT *client, Create_LinkResp *link) { Device_Error dev_error; memset (&dev_error, 0, sizeof(dev_error)); if (destroy_link_1 (&link->lid, &dev_error, client) != RPC_SUCCESS) { #ifdef CONST_CLNT_SUPPORT const char * tmpip = ip; #else char tmpip[256]; strncpy(tmpip, ip, 250); tmpip[250] = '\0'; #endif clnt_perror (client, tmpip); return -1; } clnt_destroy (client); return 0; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/vxi11_class.h����������������������������������������������������0000644�0000000�0000000�00000004143�14743226261�016416� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #ifndef VXI11_CLASS_H #define VXI11_CLASS_H #include <octave/oct.h> #include <rpc/rpc.h> #include "vxi11.h" #include <string> using std::string; #ifdef HAVE_CONFIG_H # include "../config.h" #endif class octave_vxi11 : public OCTAVE_BASE_CLASS { public: octave_vxi11 (void); ~octave_vxi11 (void); int open (string, string); int close (void); // Simple vxi11 commands int write (const char*, int); int read (char*, unsigned int); // Overloaded base functions string vxi11_value () const { return (string)this->ip; } virtual double scalar_value (bool frc_str_conv = false) const { return (double)0; } void print (std::ostream& os, bool pr_as_read_syntax = false); void print (std::ostream& os, bool pr_as_read_syntax = false) const; void print_raw (std::ostream& os, bool pr_as_read_syntax) const; // Properties bool is_constant (void) const { return true;} bool is_defined (void) const { return true;} bool print_as_scalar (void) const { return true;} private: CLIENT *client; Create_LinkResp *link; std::string ip; std::string inst; std::string device; int openvxi (const char *, CLIENT **, Create_LinkResp **, const char *); int closevxi (const char *, CLIENT *, Create_LinkResp *); DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/vxi11_close.cc���������������������������������������������������0000644�0000000�0000000�00000003171�14743226261�016554� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_VXI11 #include "vxi11_class.h" #endif // PKG_ADD: autoload ("vxi11_close", "vxi11.oct"); DEFUN_DLD (vxi11_close, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} vxi11_close (@var{vxi11})\n \ \n\ Close the interface and release a file descriptor.\n \ \n\ @var{vxi11} - instance of @var{octave_vxi11} class.\n \ @end deftypefn") { #ifndef BUILD_VXI11 error ("vxi11: Your system doesn't support the VXI11 interface"); return octave_value(); #else if (args.length () != 1 || args (0).type_id () != octave_vxi11::static_type_id()) { print_usage (); return octave_value (-1); } octave_vxi11* vxi11 = NULL; const octave_base_value& rep = args (0).get_rep (); vxi11 = &((octave_vxi11 &)rep); vxi11->close (); return octave_value (); #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/vxi11_read.cc����������������������������������������������������0000644�0000000�0000000�00000005261�14743226261�016364� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_VXI11 #include <octave/uint8NDArray.h> #include "vxi11_class.h" #endif // PKG_ADD: autoload ("vxi11_read", "vxi11.oct"); DEFUN_DLD (vxi11_read, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{data}, @var{count}] = } vxi11_read (@var{vxi11}, @var{n})\n \ \n\ Read from vxi11 slave device.\n \ \n\ @var{vxi11} - instance of @var{octave_vxi11} class.@* \ @var{n} - number of bytes to attempt to read of type Integer.\n \ \n\ The vxi11_read() shall return number of bytes successfully read in @var{count} as Integer and the bytes themselves in @var{data} as uint8 array.\n \ @end deftypefn") { #ifndef BUILD_VXI11 error ("vxi11: Your system doesn't support the VXI11 interface"); return octave_value (); #else if (args.length () < 1 || args.length () > 2 || args (0).type_id () != octave_vxi11::static_type_id ()) { print_usage (); return octave_value (-1); } unsigned int buffer_len = 1; if (args.length () > 1) { if ( !(args (1).OV_ISINTEGER() || args (1).OV_ISFLOAT()) ) { print_usage (); return octave_value (-1); } buffer_len = args (1).int_value (); } OCTAVE_LOCAL_BUFFER (char, buffer, (buffer_len + 1)); if (buffer == NULL) { error ("vxi11_read: cannot allocate requested memory..."); return octave_value (-1); } octave_vxi11* vxi11 = NULL; const octave_base_value& rep = args(0).get_rep(); vxi11 = &((octave_vxi11 &)rep); int retval; retval = vxi11->read (buffer, buffer_len); octave_value_list return_list; uint8NDArray data( dim_vector(1, (retval > 0) ? retval : 0) ); for (int i = 0; i < retval; i++) data(i) = static_cast<uint8_t>(buffer[i]); return_list (0) = data; return_list (1) = retval; return return_list; #endif } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������instrument-control-0.9.4/src/vxi11/vxi11_write.cc���������������������������������������������������0000644�0000000�0000000�00000004670�14743226261�016606� 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2018 John Donoghue <john.donoghue@ieee.org> // Copyright (C) 2013 Stefan Mahr <dac922@gmx.de> // Copyright (C) 2012 Andrius Sutas <andrius.sutas@gmail.com> // // 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 <http://www.gnu.org/licenses/>. #include <octave/oct.h> #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef BUILD_VXI11 #include "vxi11_class.h" #endif // PKG_ADD: autoload ("vxi11_write", "vxi11.oct"); DEFUN_DLD (vxi11_write, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{n} = } vxi11_write (@var{vxi11}, @var{data})\n \ \n\ Write data to a vxi11 slave device.\n \ \n\ @var{vxi11} - instance of @var{octave_vxi11} class.@* \ @var{data} - data to be written to the slave device. Can be either of String or uint8 type.\n \ \n\ Upon successful completion, vxi11_write() shall return the number of bytes written as the result @var{n}.\n \ @end deftypefn") { #ifndef BUILD_VXI11 error ("vxi11: Your system doesn't support the VXI11 interface"); return octave_value (); #else if (args.length () != 2 || args (0).type_id () != octave_vxi11::static_type_id ()) { print_usage (); return octave_value (-1); } octave_vxi11* vxi11 = NULL; const octave_base_value& rep = args (0).get_rep (); vxi11 = &((octave_vxi11 &)rep); const octave_base_value& data = args (1).get_rep (); int retval; if (data.is_string ()) { string buf = data.string_value (); retval = vxi11->write (buf.c_str (), buf.length ()); } else if (data.is_uint8_type ()) { NDArray dtmp = data.array_value (); OCTAVE_LOCAL_BUFFER (char, buf, (dtmp.numel ())); for (int i = 0; i < dtmp.numel (); i++) buf[i] = (char)dtmp(i); retval = vxi11->write (buf, data.byte_size()); } else { print_usage (); return octave_value (-1); } return octave_value (retval); #endif } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������