aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS7
-rw-r--r--COPYING699
-rw-r--r--INSTALL59
-rw-r--r--NEWS14
-rw-r--r--README13
-rw-r--r--blop.lv2/adsr.ttl82
-rw-r--r--blop.lv2/adsr_gt.ttl91
-rw-r--r--blop.lv2/amp.ttl49
-rw-r--r--blop.lv2/branch.ttl54
-rw-r--r--blop.lv2/dahdsr.ttl128
-rw-r--r--blop.lv2/difference.ttl51
-rw-r--r--blop.lv2/fmod.ttl60
-rw-r--r--blop.lv2/interpolator.ttl32
-rw-r--r--blop.lv2/lp4pole.ttl64
-rw-r--r--blop.lv2/manifest.ttl.in155
-rw-r--r--blop.lv2/product.ttl50
-rw-r--r--blop.lv2/pulse.ttl60
-rw-r--r--blop.lv2/quantiser_100.ttl719
-rw-r--r--blop.lv2/quantiser_20.ttl239
-rw-r--r--blop.lv2/quantiser_50.ttl419
-rw-r--r--blop.lv2/random.ttl64
-rw-r--r--blop.lv2/ratio.ttl52
-rw-r--r--blop.lv2/sawtooth.ttl46
-rw-r--r--blop.lv2/sequencer_16.ttl167
-rw-r--r--blop.lv2/sequencer_32.ttl263
-rw-r--r--blop.lv2/sequencer_64.ttl455
-rw-r--r--blop.lv2/square.ttl46
-rw-r--r--blop.lv2/sum.ttl50
-rw-r--r--blop.lv2/sync_pulse.ttl63
-rw-r--r--blop.lv2/sync_square.ttl55
-rw-r--r--blop.lv2/tracker.ttl122
-rw-r--r--blop.lv2/triangle.ttl61
-rw-r--r--src/adsr.c259
-rw-r--r--src/adsr_gt.c266
-rw-r--r--src/amp.c166
-rw-r--r--src/branch.c223
-rw-r--r--src/dahdsr.c416
-rw-r--r--src/difference.c188
-rw-r--r--src/fmod.c199
-rw-r--r--src/include/common.h54
-rw-r--r--src/include/interpolate.h74
-rw-r--r--src/include/lp4pole_filter.h137
-rw-r--r--src/include/math_func.h48
-rw-r--r--src/include/uris.h59
-rw-r--r--src/include/vector_op.h44
-rw-r--r--src/include/wavedata.h193
-rw-r--r--src/include/wdatutil.h141
-rw-r--r--src/interpolator.c144
-rw-r--r--src/lp4pole.c206
-rw-r--r--src/lp4pole_filter.c55
-rw-r--r--src/product.c187
-rw-r--r--src/pulse.c225
-rw-r--r--src/quantiser.c461
-rw-r--r--src/random.c237
-rw-r--r--src/ratio.c202
-rw-r--r--src/sawtooth.c194
-rw-r--r--src/sequencer.c216
-rw-r--r--src/square.c195
-rw-r--r--src/sum.c185
-rw-r--r--src/sync_pulse.c213
-rw-r--r--src/sync_square.c201
-rw-r--r--src/tracker.c245
-rw-r--r--src/triangle.c232
-rw-r--r--src/wavedata.c79
-rw-r--r--src/wavegen.c310
-rw-r--r--src/wdatutil.c679
-rwxr-xr-xwaf171
-rw-r--r--waflib/.gitignore (renamed from .gitignore)0
-rw-r--r--waflib/Build.py (renamed from Build.py)0
-rw-r--r--waflib/COPYING25
-rw-r--r--waflib/ConfigSet.py (renamed from ConfigSet.py)0
-rw-r--r--waflib/Configure.py (renamed from Configure.py)0
-rw-r--r--waflib/Context.py (renamed from Context.py)0
-rw-r--r--waflib/Errors.py (renamed from Errors.py)0
-rw-r--r--waflib/Logs.py (renamed from Logs.py)0
-rw-r--r--waflib/Node.py (renamed from Node.py)0
-rw-r--r--waflib/Options.py (renamed from Options.py)0
-rw-r--r--waflib/README.md (renamed from README.md)0
-rw-r--r--waflib/Runner.py (renamed from Runner.py)0
-rw-r--r--waflib/Scripting.py (renamed from Scripting.py)0
-rw-r--r--waflib/Task.py (renamed from Task.py)0
-rw-r--r--waflib/TaskGen.py (renamed from TaskGen.py)0
-rw-r--r--waflib/Tools/__init__.py (renamed from Tools/__init__.py)0
-rw-r--r--waflib/Tools/ar.py (renamed from Tools/ar.py)0
-rw-r--r--waflib/Tools/asm.py (renamed from Tools/asm.py)0
-rw-r--r--waflib/Tools/bison.py (renamed from Tools/bison.py)0
-rw-r--r--waflib/Tools/c.py (renamed from Tools/c.py)0
-rw-r--r--waflib/Tools/c_aliases.py (renamed from Tools/c_aliases.py)0
-rw-r--r--waflib/Tools/c_config.py (renamed from Tools/c_config.py)0
-rw-r--r--waflib/Tools/c_osx.py (renamed from Tools/c_osx.py)0
-rw-r--r--waflib/Tools/c_preproc.py (renamed from Tools/c_preproc.py)0
-rw-r--r--waflib/Tools/c_tests.py (renamed from Tools/c_tests.py)0
-rw-r--r--waflib/Tools/ccroot.py (renamed from Tools/ccroot.py)0
-rw-r--r--waflib/Tools/clang.py (renamed from Tools/clang.py)0
-rw-r--r--waflib/Tools/clangxx.py (renamed from Tools/clangxx.py)0
-rw-r--r--waflib/Tools/compiler_c.py (renamed from Tools/compiler_c.py)0
-rw-r--r--waflib/Tools/compiler_cxx.py (renamed from Tools/compiler_cxx.py)0
-rw-r--r--waflib/Tools/compiler_d.py (renamed from Tools/compiler_d.py)0
-rw-r--r--waflib/Tools/compiler_fc.py (renamed from Tools/compiler_fc.py)0
-rw-r--r--waflib/Tools/cs.py (renamed from Tools/cs.py)0
-rw-r--r--waflib/Tools/cxx.py (renamed from Tools/cxx.py)0
-rw-r--r--waflib/Tools/d.py (renamed from Tools/d.py)0
-rw-r--r--waflib/Tools/d_config.py (renamed from Tools/d_config.py)0
-rw-r--r--waflib/Tools/d_scan.py (renamed from Tools/d_scan.py)0
-rw-r--r--waflib/Tools/dbus.py (renamed from Tools/dbus.py)0
-rw-r--r--waflib/Tools/dmd.py (renamed from Tools/dmd.py)0
-rw-r--r--waflib/Tools/errcheck.py (renamed from Tools/errcheck.py)0
-rw-r--r--waflib/Tools/fc.py (renamed from Tools/fc.py)0
-rw-r--r--waflib/Tools/fc_config.py (renamed from Tools/fc_config.py)0
-rw-r--r--waflib/Tools/fc_scan.py (renamed from Tools/fc_scan.py)0
-rw-r--r--waflib/Tools/flex.py (renamed from Tools/flex.py)0
-rw-r--r--waflib/Tools/g95.py (renamed from Tools/g95.py)0
-rw-r--r--waflib/Tools/gas.py (renamed from Tools/gas.py)0
-rw-r--r--waflib/Tools/gcc.py (renamed from Tools/gcc.py)0
-rw-r--r--waflib/Tools/gdc.py (renamed from Tools/gdc.py)0
-rw-r--r--waflib/Tools/gfortran.py (renamed from Tools/gfortran.py)0
-rw-r--r--waflib/Tools/glib2.py (renamed from Tools/glib2.py)0
-rw-r--r--waflib/Tools/gnu_dirs.py (renamed from Tools/gnu_dirs.py)0
-rw-r--r--waflib/Tools/gxx.py (renamed from Tools/gxx.py)0
-rw-r--r--waflib/Tools/icc.py (renamed from Tools/icc.py)0
-rw-r--r--waflib/Tools/icpc.py (renamed from Tools/icpc.py)0
-rw-r--r--waflib/Tools/ifort.py (renamed from Tools/ifort.py)0
-rw-r--r--waflib/Tools/intltool.py (renamed from Tools/intltool.py)0
-rw-r--r--waflib/Tools/irixcc.py (renamed from Tools/irixcc.py)0
-rw-r--r--waflib/Tools/javaw.py (renamed from Tools/javaw.py)0
-rw-r--r--waflib/Tools/ldc2.py (renamed from Tools/ldc2.py)0
-rw-r--r--waflib/Tools/lua.py (renamed from Tools/lua.py)0
-rw-r--r--waflib/Tools/md5_tstamp.py (renamed from Tools/md5_tstamp.py)0
-rw-r--r--waflib/Tools/msvc.py (renamed from Tools/msvc.py)0
-rw-r--r--waflib/Tools/nasm.py (renamed from Tools/nasm.py)0
-rw-r--r--waflib/Tools/nobuild.py (renamed from Tools/nobuild.py)0
-rw-r--r--waflib/Tools/perl.py (renamed from Tools/perl.py)0
-rw-r--r--waflib/Tools/python.py (renamed from Tools/python.py)0
-rw-r--r--waflib/Tools/qt5.py (renamed from Tools/qt5.py)0
-rw-r--r--waflib/Tools/ruby.py (renamed from Tools/ruby.py)0
-rw-r--r--waflib/Tools/suncc.py (renamed from Tools/suncc.py)0
-rw-r--r--waflib/Tools/suncxx.py (renamed from Tools/suncxx.py)0
-rw-r--r--waflib/Tools/tex.py (renamed from Tools/tex.py)0
-rw-r--r--waflib/Tools/vala.py (renamed from Tools/vala.py)0
-rw-r--r--waflib/Tools/waf_unit_test.py (renamed from Tools/waf_unit_test.py)0
-rw-r--r--waflib/Tools/winres.py (renamed from Tools/winres.py)0
-rw-r--r--waflib/Tools/xlc.py (renamed from Tools/xlc.py)0
-rw-r--r--waflib/Tools/xlcxx.py (renamed from Tools/xlcxx.py)0
-rw-r--r--waflib/Utils.py (renamed from Utils.py)0
-rw-r--r--waflib/__init__.py (renamed from __init__.py)0
-rw-r--r--waflib/ansiterm.py (renamed from ansiterm.py)0
-rw-r--r--waflib/extras/__init__.py (renamed from extras/__init__.py)0
-rw-r--r--waflib/extras/autowaf.py (renamed from extras/autowaf.py)0
-rw-r--r--waflib/extras/batched_cc.py (renamed from extras/batched_cc.py)0
-rw-r--r--waflib/extras/biber.py (renamed from extras/biber.py)0
-rw-r--r--waflib/extras/bjam.py (renamed from extras/bjam.py)0
-rw-r--r--waflib/extras/blender.py (renamed from extras/blender.py)0
-rw-r--r--waflib/extras/boo.py (renamed from extras/boo.py)0
-rw-r--r--waflib/extras/boost.py (renamed from extras/boost.py)0
-rw-r--r--waflib/extras/build_file_tracker.py (renamed from extras/build_file_tracker.py)0
-rw-r--r--waflib/extras/build_logs.py (renamed from extras/build_logs.py)0
-rw-r--r--waflib/extras/buildcopy.py (renamed from extras/buildcopy.py)0
-rw-r--r--waflib/extras/c_bgxlc.py (renamed from extras/c_bgxlc.py)0
-rw-r--r--waflib/extras/c_dumbpreproc.py (renamed from extras/c_dumbpreproc.py)0
-rw-r--r--waflib/extras/c_emscripten.py (renamed from extras/c_emscripten.py)0
-rw-r--r--waflib/extras/c_nec.py (renamed from extras/c_nec.py)0
-rw-r--r--waflib/extras/cabal.py (renamed from extras/cabal.py)0
-rw-r--r--waflib/extras/cfg_altoptions.py (renamed from extras/cfg_altoptions.py)0
-rw-r--r--waflib/extras/clang_compilation_database.py (renamed from extras/clang_compilation_database.py)0
-rw-r--r--waflib/extras/codelite.py (renamed from extras/codelite.py)0
-rw-r--r--waflib/extras/color_gcc.py (renamed from extras/color_gcc.py)0
-rw-r--r--waflib/extras/color_rvct.py (renamed from extras/color_rvct.py)0
-rw-r--r--waflib/extras/compat15.py (renamed from extras/compat15.py)0
-rw-r--r--waflib/extras/cppcheck.py (renamed from extras/cppcheck.py)0
-rw-r--r--waflib/extras/cpplint.py (renamed from extras/cpplint.py)0
-rw-r--r--waflib/extras/cross_gnu.py (renamed from extras/cross_gnu.py)0
-rw-r--r--waflib/extras/cython.py (renamed from extras/cython.py)0
-rw-r--r--waflib/extras/dcc.py (renamed from extras/dcc.py)0
-rw-r--r--waflib/extras/distnet.py (renamed from extras/distnet.py)0
-rw-r--r--waflib/extras/doxygen.py (renamed from extras/doxygen.py)0
-rw-r--r--waflib/extras/dpapi.py (renamed from extras/dpapi.py)0
-rw-r--r--waflib/extras/eclipse.py (renamed from extras/eclipse.py)0
-rw-r--r--waflib/extras/erlang.py (renamed from extras/erlang.py)0
-rw-r--r--waflib/extras/fast_partial.py (renamed from extras/fast_partial.py)0
-rw-r--r--waflib/extras/fc_bgxlf.py (renamed from extras/fc_bgxlf.py)0
-rw-r--r--waflib/extras/fc_cray.py (renamed from extras/fc_cray.py)0
-rw-r--r--waflib/extras/fc_nag.py (renamed from extras/fc_nag.py)0
-rw-r--r--waflib/extras/fc_nec.py (renamed from extras/fc_nec.py)0
-rw-r--r--waflib/extras/fc_open64.py (renamed from extras/fc_open64.py)0
-rw-r--r--waflib/extras/fc_pgfortran.py (renamed from extras/fc_pgfortran.py)0
-rw-r--r--waflib/extras/fc_solstudio.py (renamed from extras/fc_solstudio.py)0
-rw-r--r--waflib/extras/fc_xlf.py (renamed from extras/fc_xlf.py)0
-rw-r--r--waflib/extras/file_to_object.py (renamed from extras/file_to_object.py)0
-rw-r--r--waflib/extras/fluid.py (renamed from extras/fluid.py)0
-rw-r--r--waflib/extras/freeimage.py (renamed from extras/freeimage.py)0
-rw-r--r--waflib/extras/fsb.py (renamed from extras/fsb.py)0
-rw-r--r--waflib/extras/fsc.py (renamed from extras/fsc.py)0
-rw-r--r--waflib/extras/gccdeps.py (renamed from extras/gccdeps.py)0
-rw-r--r--waflib/extras/gdbus.py (renamed from extras/gdbus.py)0
-rw-r--r--waflib/extras/gob2.py (renamed from extras/gob2.py)0
-rw-r--r--waflib/extras/halide.py (renamed from extras/halide.py)0
-rwxr-xr-xwaflib/extras/javatest.py (renamed from extras/javatest.py)0
-rw-r--r--waflib/extras/kde4.py (renamed from extras/kde4.py)0
-rw-r--r--waflib/extras/local_rpath.py (renamed from extras/local_rpath.py)0
-rw-r--r--waflib/extras/lv2.py (renamed from extras/lv2.py)0
-rw-r--r--waflib/extras/make.py (renamed from extras/make.py)0
-rw-r--r--waflib/extras/midl.py (renamed from extras/midl.py)0
-rw-r--r--waflib/extras/msvcdeps.py (renamed from extras/msvcdeps.py)0
-rw-r--r--waflib/extras/msvs.py (renamed from extras/msvs.py)0
-rw-r--r--waflib/extras/netcache_client.py (renamed from extras/netcache_client.py)0
-rw-r--r--waflib/extras/objcopy.py (renamed from extras/objcopy.py)0
-rw-r--r--waflib/extras/ocaml.py (renamed from extras/ocaml.py)0
-rw-r--r--waflib/extras/package.py (renamed from extras/package.py)0
-rw-r--r--waflib/extras/parallel_debug.py (renamed from extras/parallel_debug.py)0
-rw-r--r--waflib/extras/pch.py (renamed from extras/pch.py)0
-rw-r--r--waflib/extras/pep8.py (renamed from extras/pep8.py)0
-rw-r--r--waflib/extras/pgicc.py (renamed from extras/pgicc.py)0
-rw-r--r--waflib/extras/pgicxx.py (renamed from extras/pgicxx.py)0
-rw-r--r--waflib/extras/proc.py (renamed from extras/proc.py)0
-rw-r--r--waflib/extras/protoc.py (renamed from extras/protoc.py)0
-rw-r--r--waflib/extras/pyqt5.py (renamed from extras/pyqt5.py)0
-rw-r--r--waflib/extras/pytest.py (renamed from extras/pytest.py)0
-rw-r--r--waflib/extras/qnxnto.py (renamed from extras/qnxnto.py)0
-rw-r--r--waflib/extras/qt4.py (renamed from extras/qt4.py)0
-rw-r--r--waflib/extras/relocation.py (renamed from extras/relocation.py)0
-rw-r--r--waflib/extras/remote.py (renamed from extras/remote.py)0
-rw-r--r--waflib/extras/resx.py (renamed from extras/resx.py)0
-rw-r--r--waflib/extras/review.py (renamed from extras/review.py)0
-rw-r--r--waflib/extras/rst.py (renamed from extras/rst.py)0
-rw-r--r--waflib/extras/run_do_script.py (renamed from extras/run_do_script.py)0
-rw-r--r--waflib/extras/run_m_script.py (renamed from extras/run_m_script.py)0
-rw-r--r--waflib/extras/run_py_script.py (renamed from extras/run_py_script.py)0
-rw-r--r--waflib/extras/run_r_script.py (renamed from extras/run_r_script.py)0
-rw-r--r--waflib/extras/sas.py (renamed from extras/sas.py)0
-rw-r--r--waflib/extras/satellite_assembly.py (renamed from extras/satellite_assembly.py)0
-rw-r--r--waflib/extras/scala.py (renamed from extras/scala.py)0
-rw-r--r--waflib/extras/slow_qt4.py (renamed from extras/slow_qt4.py)0
-rw-r--r--waflib/extras/softlink_libs.py (renamed from extras/softlink_libs.py)0
-rw-r--r--waflib/extras/stale.py (renamed from extras/stale.py)0
-rw-r--r--waflib/extras/stracedeps.py (renamed from extras/stracedeps.py)0
-rw-r--r--waflib/extras/swig.py (renamed from extras/swig.py)0
-rw-r--r--waflib/extras/syms.py (renamed from extras/syms.py)0
-rw-r--r--waflib/extras/ticgt.py (renamed from extras/ticgt.py)0
-rw-r--r--waflib/extras/unity.py (renamed from extras/unity.py)0
-rw-r--r--waflib/extras/use_config.py (renamed from extras/use_config.py)0
-rw-r--r--waflib/extras/valadoc.py (renamed from extras/valadoc.py)0
-rw-r--r--waflib/extras/waf_xattr.py (renamed from extras/waf_xattr.py)0
-rw-r--r--waflib/extras/why.py (renamed from extras/why.py)0
-rw-r--r--waflib/extras/win32_opts.py (renamed from extras/win32_opts.py)0
-rw-r--r--waflib/extras/wix.py (renamed from extras/wix.py)0
-rw-r--r--waflib/extras/xcode6.py (renamed from extras/xcode6.py)0
-rw-r--r--waflib/fixpy2.py (renamed from fixpy2.py)0
-rwxr-xr-xwaflib/processor.py (renamed from processor.py)0
-rwxr-xr-xwaflib/waf16
-rw-r--r--wscript193
250 files changed, 11793 insertions, 34 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..ab05648
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,7 @@
+The original LADSPA plugins on which this port is based are by:
+
+ Mike Rawes <mike_rawes@yahoo.co.uk>
+
+This LV2 port was done by:
+
+ David Robillard <d@drobilla.net>
diff --git a/COPYING b/COPYING
index a4147d2..94a9ed0 100644
--- a/COPYING
+++ b/COPYING
@@ -1,25 +1,674 @@
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 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
+
+ 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 <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>.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..623cddd
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,59 @@
+Installation Instructions
+=========================
+
+Basic Installation
+------------------
+
+Building this software requires only Python. To install with default options:
+
+ ./waf configure
+ ./waf
+ ./waf install
+
+You may need to become root for the install stage, for example:
+
+ sudo ./waf install
+
+Configuration Options
+---------------------
+
+All supported options can be viewed using the command:
+
+ ./waf --help
+
+Most options only need to be passed during the configure stage, for example:
+
+ ./waf configure --prefix=/usr
+ ./waf
+ ./waf install
+
+Compiler Configuration
+----------------------
+
+Several standard environment variables can be used to control how compilers are
+invoked:
+
+ * CC: Path to C compiler
+ * CFLAGS: C compiler options
+ * CXX: Path to C++ compiler
+ * CXXFLAGS: C++ compiler options
+ * CPPFLAGS: C preprocessor options
+ * LINKFLAGS: Linker options
+
+Installation Directories
+------------------------
+
+The --prefix option (or the PREFIX environment variable) can be used to change
+the prefix which all files are installed under. There are also several options
+allowing for more fine-tuned control, see the --help output for details.
+
+Packaging
+---------
+
+Everything can be installed to a specific root directory by passing a --destdir
+option to the install stage (or setting the DESTDIR environment variable),
+which adds a prefix to all install paths. For example:
+
+ ./waf configure --prefix=/usr
+ ./waf
+ ./waf install --destdir=/tmp/package
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..583efcf
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,14 @@
+blop-lv2 (1.0.1) unstable;
+
+ * Add missing properties for options interface
+ * Fix compilation with default hidden visibility
+ * Set Hz unit on frequency ports
+ * Avoid pedantic warnings
+
+ -- David Robillard <d@drobilla.net> Sun, 12 Feb 2017 18:07:57 +0100
+
+blop-lv2 (1.0.0) stable;
+
+ * Initial release
+
+ -- David Robillard <d@drobilla.net> Sun, 05 Jan 2014 12:00:00 -0500
diff --git a/README b/README
new file mode 100644
index 0000000..286c5f6
--- /dev/null
+++ b/README
@@ -0,0 +1,13 @@
+BLOP.LV2
+========
+
+This is a port of the BLOP LADSPA plugins by Mike Rawes to LV2.
+
+This is a mostly faithful port of blop-0.2.8, except plugin variants have been
+eliminated via the use of morphable Control/CV ports. This way, users do not
+have to choose from several versions of the same plugin, but the host can
+configure controls to be control-rate or audio-rate as appropriate. This
+mechanism is backwards compatible, so these ports will simply appear as normal
+LV2 control ports in hosts that do not support port morphing.
+
+ -- David Robillard <d@drobilla.net>
diff --git a/blop.lv2/adsr.ttl b/blop.lv2/adsr.ttl
new file mode 100644
index 0000000..290a745
--- /dev/null
+++ b/blop.lv2/adsr.ttl
@@ -0,0 +1,82 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+
+blop:adsr
+ a lv2:Plugin ,
+ lv2:EnvelopePlugin ;
+ lv2:project blop: ;
+ lv2:symbol "adsr" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Driving Signal" ;
+ lv2:symbol "drive"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Trigger Threshold" ;
+ lv2:symbol "thresh"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Attack Time" ;
+ lv2:symbol "attack" ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:minimum 0 ;
+ lv2:name "Decay Time" ;
+ lv2:symbol "decay" ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 1 ;
+ lv2:index 4 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Sustain Level" ;
+ lv2:symbol "sustain"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 5 ;
+ lv2:minimum 0 ;
+ lv2:name "Release Time" ;
+ lv2:symbol "release" ;
+ units:unit units:s
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 6 ;
+ lv2:name "Envelope Out" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1653> ;
+ doap:name "ADSR Envelope" ;
+ lv2:documentation """
+<p>Generates an ADSR (Attack, Decay, Sustain and Release) envelope.</p>
+
+<p>Driven by a gate signal - if the level of the signal goes higher than the
+Trigger Threshold, the attack stage begins, proceeds to the decay stage and
+then holds at the sustain level. The release stage begins when the gate falls
+below this theshold - even if the previous stages have not completed.</p>
+
+<p>The output is a signal between 0.0 (rest) and 1.0 (peak) and the transitions
+are linear.</p>
+""" .
diff --git a/blop.lv2/adsr_gt.ttl b/blop.lv2/adsr_gt.ttl
new file mode 100644
index 0000000..719330e
--- /dev/null
+++ b/blop.lv2/adsr_gt.ttl
@@ -0,0 +1,91 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+
+blop:adsr_gt
+ a lv2:Plugin ,
+ lv2:EnvelopePlugin ;
+ lv2:project blop: ;
+ lv2:symbol "adsr_gt" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Trigger" ;
+ lv2:portProperty lv2:toggled ,
+ <http://lv2plug.in/ns/ext/port-props#trigger> ;
+ lv2:symbol "trigger"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Attack Time" ;
+ lv2:symbol "attack" ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:minimum 0 ;
+ lv2:name "Decay Time" ;
+ lv2:symbol "decay" ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 1 ;
+ lv2:index 4 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Sustain Level" ;
+ lv2:symbol "sustain"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 5 ;
+ lv2:minimum 0 ;
+ lv2:name "Release Time" ;
+ lv2:symbol "release" ;
+ units:unit units:s
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 6 ;
+ lv2:name "Envelope Out" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1680> ;
+ doap:name "Retriggerable ADSR Envelope" ;
+ lv2:documentation """
+<p>Generates an ADSR (Attack, Decay, Sustain and Release)
+envelope.</p>
+
+<p>Does the same thing as the other ADSR (1658) above, except the
+Trigger Threshold is fixed at zero, and the additional Trigger
+input allows retriggering whilst the gate is still high.</p>
+
+<p>The reasoning behind this design is to remove the need for a keyboard player
+to release a key before pressing another when using with a monosynth. <a
+href="http://www.sospubs.co.uk/sos/nov99/articles/synthsecrets.htm">The
+&lsquo;Synth Secrets&rsquo; article in the November 1999 issue of &lsquo;Sound
+on Sound&rsquo;</a> explains this in detail.</p>
+
+<p>The output is a signal between 0.0 (rest) and 1.0 (peak) and the
+transitions are linear.</p>
+""" .
diff --git a/blop.lv2/amp.ttl b/blop.lv2/amp.ttl
new file mode 100644
index 0000000..8ba454d
--- /dev/null
+++ b/blop.lv2/amp.ttl
@@ -0,0 +1,49 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:amp
+ a lv2:Plugin ,
+ lv2:AmplifierPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "amp" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 96 ;
+ lv2:minimum -96 ;
+ lv2:name "Gain" ;
+ lv2:symbol "gain" ;
+ units:unit units:db ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:AudioPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 2 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1654> ,
+ <urn:ladspa:1655> ;
+ doap:name "Amplifier" ;
+ lv2:documentation """
+<p>A simple monophonic amplifier.</p>
+""" .
diff --git a/blop.lv2/branch.ttl b/blop.lv2/branch.ttl
new file mode 100644
index 0000000..f58b81d
--- /dev/null
+++ b/blop.lv2/branch.ttl
@@ -0,0 +1,54 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:branch
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "branch" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:name "Input" ;
+ lv2:symbol "in" ;
+ morph:supportsType lv2:CVPort ,
+ lv2:AudioPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 1 ;
+ lv2:name "Output 1" ;
+ lv2:symbol "out1" ;
+ morph:supportsType lv2:CVPort ,
+ lv2:AudioPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 2 ;
+ lv2:name "Output 2" ;
+ lv2:symbol "out2" ;
+ morph:supportsType lv2:CVPort ,
+ lv2:AudioPort
+ ] ;
+ dct:replaces <urn:ladspa:1673> ,
+ <urn:ladspa:1674> ;
+ doap:name "Branch" ;
+ lv2:documentation """
+<p>Splits an input signal into two identical signals. Somewhat redundant, as
+most modular synth hosts allow you to connect an output to more than one input.
+If your host of choice does not allow this, this plugin will do the job...</p>
+""" .
diff --git a/blop.lv2/dahdsr.ttl b/blop.lv2/dahdsr.ttl
new file mode 100644
index 0000000..68652aa
--- /dev/null
+++ b/blop.lv2/dahdsr.ttl
@@ -0,0 +1,128 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+
+blop:dahdsr
+ a lv2:Plugin ,
+ lv2:EnvelopePlugin ;
+ lv2:project blop: ;
+ lv2:symbol "dahdsr" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Trigger" ;
+ lv2:portProperty lv2:toggled ,
+ <http://lv2plug.in/ns/ext/port-props#trigger> ;
+ lv2:symbol "trigger"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0 ;
+ lv2:index 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Delay Time" ;
+ lv2:symbol "delay" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:minimum 0 ;
+ lv2:name "Attack Time" ;
+ lv2:symbol "attack" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0 ;
+ lv2:index 4 ;
+ lv2:minimum 0 ;
+ lv2:name "Hold Time" ;
+ lv2:symbol "hold" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0 ;
+ lv2:index 5 ;
+ lv2:minimum 0 ;
+ lv2:name "Decay Time" ;
+ lv2:symbol "decay" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:s
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 1 ;
+ lv2:index 6 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Sustain Level" ;
+ lv2:symbol "sustain" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0 ;
+ lv2:index 7 ;
+ lv2:minimum 0 ;
+ lv2:name "Release Time" ;
+ lv2:symbol "release" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:s
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 8 ;
+ lv2:name "Envelope Out" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:2021> ,
+ <urn:ladspa:2022> ,
+ <urn:ladspa:2038> ;
+ doap:name "Retriggerable DAHDSR Envelope" ;
+ lv2:documentation """
+<p>Generates a DAHDSR (Delay, Attack, Hold, Decay, Sustain, Release)
+envelope.</p>
+
+<p>Another envelope generator, this time with two additional stages - Delay,
+which delays the onset of the Attack stage, and Hold, which holds the output at
+maximum before the Decay stage begins.</p>
+
+<p>Triggering works in subtly different ways to the <a href="#adsr_gnt">ADSR
+(1680)</a> - the Trigger will restart the envelope even if the Gate is closed -
+the effect of this is to proceed through the stages and begin the release stage
+immediately after the decay stage.</p>
+
+<p>The final variant (ID 2038) uses control-rate gate and trigger, which is a
+little less CPU hungry, but will cause timing errors that are dependent on the
+block size being used by the host.</p>
+""" .
diff --git a/blop.lv2/difference.ttl b/blop.lv2/difference.ttl
new file mode 100644
index 0000000..e55c6fe
--- /dev/null
+++ b/blop.lv2/difference.ttl
@@ -0,0 +1,51 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:difference
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "difference" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:name "Minuend" ;
+ lv2:symbol "minuend" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 1 ;
+ lv2:name "Subtrahend" ;
+ lv2:symbol "subtrahend" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 2 ;
+ lv2:name "Difference" ;
+ lv2:symbol "difference" ;
+ morph:supportsType lv2:CVPort
+ ] ;
+ dct:replaces <urn:ladspa:2030> ,
+ <urn:ladspa:2031> ,
+ <urn:ladspa:2032> ,
+ <urn:ladspa:2033> ;
+ doap:name "Difference" ;
+ lv2:documentation """
+<p>Subtract two signals.</p>
+""" .
diff --git a/blop.lv2/fmod.ttl b/blop.lv2/fmod.ttl
new file mode 100644
index 0000000..38a552d
--- /dev/null
+++ b/blop.lv2/fmod.ttl
@@ -0,0 +1,60 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:fmod
+ a lv2:Plugin ,
+ lv2:SpectralPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "fmod" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.00001 ;
+ lv2:name "Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 1 ;
+ lv2:name "Modulation" ;
+ lv2:symbol "mod" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:oct
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 2 ;
+ lv2:name "Modulated Frequency" ;
+ lv2:symbol "out" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] ;
+ dct:replaces <urn:ladspa:1656> ,
+ <urn:ladspa:1657> ,
+ <urn:ladspa:1658> ,
+ <urn:ladspa:1659> ;
+ doap:name "Frequency Modulator" ;
+ lv2:documentation """
+<p>Modulates an input frequency by a driving signal, transposing the frequency
+by &#177;1 Octave per unit amplitude of signal.</p>
+""" .
diff --git a/blop.lv2/interpolator.ttl b/blop.lv2/interpolator.ttl
new file mode 100644
index 0000000..38c93db
--- /dev/null
+++ b/blop.lv2/interpolator.ttl
@@ -0,0 +1,32 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+
+blop:interpolator
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "interpolator" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Control Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 1 ;
+ lv2:name "Interpolated Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1660> ;
+ doap:name "Control to CV Interpolator" ;
+ lv2:documentation """
+<p>Interpolates a control-rate (per-block) signal into a smooth audio-rate
+(per-sample) signal.</p>
+""" .
diff --git a/blop.lv2/lp4pole.ttl b/blop.lv2/lp4pole.ttl
new file mode 100644
index 0000000..8fcf75c
--- /dev/null
+++ b/blop.lv2/lp4pole.ttl
@@ -0,0 +1,64 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:lp4pole
+ a lv2:Plugin ,
+ lv2:LowpassPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "lp4pole" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0.5 ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.00001 ;
+ lv2:name "Cutoff Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "cutoff" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0 ;
+ lv2:index 1 ;
+ lv2:maximum 4 ;
+ lv2:minimum 0 ;
+ lv2:name "Resonance" ;
+ lv2:symbol "resonance" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:AudioPort ,
+ lv2:InputPort ;
+ lv2:index 2 ;
+ lv2:name "Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 3 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1671> ,
+ <urn:ladspa:1672> ;
+ doap:name "4 Pole Resonant Low-Pass" ;
+ lv2:documentation """
+<p>Emulates a low pass filter in popular analogue synthesisers. This particular
+filter is derived from one of <a
+href="http://www.musicdsp.org/archive.php?classid=3#24">many
+implementations</a> of the Moog 4 pole filter.</p>
+""" .
diff --git a/blop.lv2/manifest.ttl.in b/blop.lv2/manifest.ttl.in
new file mode 100644
index 0000000..4942342
--- /dev/null
+++ b/blop.lv2/manifest.ttl.in
@@ -0,0 +1,155 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drobilla.net/drobilla#me>
+ a foaf:Person ;
+ foaf:name "David Robillard" ;
+ foaf:mbox <mailto:d@drobilla.net> ;
+ rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+blop:
+ a doap:Project ;
+ lv2:symbol "blop" ;
+ doap:name "Blop LV2" ;
+ doap:shortdesc "An LV2 port of the Blop plugins." ;
+ doap:homepage <http://drobilla.net/software/blop-lv2> ;
+ doap:license <http://opensource.org/licenses/gpl-3.0> ;
+ doap:maintainer <http://drobilla.net/drobilla#me> ;
+ doap:developer [
+ a foaf:Person ;
+ foaf:name "Mike Rawes" ;
+ foaf:mbox <mike_rawes@yahoo.co.uk>
+ ] .
+
+blop:adsr
+ a lv2:Plugin ;
+ rdfs:seeAlso <adsr.ttl> ;
+ lv2:binary <adsr@LIB_EXT@> .
+
+blop:adsr_gt
+ a lv2:Plugin ;
+ rdfs:seeAlso <adsr_gt.ttl> ;
+ lv2:binary <adsr_gt@LIB_EXT@> .
+
+blop:amp
+ a lv2:Plugin ;
+ rdfs:seeAlso <amp.ttl> ;
+ lv2:binary <amp@LIB_EXT@> .
+
+blop:branch
+ a lv2:Plugin ;
+ rdfs:seeAlso <branch.ttl> ;
+ lv2:binary <branch@LIB_EXT@> .
+
+blop:dahdsr
+ a lv2:Plugin ;
+ rdfs:seeAlso <dahdsr.ttl> ;
+ lv2:binary <dahdsr@LIB_EXT@> .
+
+blop:difference
+ a lv2:Plugin ;
+ rdfs:seeAlso <difference.ttl> ;
+ lv2:binary <difference@LIB_EXT@> .
+
+blop:fmod
+ a lv2:Plugin ;
+ rdfs:seeAlso <fmod.ttl> ;
+ lv2:binary <fmod@LIB_EXT@> .
+
+blop:interpolator
+ a lv2:Plugin ;
+ rdfs:seeAlso <interpolator.ttl> ;
+ lv2:binary <interpolator@LIB_EXT@> .
+
+blop:lp4pole
+ a lv2:Plugin ;
+ rdfs:seeAlso <lp4pole.ttl> ;
+ lv2:binary <lp4pole@LIB_EXT@> .
+
+blop:product
+ a lv2:Plugin ;
+ rdfs:seeAlso <product.ttl> ;
+ lv2:binary <product@LIB_EXT@> .
+
+blop:pulse
+ a lv2:Plugin ;
+ rdfs:seeAlso <pulse.ttl> ;
+ lv2:binary <pulse@LIB_EXT@> .
+
+blop:quantiser_20
+ a lv2:Plugin ;
+ rdfs:seeAlso <quantiser_20.ttl> ;
+ lv2:binary <quantiser_20@LIB_EXT@> .
+
+blop:quantiser_50
+ a lv2:Plugin ;
+ rdfs:seeAlso <quantiser_50.ttl> ;
+ lv2:binary <quantiser_50@LIB_EXT@> .
+
+blop:quantiser_100
+ a lv2:Plugin ;
+ rdfs:seeAlso <quantiser_100.ttl> ;
+ lv2:binary <quantiser_100@LIB_EXT@> .
+
+blop:random
+ a lv2:Plugin ;
+ rdfs:seeAlso <random.ttl> ;
+ lv2:binary <random@LIB_EXT@> .
+
+blop:ratio
+ a lv2:Plugin ;
+ rdfs:seeAlso <ratio.ttl> ;
+ lv2:binary <ratio@LIB_EXT@> .
+
+blop:sawtooth
+ a lv2:Plugin ;
+ rdfs:seeAlso <sawtooth.ttl> ;
+ lv2:binary <sawtooth@LIB_EXT@> .
+
+blop:sequencer_16
+ a lv2:Plugin ;
+ rdfs:seeAlso <sequencer_16.ttl> ;
+ lv2:binary <sequencer_16@LIB_EXT@> .
+
+blop:sequencer_32
+ a lv2:Plugin ;
+ rdfs:seeAlso <sequencer_32.ttl> ;
+ lv2:binary <sequencer_32@LIB_EXT@> .
+
+blop:sequencer_64
+ a lv2:Plugin ;
+ rdfs:seeAlso <sequencer_64.ttl> ;
+ lv2:binary <sequencer_64@LIB_EXT@> .
+
+blop:square
+ a lv2:Plugin ;
+ rdfs:seeAlso <square.ttl> ;
+ lv2:binary <square@LIB_EXT@> .
+
+blop:sum
+ a lv2:Plugin ;
+ rdfs:seeAlso <sum.ttl> ;
+ lv2:binary <sum@LIB_EXT@> .
+
+blop:sync_pulse
+ a lv2:Plugin ;
+ rdfs:seeAlso <sync_pulse.ttl> ;
+ lv2:binary <sync_pulse@LIB_EXT@> .
+
+blop:sync_square
+ a lv2:Plugin ;
+ rdfs:seeAlso <sync_square.ttl> ;
+ lv2:binary <sync_square@LIB_EXT@> .
+
+blop:tracker
+ a lv2:Plugin ;
+ rdfs:seeAlso <tracker.ttl> ;
+ lv2:binary <tracker@LIB_EXT@> .
+
+blop:triangle
+ a lv2:Plugin ;
+ rdfs:seeAlso <triangle.ttl> ;
+ lv2:binary <triangle@LIB_EXT@> .
diff --git a/blop.lv2/product.ttl b/blop.lv2/product.ttl
new file mode 100644
index 0000000..d273f22
--- /dev/null
+++ b/blop.lv2/product.ttl
@@ -0,0 +1,50 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:product
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "product" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:name "Multiplicand" ;
+ lv2:symbol "multiplicand" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 1 ;
+ lv2:name "Multiplier" ;
+ lv2:symbol "multiplier" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 2 ;
+ lv2:name "Product" ;
+ lv2:symbol "product" ;
+ morph:supportsType lv2:CVPort
+ ] ;
+ dct:replaces <urn:ladspa:1668> ,
+ <urn:ladspa:1669> ,
+ <urn:ladspa:1670> ;
+ doap:name "Product" ;
+ lv2:documentation """
+<p>Multiply two signals.</p>
+""" .
diff --git a/blop.lv2/pulse.ttl b/blop.lv2/pulse.ttl
new file mode 100644
index 0000000..5a940a9
--- /dev/null
+++ b/blop.lv2/pulse.ttl
@@ -0,0 +1,60 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:pulse
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "pulse" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.000001 ;
+ lv2:default 440.0 ;
+ lv2:name "Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0.5 ;
+ lv2:index 1 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Pulse Width" ;
+ lv2:symbol "pwidth" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 2 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1645> ,
+ <urn:ladspa:1646> ,
+ <urn:ladspa:1647> ,
+ <urn:ladspa:1648> ;
+ doap:name "Pulse" ;
+ lv2:documentation """
+<p>Generates an alias-free pulse wave at given input frequency and pulse width
+(duty).</p>
+""" .
diff --git a/blop.lv2/quantiser_100.ttl b/blop.lv2/quantiser_100.ttl
new file mode 100644
index 0000000..c2873aa
--- /dev/null
+++ b/blop.lv2/quantiser_100.ttl
@@ -0,0 +1,719 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+blop:quantiser_100
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "quantiser_100" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Minimum" ;
+ lv2:symbol "min"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Maximum" ;
+ lv2:symbol "max"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Match Range" ;
+ lv2:symbol "range"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:maximum 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Mode" ;
+ lv2:symbol "mode" ;
+ lv2:portProperty lv2:enumeration ,
+ lv2:integer ;
+ lv2:scalePoint [
+ rdfs:label "Extend" ;
+ rdf:value 0.0
+ ] , [
+ rdfs:label "Wrap" ;
+ rdf:value 1.0
+ ] , [
+ rdfs:label "Clip" ;
+ rdf:value 1.0
+ ]
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 20 ;
+ lv2:index 4 ;
+ lv2:maximum 20 ;
+ lv2:minimum 1 ;
+ lv2:name "Steps" ;
+ lv2:portProperty lv2:integer ;
+ lv2:symbol "steps"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Value 0" ;
+ lv2:symbol "val00"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 6 ;
+ lv2:name "Value 1" ;
+ lv2:symbol "val01"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 7 ;
+ lv2:name "Value 2" ;
+ lv2:symbol "val02"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 8 ;
+ lv2:name "Value 3" ;
+ lv2:symbol "val03"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 9 ;
+ lv2:name "Value 4" ;
+ lv2:symbol "val04"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 10 ;
+ lv2:name "Value 5" ;
+ lv2:symbol "val05"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 11 ;
+ lv2:name "Value 6" ;
+ lv2:symbol "val06"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 12 ;
+ lv2:name "Value 7" ;
+ lv2:symbol "val07"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 13 ;
+ lv2:name "Value 8" ;
+ lv2:symbol "val08"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 14 ;
+ lv2:name "Value 9" ;
+ lv2:symbol "val09"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 15 ;
+ lv2:name "Value 10" ;
+ lv2:symbol "val10"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 16 ;
+ lv2:name "Value 11" ;
+ lv2:symbol "val11"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 17 ;
+ lv2:name "Value 12" ;
+ lv2:symbol "val12"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 18 ;
+ lv2:name "Value 13" ;
+ lv2:symbol "val13"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 19 ;
+ lv2:name "Value 14" ;
+ lv2:symbol "val14"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 20 ;
+ lv2:name "Value 15" ;
+ lv2:symbol "val15"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 21 ;
+ lv2:name "Value 16" ;
+ lv2:symbol "val16"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 22 ;
+ lv2:name "Value 17" ;
+ lv2:symbol "val17"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 23 ;
+ lv2:name "Value 18" ;
+ lv2:symbol "val18"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 24 ;
+ lv2:name "Value 19" ;
+ lv2:symbol "val19"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 25 ;
+ lv2:name "Value 20" ;
+ lv2:symbol "val20"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 26 ;
+ lv2:name "Value 21" ;
+ lv2:symbol "val21"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 27 ;
+ lv2:name "Value 22" ;
+ lv2:symbol "val22"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 28 ;
+ lv2:name "Value 23" ;
+ lv2:symbol "val23"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 29 ;
+ lv2:name "Value 24" ;
+ lv2:symbol "val24"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 30 ;
+ lv2:name "Value 25" ;
+ lv2:symbol "val25"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 31 ;
+ lv2:name "Value 26" ;
+ lv2:symbol "val26"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 32 ;
+ lv2:name "Value 27" ;
+ lv2:symbol "val27"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 33 ;
+ lv2:name "Value 28" ;
+ lv2:symbol "val28"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 34 ;
+ lv2:name "Value 29" ;
+ lv2:symbol "val29"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 35 ;
+ lv2:name "Value 30" ;
+ lv2:symbol "val30"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 36 ;
+ lv2:name "Value 31" ;
+ lv2:symbol "val31"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 37 ;
+ lv2:name "Value 32" ;
+ lv2:symbol "val32"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 38 ;
+ lv2:name "Value 33" ;
+ lv2:symbol "val33"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 39 ;
+ lv2:name "Value 34" ;
+ lv2:symbol "val34"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 40 ;
+ lv2:name "Value 35" ;
+ lv2:symbol "val35"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 41 ;
+ lv2:name "Value 36" ;
+ lv2:symbol "val36"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 42 ;
+ lv2:name "Value 37" ;
+ lv2:symbol "val37"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 43 ;
+ lv2:name "Value 38" ;
+ lv2:symbol "val38"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 44 ;
+ lv2:name "Value 39" ;
+ lv2:symbol "val39"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 45 ;
+ lv2:name "Value 40" ;
+ lv2:symbol "val40"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 46 ;
+ lv2:name "Value 41" ;
+ lv2:symbol "val41"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 47 ;
+ lv2:name "Value 42" ;
+ lv2:symbol "val42"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 48 ;
+ lv2:name "Value 43" ;
+ lv2:symbol "val43"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 49 ;
+ lv2:name "Value 44" ;
+ lv2:symbol "val44"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 50 ;
+ lv2:name "Value 45" ;
+ lv2:symbol "val45"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 51 ;
+ lv2:name "Value 46" ;
+ lv2:symbol "val46"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 52 ;
+ lv2:name "Value 47" ;
+ lv2:symbol "val47"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 53 ;
+ lv2:name "Value 48" ;
+ lv2:symbol "val48"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 54 ;
+ lv2:name "Value 49" ;
+ lv2:symbol "val49"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 55 ;
+ lv2:name "Value 50" ;
+ lv2:symbol "val50"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 56 ;
+ lv2:name "Value 51" ;
+ lv2:symbol "val51"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 57 ;
+ lv2:name "Value 52" ;
+ lv2:symbol "val52"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 58 ;
+ lv2:name "Value 53" ;
+ lv2:symbol "val53"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 59 ;
+ lv2:name "Value 54" ;
+ lv2:symbol "val54"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 60 ;
+ lv2:name "Value 55" ;
+ lv2:symbol "val55"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 61 ;
+ lv2:name "Value 56" ;
+ lv2:symbol "val56"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 62 ;
+ lv2:name "Value 57" ;
+ lv2:symbol "val57"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 63 ;
+ lv2:name "Value 58" ;
+ lv2:symbol "val58"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 64 ;
+ lv2:name "Value 59" ;
+ lv2:symbol "val59"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 65 ;
+ lv2:name "Value 60" ;
+ lv2:symbol "val60"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 66 ;
+ lv2:name "Value 61" ;
+ lv2:symbol "val61"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 67 ;
+ lv2:name "Value 62" ;
+ lv2:symbol "val62"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 68 ;
+ lv2:name "Value 63" ;
+ lv2:symbol "val63"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 69 ;
+ lv2:name "Value 64" ;
+ lv2:symbol "val64"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 70 ;
+ lv2:name "Value 65" ;
+ lv2:symbol "val65"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 71 ;
+ lv2:name "Value 66" ;
+ lv2:symbol "val66"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 72 ;
+ lv2:name "Value 67" ;
+ lv2:symbol "val67"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 73 ;
+ lv2:name "Value 68" ;
+ lv2:symbol "val68"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 74 ;
+ lv2:name "Value 69" ;
+ lv2:symbol "val69"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 75 ;
+ lv2:name "Value 70" ;
+ lv2:symbol "val70"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 76 ;
+ lv2:name "Value 71" ;
+ lv2:symbol "val71"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 77 ;
+ lv2:name "Value 72" ;
+ lv2:symbol "val72"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 78 ;
+ lv2:name "Value 73" ;
+ lv2:symbol "val73"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 79 ;
+ lv2:name "Value 74" ;
+ lv2:symbol "val74"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 80 ;
+ lv2:name "Value 75" ;
+ lv2:symbol "val75"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 81 ;
+ lv2:name "Value 76" ;
+ lv2:symbol "val76"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 82 ;
+ lv2:name "Value 77" ;
+ lv2:symbol "val77"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 83 ;
+ lv2:name "Value 78" ;
+ lv2:symbol "val78"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 84 ;
+ lv2:name "Value 79" ;
+ lv2:symbol "val79"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 85 ;
+ lv2:name "Value 80" ;
+ lv2:symbol "val80"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 86 ;
+ lv2:name "Value 81" ;
+ lv2:symbol "val81"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 87 ;
+ lv2:name "Value 82" ;
+ lv2:symbol "val82"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 88 ;
+ lv2:name "Value 83" ;
+ lv2:symbol "val83"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 89 ;
+ lv2:name "Value 84" ;
+ lv2:symbol "val84"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 90 ;
+ lv2:name "Value 85" ;
+ lv2:symbol "val85"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 91 ;
+ lv2:name "Value 86" ;
+ lv2:symbol "val86"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 92 ;
+ lv2:name "Value 87" ;
+ lv2:symbol "val87"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 93 ;
+ lv2:name "Value 88" ;
+ lv2:symbol "val88"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 94 ;
+ lv2:name "Value 89" ;
+ lv2:symbol "val89"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 95 ;
+ lv2:name "Value 90" ;
+ lv2:symbol "val90"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 96 ;
+ lv2:name "Value 91" ;
+ lv2:symbol "val91"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 97 ;
+ lv2:name "Value 92" ;
+ lv2:symbol "val92"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 98 ;
+ lv2:name "Value 93" ;
+ lv2:symbol "val93"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 99 ;
+ lv2:name "Value 94" ;
+ lv2:symbol "val94"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 100 ;
+ lv2:name "Value 95" ;
+ lv2:symbol "val95"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 101 ;
+ lv2:name "Value 96" ;
+ lv2:symbol "val96"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 102 ;
+ lv2:name "Value 97" ;
+ lv2:symbol "val97"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 103 ;
+ lv2:name "Value 98" ;
+ lv2:symbol "val98"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 104 ;
+ lv2:name "Value 99" ;
+ lv2:symbol "val99"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 105 ;
+ lv2:name "Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 106 ;
+ lv2:name "Quantised Output" ;
+ lv2:symbol "out"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 107 ;
+ lv2:name "Output Changed" ;
+ lv2:symbol "changed"
+ ] ;
+ dct:replaces <urn:ladspa:2029> ;
+ doap:name "Quantiser (100 Steps)" ;
+ lv2:documentation """
+<p>Quantises a signal to a set of arbitrary values within a range.</p>
+
+<p>Match Range determines the distance from the quantised value that the input
+can deviate before being altered. This allows small variations in input to get
+through unmolested. If it is set to 0 the input is quantised to the nearest
+exact match.</p>
+
+<p>Mode is one of Extend (0), Wrap (1) or Clip (2).</p>
+
+<p>Steps is the number of quantisation steps to use (up to a maximum of
+100).</p>
+
+<p>For example, given the following settings:</p>
+<ul>
+ <li>Range Minimum = 0.0</li>
+ <li>Range Maximum = 12.0</li>
+ <li>Match Range = 0.0</li>
+ <li>Steps = 4</li>
+ <li>Quantisation Values 3, 5, 7 and 10</li>
+</ul>
+
+<p>and an input that is a line from -24 to 24, the output will be:</p>
+<ul>
+ <li>Extend: -26, -21, -19, -17, -14, -9, -7, -5, -2, 3, 5, 7, 10, 15, 17, 19,
+ 22</li>
+ <li>Wrap: 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10</li>
+ <li>Clip: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 10, 10, 10, 10, 10</li>
+</ul>
+
+<p>The quantisation values should all be within the range minimum and maximum
+for it to work!</p>
+""" .
diff --git a/blop.lv2/quantiser_20.ttl b/blop.lv2/quantiser_20.ttl
new file mode 100644
index 0000000..095716f
--- /dev/null
+++ b/blop.lv2/quantiser_20.ttl
@@ -0,0 +1,239 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+blop:quantiser_20
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "quantiser_20" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Minimum" ;
+ lv2:symbol "min"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Maximum" ;
+ lv2:symbol "max"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Match Range" ;
+ lv2:symbol "range"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:maximum 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Mode" ;
+ lv2:symbol "mode" ;
+ lv2:portProperty lv2:enumeration ,
+ lv2:integer ;
+ lv2:scalePoint [
+ rdfs:label "Extend" ;
+ rdf:value 0.0
+ ] , [
+ rdfs:label "Wrap" ;
+ rdf:value 1.0
+ ] , [
+ rdfs:label "Clip" ;
+ rdf:value 1.0
+ ]
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 20 ;
+ lv2:index 4 ;
+ lv2:maximum 20 ;
+ lv2:minimum 1 ;
+ lv2:name "Steps" ;
+ lv2:portProperty lv2:integer ;
+ lv2:symbol "steps"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Value 0" ;
+ lv2:symbol "val00"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 6 ;
+ lv2:name "Value 1" ;
+ lv2:symbol "val01"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 7 ;
+ lv2:name "Value 2" ;
+ lv2:symbol "val02"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 8 ;
+ lv2:name "Value 3" ;
+ lv2:symbol "val03"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 9 ;
+ lv2:name "Value 4" ;
+ lv2:symbol "val04"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 10 ;
+ lv2:name "Value 5" ;
+ lv2:symbol "val05"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 11 ;
+ lv2:name "Value 6" ;
+ lv2:symbol "val06"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 12 ;
+ lv2:name "Value 7" ;
+ lv2:symbol "val07"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 13 ;
+ lv2:name "Value 8" ;
+ lv2:symbol "val08"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 14 ;
+ lv2:name "Value 9" ;
+ lv2:symbol "val09"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 15 ;
+ lv2:name "Value 10" ;
+ lv2:symbol "val10"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 16 ;
+ lv2:name "Value 11" ;
+ lv2:symbol "val11"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 17 ;
+ lv2:name "Value 12" ;
+ lv2:symbol "val12"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 18 ;
+ lv2:name "Value 13" ;
+ lv2:symbol "val13"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 19 ;
+ lv2:name "Value 14" ;
+ lv2:symbol "val14"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 20 ;
+ lv2:name "Value 15" ;
+ lv2:symbol "val15"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 21 ;
+ lv2:name "Value 16" ;
+ lv2:symbol "val16"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 22 ;
+ lv2:name "Value 17" ;
+ lv2:symbol "val17"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 23 ;
+ lv2:name "Value 18" ;
+ lv2:symbol "val18"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 24 ;
+ lv2:name "Value 19" ;
+ lv2:symbol "val19"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 25 ;
+ lv2:name "Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 26 ;
+ lv2:name "Quantised Output" ;
+ lv2:symbol "out"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 27 ;
+ lv2:name "Output Changed" ;
+ lv2:symbol "changed"
+ ] ;
+ dct:replaces <urn:ladspa:2027> ;
+ doap:name "Quantiser (20 Steps)" ;
+ lv2:documentation """
+<p>Quantises a signal to a set of arbitrary values within a range.</p>
+
+<p>Match Range determines the distance from the quantised value that the input
+can deviate before being altered. This allows small variations in input to get
+through unmolested. If it is set to 0 the input is quantised to the nearest
+exact match.</p>
+
+<p>Mode is one of Extend (0), Wrap (1) or Clip (2).</p>
+
+<p>Steps is the number of quantisation steps to use (up to a maximum of
+20).</p>
+
+<p>For example, given the following settings:</p>
+<ul>
+ <li>Range Minimum = 0.0</li>
+ <li>Range Maximum = 12.0</li>
+ <li>Match Range = 0.0</li>
+ <li>Steps = 4</li>
+ <li>Quantisation Values 3, 5, 7 and 10</li>
+</ul>
+
+<p>and an input that is a line from -24 to 24, the output will be:</p>
+<ul>
+ <li>Extend: -26, -21, -19, -17, -14, -9, -7, -5, -2, 3, 5, 7, 10, 15, 17, 19,
+ 22</li>
+ <li>Wrap: 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10</li>
+ <li>Clip: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 10, 10, 10, 10, 10</li>
+</ul>
+
+<p>The quantisation values should all be within the range minimum and maximum
+for it to work!</p>
+""" .
diff --git a/blop.lv2/quantiser_50.ttl b/blop.lv2/quantiser_50.ttl
new file mode 100644
index 0000000..901865c
--- /dev/null
+++ b/blop.lv2/quantiser_50.ttl
@@ -0,0 +1,419 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+blop:quantiser_50
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "quantiser_50" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Minimum" ;
+ lv2:symbol "min"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Maximum" ;
+ lv2:symbol "max"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Match Range" ;
+ lv2:symbol "range"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:maximum 2 ;
+ lv2:minimum 0 ;
+ lv2:name "Mode" ;
+ lv2:symbol "mode" ;
+ lv2:portProperty lv2:enumeration ,
+ lv2:integer ;
+ lv2:scalePoint [
+ rdfs:label "Extend" ;
+ rdf:value 0.0
+ ] , [
+ rdfs:label "Wrap" ;
+ rdf:value 1.0
+ ] , [
+ rdfs:label "Clip" ;
+ rdf:value 1.0
+ ]
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 20 ;
+ lv2:index 4 ;
+ lv2:maximum 20 ;
+ lv2:minimum 1 ;
+ lv2:name "Steps" ;
+ lv2:portProperty lv2:integer ;
+ lv2:symbol "steps"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Value 0" ;
+ lv2:symbol "val00"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 6 ;
+ lv2:name "Value 1" ;
+ lv2:symbol "val01"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 7 ;
+ lv2:name "Value 2" ;
+ lv2:symbol "val02"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 8 ;
+ lv2:name "Value 3" ;
+ lv2:symbol "val03"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 9 ;
+ lv2:name "Value 4" ;
+ lv2:symbol "val04"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 10 ;
+ lv2:name "Value 5" ;
+ lv2:symbol "val05"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 11 ;
+ lv2:name "Value 6" ;
+ lv2:symbol "val06"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 12 ;
+ lv2:name "Value 7" ;
+ lv2:symbol "val07"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 13 ;
+ lv2:name "Value 8" ;
+ lv2:symbol "val08"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 14 ;
+ lv2:name "Value 9" ;
+ lv2:symbol "val09"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 15 ;
+ lv2:name "Value 10" ;
+ lv2:symbol "val10"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 16 ;
+ lv2:name "Value 11" ;
+ lv2:symbol "val11"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 17 ;
+ lv2:name "Value 12" ;
+ lv2:symbol "val12"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 18 ;
+ lv2:name "Value 13" ;
+ lv2:symbol "val13"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 19 ;
+ lv2:name "Value 14" ;
+ lv2:symbol "val14"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 20 ;
+ lv2:name "Value 15" ;
+ lv2:symbol "val15"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 21 ;
+ lv2:name "Value 16" ;
+ lv2:symbol "val16"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 22 ;
+ lv2:name "Value 17" ;
+ lv2:symbol "val17"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 23 ;
+ lv2:name "Value 18" ;
+ lv2:symbol "val18"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 24 ;
+ lv2:name "Value 19" ;
+ lv2:symbol "val19"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 25 ;
+ lv2:name "Value 20" ;
+ lv2:symbol "val20"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 26 ;
+ lv2:name "Value 21" ;
+ lv2:symbol "val21"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 27 ;
+ lv2:name "Value 22" ;
+ lv2:symbol "val22"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 28 ;
+ lv2:name "Value 23" ;
+ lv2:symbol "val23"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 29 ;
+ lv2:name "Value 24" ;
+ lv2:symbol "val24"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 30 ;
+ lv2:name "Value 25" ;
+ lv2:symbol "val25"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 31 ;
+ lv2:name "Value 26" ;
+ lv2:symbol "val26"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 32 ;
+ lv2:name "Value 27" ;
+ lv2:symbol "val27"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 33 ;
+ lv2:name "Value 28" ;
+ lv2:symbol "val28"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 34 ;
+ lv2:name "Value 29" ;
+ lv2:symbol "val29"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 35 ;
+ lv2:name "Value 30" ;
+ lv2:symbol "val30"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 36 ;
+ lv2:name "Value 31" ;
+ lv2:symbol "val31"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 37 ;
+ lv2:name "Value 32" ;
+ lv2:symbol "val32"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 38 ;
+ lv2:name "Value 33" ;
+ lv2:symbol "val33"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 39 ;
+ lv2:name "Value 34" ;
+ lv2:symbol "val34"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 40 ;
+ lv2:name "Value 35" ;
+ lv2:symbol "val35"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 41 ;
+ lv2:name "Value 36" ;
+ lv2:symbol "val36"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 42 ;
+ lv2:name "Value 37" ;
+ lv2:symbol "val37"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 43 ;
+ lv2:name "Value 38" ;
+ lv2:symbol "val38"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 44 ;
+ lv2:name "Value 39" ;
+ lv2:symbol "val39"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 45 ;
+ lv2:name "Value 40" ;
+ lv2:symbol "val40"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 46 ;
+ lv2:name "Value 41" ;
+ lv2:symbol "val41"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 47 ;
+ lv2:name "Value 42" ;
+ lv2:symbol "val42"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 48 ;
+ lv2:name "Value 43" ;
+ lv2:symbol "val43"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 49 ;
+ lv2:name "Value 44" ;
+ lv2:symbol "val44"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 50 ;
+ lv2:name "Value 45" ;
+ lv2:symbol "val45"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 51 ;
+ lv2:name "Value 46" ;
+ lv2:symbol "val46"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 52 ;
+ lv2:name "Value 47" ;
+ lv2:symbol "val47"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 53 ;
+ lv2:name "Value 48" ;
+ lv2:symbol "val48"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 54 ;
+ lv2:name "Value 49" ;
+ lv2:symbol "val49"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 55 ;
+ lv2:name "Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 56 ;
+ lv2:name "Quantised Output" ;
+ lv2:symbol "out"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 57 ;
+ lv2:name "Output Changed" ;
+ lv2:symbol "changed"
+ ] ;
+ dct:replaces <urn:ladspa:2028> ;
+ doap:name "Quantiser (50 Steps)" ;
+ lv2:documentation """
+<p>Quantises a signal to a set of arbitrary values within a range.</p>
+
+<p>Match Range determines the distance from the quantised value that the input
+can deviate before being altered. This allows small variations in input to get
+through unmolested. If it is set to 0 the input is quantised to the nearest
+exact match.</p>
+
+<p>Mode is one of Extend (0), Wrap (1) or Clip (2).</p>
+
+<p>Steps is the number of quantisation steps to use (up to a maximum of
+50).</p>
+
+<p>For example, given the following settings:</p>
+<ul>
+ <li>Range Minimum = 0.0</li>
+ <li>Range Maximum = 12.0</li>
+ <li>Match Range = 0.0</li>
+ <li>Steps = 4</li>
+ <li>Quantisation Values 3, 5, 7 and 10</li>
+</ul>
+
+<p>and an input that is a line from -24 to 24, the output will be:</p>
+<ul>
+ <li>Extend: -26, -21, -19, -17, -14, -9, -7, -5, -2, 3, 5, 7, 10, 15, 17, 19,
+ 22</li>
+ <li>Wrap: 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10, 3, 5, 7, 10</li>
+ <li>Clip: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 10, 10, 10, 10, 10</li>
+</ul>
+
+<p>The quantisation values should all be within the range minimum and maximum
+for it to work!</p>
+""" .
diff --git a/blop.lv2/random.ttl b/blop.lv2/random.ttl
new file mode 100644
index 0000000..8b810c9
--- /dev/null
+++ b/blop.lv2/random.ttl
@@ -0,0 +1,64 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:random
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "random" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.000001 ;
+ lv2:default 440.0 ;
+ lv2:name "Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 1 ;
+ lv2:index 1 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Smoothness" ;
+ lv2:symbol "smooth" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ,
+ lv2:Port ;
+ lv2:index 2 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1661> ,
+ <urn:ladspa:1662> ,
+ <urn:ladspa:1663> ,
+ <urn:ladspa:1664> ;
+ doap:name "Random Wave" ;
+ lv2:documentation """
+<p>Generates a random waveform of varying frequency and smoothness. The
+frequency determines how often the output changes. The smoothness, how quickly
+a transition occurs.</p>
+
+<p>The output varies between &#177;1, with an even distribution.</p>
+""" .
diff --git a/blop.lv2/ratio.ttl b/blop.lv2/ratio.ttl
new file mode 100644
index 0000000..04e4d90
--- /dev/null
+++ b/blop.lv2/ratio.ttl
@@ -0,0 +1,52 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:ratio
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "ratio" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:name "Numerator" ;
+ lv2:symbol "numerator" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 1 ;
+ lv2:name "Denominator" ;
+ lv2:symbol "denominator" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 2 ;
+ lv2:name "Ratio" ;
+ lv2:symbol "ratio" ;
+ morph:supportsType lv2:CVPort
+ ] ;
+ dct:replaces <urn:ladspa:2034> ,
+ <urn:ladspa:2035> ,
+ <urn:ladspa:2036> ,
+ <urn:ladspa:2037> ;
+ doap:name "Ratio" ;
+ lv2:documentation """
+<p>Get the ratio between two signals.</p>
+<p>To avoid divisions by zero, 0 is treated as a really small number.</p>
+""" .
diff --git a/blop.lv2/sawtooth.ttl b/blop.lv2/sawtooth.ttl
new file mode 100644
index 0000000..04dec12
--- /dev/null
+++ b/blop.lv2/sawtooth.ttl
@@ -0,0 +1,46 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:sawtooth
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "sawtooth" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.000001 ;
+ lv2:default 440.0 ;
+ lv2:name "Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 1 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1642> ,
+ <urn:ladspa:1643> ;
+ doap:name "Sawtooth" ;
+ lv2:documentation """
+<p>Generates an alias-free sawtooth wave at given input frequency.</p>
+""" .
diff --git a/blop.lv2/sequencer_16.ttl b/blop.lv2/sequencer_16.ttl
new file mode 100644
index 0000000..97473a6
--- /dev/null
+++ b/blop.lv2/sequencer_16.ttl
@@ -0,0 +1,167 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+
+blop:sequencer_16
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "sequencer_16" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Step Trigger" ;
+ lv2:portProperty lv2:toggled ,
+ <http://lv2plug.in/ns/ext/port-props#trigger> ;
+ lv2:symbol "trigger"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 16 ;
+ lv2:index 2 ;
+ lv2:maximum 16 ;
+ lv2:minimum 1 ;
+ lv2:name "Loop Steps" ;
+ lv2:portProperty lv2:integer ;
+ lv2:symbol "steps"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Reset on Gate Close" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "reset"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 4 ;
+ lv2:name "Closed Gate Value" ;
+ lv2:symbol "closed_val"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Value 0" ;
+ lv2:symbol "val00"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 6 ;
+ lv2:name "Value 1" ;
+ lv2:symbol "val01"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 7 ;
+ lv2:name "Value 2" ;
+ lv2:symbol "val02"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 8 ;
+ lv2:name "Value 3" ;
+ lv2:symbol "val03"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 9 ;
+ lv2:name "Value 4" ;
+ lv2:symbol "val04"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 10 ;
+ lv2:name "Value 5" ;
+ lv2:symbol "val05"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 11 ;
+ lv2:name "Value 6" ;
+ lv2:symbol "val06"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 12 ;
+ lv2:name "Value 7" ;
+ lv2:symbol "val07"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 13 ;
+ lv2:name "Value 8" ;
+ lv2:symbol "val08"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 14 ;
+ lv2:name "Value 9" ;
+ lv2:symbol "val09"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 15 ;
+ lv2:name "Value 10" ;
+ lv2:symbol "val10"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 16 ;
+ lv2:name "Value 11" ;
+ lv2:symbol "val11"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 17 ;
+ lv2:name "Value 12" ;
+ lv2:symbol "val12"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 18 ;
+ lv2:name "Value 13" ;
+ lv2:symbol "val13"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 19 ;
+ lv2:name "Value 14" ;
+ lv2:symbol "val14"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 20 ;
+ lv2:name "Value 15" ;
+ lv2:symbol "val15"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 21 ;
+ lv2:name "Value Out" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1677> ;
+ doap:name "16 Step Sequencer" ;
+ lv2:documentation """
+<p>Simulates an analogue step sequencer. The sequencer stores a number of
+values which are stepped through using a trigger when the gate is open, looping
+after a given number of steps. This variant has 16 steps.</p>
+
+<p>When the gate is closed, the sequencer returns to the start. Output when
+the gate is closed can be set to a default value. If not, it will just output
+the last value reached before the gate was closed.</p>
+""" .
diff --git a/blop.lv2/sequencer_32.ttl b/blop.lv2/sequencer_32.ttl
new file mode 100644
index 0000000..ae289f2
--- /dev/null
+++ b/blop.lv2/sequencer_32.ttl
@@ -0,0 +1,263 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+
+blop:sequencer_32
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "sequencer_32" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Step Trigger" ;
+ lv2:portProperty lv2:toggled ,
+ <http://lv2plug.in/ns/ext/port-props#trigger> ;
+ lv2:symbol "trigger"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 32 ;
+ lv2:index 2 ;
+ lv2:maximum 32 ;
+ lv2:minimum 1 ;
+ lv2:name "Loop Steps" ;
+ lv2:portProperty lv2:integer ;
+ lv2:symbol "steps"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Reset on Gate Close" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "reset"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 4 ;
+ lv2:name "Closed Gate Value" ;
+ lv2:symbol "closed_val"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Value 0" ;
+ lv2:symbol "val00"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 6 ;
+ lv2:name "Value 1" ;
+ lv2:symbol "val01"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 7 ;
+ lv2:name "Value 2" ;
+ lv2:symbol "val02"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 8 ;
+ lv2:name "Value 3" ;
+ lv2:symbol "val03"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 9 ;
+ lv2:name "Value 4" ;
+ lv2:symbol "val04"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 10 ;
+ lv2:name "Value 5" ;
+ lv2:symbol "val05"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 11 ;
+ lv2:name "Value 6" ;
+ lv2:symbol "val06"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 12 ;
+ lv2:name "Value 7" ;
+ lv2:symbol "val07"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 13 ;
+ lv2:name "Value 8" ;
+ lv2:symbol "val08"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 14 ;
+ lv2:name "Value 9" ;
+ lv2:symbol "val09"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 15 ;
+ lv2:name "Value 10" ;
+ lv2:symbol "val10"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 16 ;
+ lv2:name "Value 11" ;
+ lv2:symbol "val11"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 17 ;
+ lv2:name "Value 12" ;
+ lv2:symbol "val12"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 18 ;
+ lv2:name "Value 13" ;
+ lv2:symbol "val13"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 19 ;
+ lv2:name "Value 14" ;
+ lv2:symbol "val14"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 20 ;
+ lv2:name "Value 15" ;
+ lv2:symbol "val15"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 21 ;
+ lv2:name "Value 16" ;
+ lv2:symbol "val16"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 22 ;
+ lv2:name "Value 17" ;
+ lv2:symbol "val17"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 23 ;
+ lv2:name "Value 18" ;
+ lv2:symbol "val18"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 24 ;
+ lv2:name "Value 19" ;
+ lv2:symbol "val19"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 25 ;
+ lv2:name "Value 20" ;
+ lv2:symbol "val20"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 26 ;
+ lv2:name "Value 21" ;
+ lv2:symbol "val21"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 27 ;
+ lv2:name "Value 22" ;
+ lv2:symbol "val22"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 28 ;
+ lv2:name "Value 23" ;
+ lv2:symbol "val23"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 29 ;
+ lv2:name "Value 24" ;
+ lv2:symbol "val24"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 30 ;
+ lv2:name "Value 25" ;
+ lv2:symbol "val25"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 31 ;
+ lv2:name "Value 26" ;
+ lv2:symbol "val26"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 32 ;
+ lv2:name "Value 27" ;
+ lv2:symbol "val27"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 33 ;
+ lv2:name "Value 28" ;
+ lv2:symbol "val28"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 34 ;
+ lv2:name "Value 29" ;
+ lv2:symbol "val29"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 35 ;
+ lv2:name "Value 30" ;
+ lv2:symbol "val30"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 36 ;
+ lv2:name "Value 31" ;
+ lv2:symbol "val31"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 37 ;
+ lv2:name "Value Out" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1676> ;
+ doap:name "32 Step Sequencer" ;
+ lv2:documentation """
+<p>Simulates an analogue step sequencer. The sequencer stores a number of
+values which are stepped through using a trigger when the gate is open, looping
+after a given number of steps. This variant has 32 steps.</p>
+
+<p>When the gate is closed, the sequencer returns to the start. Output when
+the gate is closed can be set to a default value. If not, it will just output
+the last value reached before the gate was closed.</p>
+""" .
diff --git a/blop.lv2/sequencer_64.ttl b/blop.lv2/sequencer_64.ttl
new file mode 100644
index 0000000..3a3ea0f
--- /dev/null
+++ b/blop.lv2/sequencer_64.ttl
@@ -0,0 +1,455 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+
+blop:sequencer_64
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "sequencer_64" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:optionalFeature lv2:hardRTCapable ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Step Trigger" ;
+ lv2:portProperty lv2:toggled ,
+ <http://lv2plug.in/ns/ext/port-props#trigger> ;
+ lv2:symbol "trigger"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 32 ;
+ lv2:index 2 ;
+ lv2:maximum 32 ;
+ lv2:minimum 1 ;
+ lv2:name "Loop Steps" ;
+ lv2:portProperty lv2:integer ;
+ lv2:symbol "steps"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:default 0 ;
+ lv2:index 3 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Reset on Gate Close" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "reset"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 4 ;
+ lv2:name "Closed Gate Value" ;
+ lv2:symbol "closed_val"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Value 0" ;
+ lv2:symbol "val00"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 6 ;
+ lv2:name "Value 1" ;
+ lv2:symbol "val01"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 7 ;
+ lv2:name "Value 2" ;
+ lv2:symbol "val02"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 8 ;
+ lv2:name "Value 3" ;
+ lv2:symbol "val03"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 9 ;
+ lv2:name "Value 4" ;
+ lv2:symbol "val04"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 10 ;
+ lv2:name "Value 5" ;
+ lv2:symbol "val05"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 11 ;
+ lv2:name "Value 6" ;
+ lv2:symbol "val06"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 12 ;
+ lv2:name "Value 7" ;
+ lv2:symbol "val07"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 13 ;
+ lv2:name "Value 8" ;
+ lv2:symbol "val08"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 14 ;
+ lv2:name "Value 9" ;
+ lv2:symbol "val09"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 15 ;
+ lv2:name "Value 10" ;
+ lv2:symbol "val10"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 16 ;
+ lv2:name "Value 11" ;
+ lv2:symbol "val11"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 17 ;
+ lv2:name "Value 12" ;
+ lv2:symbol "val12"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 18 ;
+ lv2:name "Value 13" ;
+ lv2:symbol "val13"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 19 ;
+ lv2:name "Value 14" ;
+ lv2:symbol "val14"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 20 ;
+ lv2:name "Value 15" ;
+ lv2:symbol "val15"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 21 ;
+ lv2:name "Value 16" ;
+ lv2:symbol "val16"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 22 ;
+ lv2:name "Value 17" ;
+ lv2:symbol "val17"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 23 ;
+ lv2:name "Value 18" ;
+ lv2:symbol "val18"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 24 ;
+ lv2:name "Value 19" ;
+ lv2:symbol "val19"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 25 ;
+ lv2:name "Value 20" ;
+ lv2:symbol "val20"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 26 ;
+ lv2:name "Value 21" ;
+ lv2:symbol "val21"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 27 ;
+ lv2:name "Value 22" ;
+ lv2:symbol "val22"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 28 ;
+ lv2:name "Value 23" ;
+ lv2:symbol "val23"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 29 ;
+ lv2:name "Value 24" ;
+ lv2:symbol "val24"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 30 ;
+ lv2:name "Value 25" ;
+ lv2:symbol "val25"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 31 ;
+ lv2:name "Value 26" ;
+ lv2:symbol "val26"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 32 ;
+ lv2:name "Value 27" ;
+ lv2:symbol "val27"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 33 ;
+ lv2:name "Value 28" ;
+ lv2:symbol "val28"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 34 ;
+ lv2:name "Value 29" ;
+ lv2:symbol "val29"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 35 ;
+ lv2:name "Value 30" ;
+ lv2:symbol "val30"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 36 ;
+ lv2:name "Value 31" ;
+ lv2:symbol "val31"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 37 ;
+ lv2:name "Value 32" ;
+ lv2:symbol "val32"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 38 ;
+ lv2:name "Value 33" ;
+ lv2:symbol "val33"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 39 ;
+ lv2:name "Value 34" ;
+ lv2:symbol "val34"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 40 ;
+ lv2:name "Value 35" ;
+ lv2:symbol "val35"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 41 ;
+ lv2:name "Value 36" ;
+ lv2:symbol "val36"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 42 ;
+ lv2:name "Value 37" ;
+ lv2:symbol "val37"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 43 ;
+ lv2:name "Value 38" ;
+ lv2:symbol "val38"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 44 ;
+ lv2:name "Value 39" ;
+ lv2:symbol "val39"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 45 ;
+ lv2:name "Value 40" ;
+ lv2:symbol "val40"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 46 ;
+ lv2:name "Value 41" ;
+ lv2:symbol "val41"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 47 ;
+ lv2:name "Value 42" ;
+ lv2:symbol "val42"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 48 ;
+ lv2:name "Value 43" ;
+ lv2:symbol "val43"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 49 ;
+ lv2:name "Value 44" ;
+ lv2:symbol "val44"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 50 ;
+ lv2:name "Value 45" ;
+ lv2:symbol "val45"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 51 ;
+ lv2:name "Value 46" ;
+ lv2:symbol "val46"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 52 ;
+ lv2:name "Value 47" ;
+ lv2:symbol "val47"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 53 ;
+ lv2:name "Value 48" ;
+ lv2:symbol "val48"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 54 ;
+ lv2:name "Value 49" ;
+ lv2:symbol "val49"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 55 ;
+ lv2:name "Value 50" ;
+ lv2:symbol "val50"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 56 ;
+ lv2:name "Value 51" ;
+ lv2:symbol "val51"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 57 ;
+ lv2:name "Value 52" ;
+ lv2:symbol "val52"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 58 ;
+ lv2:name "Value 53" ;
+ lv2:symbol "val53"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 59 ;
+ lv2:name "Value 54" ;
+ lv2:symbol "val54"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 60 ;
+ lv2:name "Value 55" ;
+ lv2:symbol "val55"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 61 ;
+ lv2:name "Value 56" ;
+ lv2:symbol "val56"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 62 ;
+ lv2:name "Value 57" ;
+ lv2:symbol "val57"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 63 ;
+ lv2:name "Value 58" ;
+ lv2:symbol "val58"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 64 ;
+ lv2:name "Value 59" ;
+ lv2:symbol "val59"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 65 ;
+ lv2:name "Value 60" ;
+ lv2:symbol "val60"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 66 ;
+ lv2:name "Value 61" ;
+ lv2:symbol "val61"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 67 ;
+ lv2:name "Value 62" ;
+ lv2:symbol "val62"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ;
+ lv2:index 68 ;
+ lv2:name "Value 63" ;
+ lv2:symbol "val63"
+ ] , [
+ a lv2:CVPort ,
+ lv2:OutputPort ;
+ lv2:index 69 ;
+ lv2:name "Value Out" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1675> ;
+ doap:name "64 Step Sequencer" ;
+ lv2:documentation """
+<p>Simulates an analogue step sequencer. The sequencer stores a number of
+values which are stepped through using a trigger when the gate is open, looping
+after a given number of steps. This variant has 64 steps.</p>
+
+<p>When the gate is closed, the sequencer returns to the start. Output when
+the gate is closed can be set to a default value. If not, it will just output
+the last value reached before the gate was closed.</p>
+""" .
diff --git a/blop.lv2/square.ttl b/blop.lv2/square.ttl
new file mode 100644
index 0000000..77f30bc
--- /dev/null
+++ b/blop.lv2/square.ttl
@@ -0,0 +1,46 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:square
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "square" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.000001 ;
+ lv2:default 440.0 ;
+ lv2:name "Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 1 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1643> ,
+ <urn:ladspa:1644> ;
+ doap:name "Square" ;
+ lv2:documentation """
+<p>Generates an alias-free square wave at given input frequency.</p>
+""" .
diff --git a/blop.lv2/sum.ttl b/blop.lv2/sum.ttl
new file mode 100644
index 0000000..66ea88d
--- /dev/null
+++ b/blop.lv2/sum.ttl
@@ -0,0 +1,50 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:sum
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "sum" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:name "Input 1" ;
+ lv2:symbol "in1" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 1 ;
+ lv2:name "Input 2" ;
+ lv2:symbol "in2" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:ControlPort ,
+ lv2:OutputPort ,
+ morph:AutoMorphPort ;
+ lv2:index 2 ;
+ lv2:name "Sum" ;
+ lv2:symbol "sum" ;
+ morph:supportsType lv2:CVPort
+ ] ;
+ dct:replaces <urn:ladspa:1665> ,
+ <urn:ladspa:1666> ,
+ <urn:ladspa:1667> ;
+ doap:name "Sum" ;
+ lv2:documentation """
+<p>Add two signals.</p>
+""" .
diff --git a/blop.lv2/sync_pulse.ttl b/blop.lv2/sync_pulse.ttl
new file mode 100644
index 0000000..47051e2
--- /dev/null
+++ b/blop.lv2/sync_pulse.ttl
@@ -0,0 +1,63 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:sync_pulse
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "sync_pulse" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 16 ;
+ lv2:index 0 ;
+ lv2:maximum 64 ;
+ lv2:minimum 0 ;
+ lv2:name "Frequency" ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0.5 ;
+ lv2:index 1 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Pulse Width" ;
+ lv2:symbol "pwidth" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 2 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 3 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:2023> ,
+ <urn:ladspa:2024> ;
+ doap:name "Clock Pulse" ;
+ lv2:documentation """
+<p>Same as the <a href="http://drobilla.net/plugins/blop/sync_square">Clock
+Oscillator</a>, but with pulse-width modulation.</p>
+""" .
diff --git a/blop.lv2/sync_square.ttl b/blop.lv2/sync_square.ttl
new file mode 100644
index 0000000..873619f
--- /dev/null
+++ b/blop.lv2/sync_square.ttl
@@ -0,0 +1,55 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:sync_square
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "sync_square" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 16 ;
+ lv2:index 0 ;
+ lv2:maximum 64 ;
+ lv2:minimum 0 ;
+ lv2:name "Frequency" ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 1 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 2 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1678> ,
+ <urn:ladspa:1679> ;
+ doap:name "Clock Square" ;
+ lv2:documentation """
+<p>Generates a non-bandlimited simple square waveform for use as a clock.
+Useful for triggering the sequencers, or anything else that uses a clock
+signal.</p>
+
+<p>When the gate is closed, it outputs silence, and the phase is reset.</p>
+""" .
diff --git a/blop.lv2/tracker.ttl b/blop.lv2/tracker.ttl
new file mode 100644
index 0000000..b62d811
--- /dev/null
+++ b/blop.lv2/tracker.ttl
@@ -0,0 +1,122 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:tracker
+ a lv2:Plugin ;
+ lv2:project blop: ;
+ lv2:symbol "tracker" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:CVPort ,
+ lv2:InputPort ;
+ lv2:index 0 ;
+ lv2:name "Gate" ;
+ lv2:portProperty lv2:toggled ;
+ lv2:symbol "gate"
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 100 ;
+ lv2:index 1 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.00001 ;
+ lv2:name "High Attack Rate" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "hattack" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 100 ;
+ lv2:index 2 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.00001 ;
+ lv2:name "High Decay Rate" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "hdecay" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 100 ;
+ lv2:index 3 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.00001 ;
+ lv2:name "Low Attack Rate" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "lattack" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 100 ;
+ lv2:index 4 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.00001 ;
+ lv2:name "Low Decay Rate" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "ldecay" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:AudioPort ,
+ lv2:InputPort ;
+ lv2:index 5 ;
+ lv2:name "Input" ;
+ lv2:symbol "in"
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 6 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:2025> ,
+ <urn:ladspa:2026> ;
+ doap:name "Tracker" ;
+ lv2:documentation """
+<p>This tracks an incoming signal and outputs the result.</p>
+<p>The rate controls tell the plugin how quickly to respond to a change in
+input. Low values will mean a slower response - a setting of 0 will hold the
+last value, and a very high value will track the input exactly.</p>
+<p>Attack rate is how quickly an upward change is tracked, and Decay for
+downward changes. There are two pairs of these - the one used depends on the
+level of the Gate.</p>
+<p>Example uses:</p>
+<ul>
+ <li>
+ <em>An envelope tracker</em>- use the &#8216;Gate Low&#8217; track rates with
+ the Gate held low, and run the output through a full-wave rectifier (an ABS()
+ operator) to get an estimate of the level of a signal.</li>
+ <li>
+ <em>Sample and Hold</em>- run a narrow pulse wave into the gate, set the
+ &#8216;Gate High&#8217; rates to maximum, and the &#8216;Gate Low&#8217;
+ rates set to 0.</li>
+ <li>
+ <em>Track and Hold</em>- run a variable pulse wave into the gate, set the
+ &#8216;Gate High&#8217; rates to 0, and the &#8216;Gate Low&#8217; rates set
+ high. Varying the pulsewidth will vary the time the input is tracked, and
+ when it is held.</li>
+</ul>
+""" .
diff --git a/blop.lv2/triangle.ttl b/blop.lv2/triangle.ttl
new file mode 100644
index 0000000..60b5a2b
--- /dev/null
+++ b/blop.lv2/triangle.ttl
@@ -0,0 +1,61 @@
+@prefix blop: <http://drobilla.net/plugins/blop/> .
+@prefix dct: <http://purl.org/dc/terms/> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+blop:triangle
+ a lv2:Plugin ,
+ lv2:OscillatorPlugin ;
+ lv2:project blop: ;
+ lv2:symbol "triangle" ;
+ lv2:microVersion 0 ;
+ lv2:minorVersion 0 ;
+ lv2:extensionData opts:interface ;
+ lv2:optionalFeature lv2:hardRTCapable ,
+ urid:map ;
+ lv2:port [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:index 0 ;
+ lv2:maximum 0.5 ;
+ lv2:minimum 0.000001 ;
+ lv2:default 440.0 ;
+ lv2:name "Frequency" ;
+ lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ,
+ lv2:sampleRate ;
+ lv2:symbol "freq" ;
+ morph:supportsType lv2:CVPort ;
+ units:unit units:hz
+ ] , [
+ a lv2:ControlPort ,
+ lv2:InputPort ,
+ morph:MorphPort ;
+ lv2:default 0.5 ;
+ lv2:index 1 ;
+ lv2:maximum 1 ;
+ lv2:minimum 0 ;
+ lv2:name "Slope" ;
+ lv2:symbol "slope" ;
+ morph:supportsType lv2:CVPort
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 2 ;
+ lv2:name "Output" ;
+ lv2:symbol "out"
+ ] ;
+ dct:replaces <urn:ladspa:1649> ,
+ <urn:ladspa:1650> ,
+ <urn:ladspa:1651> ,
+ <urn:ladspa:1652> ;
+ doap:name "Triangle" ;
+ lv2:documentation """
+<p>Generates an alias-free variable slope triangle wave at given input
+frequency and slope. The slope changes the wave shape from sawtooth to
+triangle.</p>
+""" .
diff --git a/src/adsr.c b/src/adsr.c
new file mode 100644
index 0000000..a84469f
--- /dev/null
+++ b/src/adsr.c
@@ -0,0 +1,259 @@
+/*
+ An LV2 plugin to generate ADSR envelopes.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "common.h"
+
+#define ADSR_SIGNAL 0
+#define ADSR_TRIGGER 1
+#define ADSR_ATTACK 2
+#define ADSR_DECAY 3
+#define ADSR_SUSTAIN 4
+#define ADSR_RELEASE 5
+#define ADSR_OUTPUT 6
+
+typedef enum {
+ IDLE,
+ ATTACK,
+ DECAY,
+ SUSTAIN,
+ RELEASE
+} ADSRState;
+
+typedef struct {
+ const float* signal;
+ const float* trigger;
+ const float* attack;
+ const float* decay;
+ const float* sustain;
+ const float* release;
+ float* output;
+ float srate;
+ float inv_srate;
+ float from_level;
+ float level;
+ ADSRState state;
+ uint32_t samples;
+} Adsr;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Adsr* plugin = (Adsr*)instance;
+
+ switch (port) {
+ case ADSR_SIGNAL:
+ plugin->signal = (const float*)data;
+ break;
+ case ADSR_TRIGGER:
+ plugin->trigger = (const float*)data;
+ break;
+ case ADSR_ATTACK:
+ plugin->attack = (const float*)data;
+ break;
+ case ADSR_DECAY:
+ plugin->decay = (const float*)data;
+ break;
+ case ADSR_SUSTAIN:
+ plugin->sustain = (const float*)data;
+ break;
+ case ADSR_RELEASE:
+ plugin->release = (const float*)data;
+ break;
+ case ADSR_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Adsr* plugin = (Adsr*)malloc(sizeof(Adsr));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->srate = (float)sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Adsr* plugin = (Adsr*)instance;
+
+ plugin->from_level = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Adsr* plugin = (Adsr*)instance;
+
+ /* Driving signal */
+ const float* signal = plugin->signal;
+
+ /* Trigger Threshold */
+ const float trigger = *(plugin->trigger);
+
+ /* Attack Time (s) */
+ float attack = *(plugin->attack);
+
+ /* Decay Time (s) */
+ float decay = *(plugin->decay);
+
+ /* Sustain Level */
+ const float sustain = f_clip(*(plugin->sustain), 0.0f, 1.0f);
+
+ /* Release Time (s) */
+ float release = *(plugin->release);
+
+ /* Envelope Out */
+ float* output = plugin->output;
+
+ float srate = plugin->srate;
+ float inv_srate = plugin->inv_srate;
+ float from_level = plugin->from_level;
+ float level = plugin->level;
+ ADSRState state = plugin->state;
+ uint32_t samples = plugin->samples;
+
+ float elapsed;
+
+ /* Convert times into rates */
+ attack = attack > 0.0f ? inv_srate / attack : srate;
+ decay = decay > 0.0f ? inv_srate / decay : srate;
+ release = release > 0.0f ? inv_srate / release : srate;
+
+ for (uint32_t s = 0; s < sample_count; s++) {
+ /* Determine if attack or release happened */
+ if ((state == IDLE) || (state == RELEASE)) {
+ if (signal[s] > trigger) {
+ if (attack < srate) {
+ state = ATTACK;
+ } else {
+ state = decay < srate ? DECAY : SUSTAIN;
+ level = 1.0f;
+ }
+ samples = 0;
+ }
+ } else {
+ if (signal[s] <= trigger) {
+ state = release < srate ? RELEASE : IDLE;
+ samples = 0;
+ }
+ }
+
+ if (samples == 0) {
+ from_level = level;
+ }
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ level = 0;
+ break;
+ case ATTACK:
+ samples++;
+ elapsed = (float)samples * attack;
+ if (elapsed > 1.0f) {
+ state = decay < srate ? DECAY : SUSTAIN;
+ level = 1.0f;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (1.0f - from_level);
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (float)samples * decay;
+ if (elapsed > 1.0f) {
+ state = SUSTAIN;
+ level = sustain;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (sustain - from_level);
+ }
+ break;
+ case SUSTAIN:
+ level = sustain;
+ break;
+ case RELEASE:
+ samples++;
+ elapsed = (float)samples * release;
+ if (elapsed > 1.0f) {
+ state = IDLE;
+ level = 0.0f;
+ samples = 0;
+ } else {
+ level = from_level - elapsed * from_level;
+ }
+ break;
+ default:
+ /* Should never happen */
+ level = 0.0f;
+ }
+
+ output[s] = level;
+ }
+
+ plugin->from_level = from_level;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/adsr",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ NULL,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/adsr_gt.c b/src/adsr_gt.c
new file mode 100644
index 0000000..4f23649
--- /dev/null
+++ b/src/adsr_gt.c
@@ -0,0 +1,266 @@
+/*
+ An LV2 plugin to generate ADSR envelopes Gate and Trigger variant.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "common.h"
+
+#define ADSR_GATE 0
+#define ADSR_TRIGGER 1
+#define ADSR_ATTACK 2
+#define ADSR_DECAY 3
+#define ADSR_SUSTAIN 4
+#define ADSR_RELEASE 5
+#define ADSR_OUTPUT 6
+
+typedef enum {
+ IDLE,
+ ATTACK,
+ DECAY,
+ SUSTAIN,
+ RELEASE
+} ADSRState;
+
+typedef struct {
+ const float* gate;
+ const float* trigger;
+ const float* attack;
+ const float* decay;
+ const float* sustain;
+ const float* release;
+ float* output;
+ float srate;
+ float inv_srate;
+ float last_trigger;
+ float from_level;
+ float level;
+ ADSRState state;
+ uint32_t samples;
+} Adsr;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Adsr* plugin = (Adsr*)instance;
+
+ switch (port) {
+ case ADSR_GATE:
+ plugin->gate = (const float*)data;
+ break;
+ case ADSR_TRIGGER:
+ plugin->trigger = (const float*)data;
+ break;
+ case ADSR_ATTACK:
+ plugin->attack = (const float*)data;
+ break;
+ case ADSR_DECAY:
+ plugin->decay = (const float*)data;
+ break;
+ case ADSR_SUSTAIN:
+ plugin->sustain = (const float*)data;
+ break;
+ case ADSR_RELEASE:
+ plugin->release = (const float*)data;
+ break;
+ case ADSR_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Adsr* plugin = (Adsr*)malloc(sizeof(Adsr));
+
+ if (plugin) {
+ plugin->srate = (float)sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Adsr* plugin = (Adsr*)instance;
+
+ plugin->last_trigger = 0.0f;
+ plugin->from_level = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Adsr* plugin = (Adsr*)instance;
+
+ /* Gate */
+ const float* gate = plugin->gate;
+
+ /* Trigger */
+ const float* trigger = plugin->trigger;
+
+ /* Attack Time (s) */
+ float attack = *(plugin->attack);
+
+ /* Decay Time (s) */
+ float decay = *(plugin->decay);
+
+ /* Sustain Level */
+ const float sustain = f_clip(*(plugin->sustain), 0.0f, 1.0f);
+
+ /* Release Time (s) */
+ float release = *(plugin->release);
+
+ /* Envelope Out */
+ float* output = plugin->output;
+
+ float srate = plugin->srate;
+ float inv_srate = plugin->inv_srate;
+ float last_trigger = plugin->last_trigger;
+ float from_level = plugin->from_level;
+ float level = plugin->level;
+ ADSRState state = plugin->state;
+ uint32_t samples = plugin->samples;
+
+ float elapsed;
+
+ /* Convert times into rates */
+ attack = attack > 0.0f ? inv_srate / attack : srate;
+ decay = decay > 0.0f ? inv_srate / decay : srate;
+ release = release > 0.0f ? inv_srate / release : srate;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ /* Attack on trigger, if gate is open */
+ if (trigger[s] > 0.0f
+ && !(last_trigger > 0.0f)
+ && gate[s] > 0.0f) {
+ if (attack < srate) {
+ state = ATTACK;
+ } else {
+ state = decay < srate ? DECAY : SUSTAIN;
+ level = 1.0f;
+ }
+ samples = 0;
+ }
+
+ /* Release if gate closed */
+ if (state != IDLE
+ && state != RELEASE
+ && !(gate[s] > 0.0f)) {
+ state = release < srate ? RELEASE : IDLE;
+ samples = 0;
+ }
+
+ if (samples == 0) {
+ from_level = level;
+ }
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ level = 0;
+ break;
+ case ATTACK:
+ samples++;
+ elapsed = (float)samples * attack;
+ if (elapsed > 1.0f) {
+ state = decay < srate ? DECAY : SUSTAIN;
+ level = 1.0f;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (1.0f - from_level);
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (float)samples * decay;
+ if (elapsed > 1.0f) {
+ state = SUSTAIN;
+ level = sustain;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (sustain - from_level);
+ }
+ break;
+ case SUSTAIN:
+ level = sustain;
+ break;
+ case RELEASE:
+ samples++;
+ elapsed = (float)samples * release;
+ if (elapsed > 1.0f) {
+ state = IDLE;
+ level = 0.0f;
+ samples = 0;
+ } else {
+ level = from_level - elapsed * from_level;
+ }
+ break;
+ default:
+ /* Should never happen */
+ level = 0.0f;
+ }
+
+ output[s] = level;
+ last_trigger = trigger[s];
+ }
+
+ plugin->last_trigger = last_trigger;
+ plugin->from_level = from_level;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/adsr_gt",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ NULL,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/amp.c b/src/amp.c
new file mode 100644
index 0000000..4f6de84
--- /dev/null
+++ b/src/amp.c
@@ -0,0 +1,166 @@
+/*
+ An LV2 plugin representing a simple mono amplifier.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "math_func.h"
+#include "uris.h"
+
+#define AMP_GAIN 0
+#define AMP_INPUT 1
+#define AMP_OUTPUT 2
+
+typedef struct {
+ const float* gain;
+ const float* input;
+ float* output;
+ URIs uris;
+ uint32_t gain_is_cv;
+} Amp;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Amp* plugin = (Amp*)instance;
+
+ switch (port) {
+ case AMP_GAIN:
+ plugin->gain = (const float*)data;
+ break;
+ case AMP_INPUT:
+ plugin->input = (const float*)data;
+ break;
+ case AMP_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Amp* plugin = (Amp*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case AMP_GAIN:
+ plugin->gain_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Amp* plugin = (Amp*)malloc(sizeof(Amp));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->gain_is_cv = 0;
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Amp* plugin = (Amp*)instance;
+
+ /* Gain (dB) */
+ const float* gain = plugin->gain;
+
+ /* Input */
+ const float* input = plugin->input;
+
+ /* Output */
+ float* output = plugin->output;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float gn = gain[s * plugin->gain_is_cv];
+ const float scale = (float)EXPF(M_LN10 * gn * 0.05f);
+
+ output[s] = scale * input[s];
+ }
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/amp",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/branch.c b/src/branch.c
new file mode 100644
index 0000000..a4de320
--- /dev/null
+++ b/src/branch.c
@@ -0,0 +1,223 @@
+/*
+ An LV2 plugin to split a signal into two.
+ Copyright 2011-2014 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+
+#define BRANCH_INPUT 0
+#define BRANCH_OUTPUT1 1
+#define BRANCH_OUTPUT2 2
+
+typedef struct {
+ const float* input;
+ float* output1;
+ float* output2;
+ LV2_URID input_type;
+ URIs uris;
+} Branch;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Branch* plugin = (Branch*)instance;
+
+ switch (port) {
+ case BRANCH_INPUT:
+ plugin->input = (const float*)data;
+ break;
+ case BRANCH_OUTPUT1:
+ plugin->output1 = (float*)data;
+ break;
+ case BRANCH_OUTPUT2:
+ plugin->output2 = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Branch* plugin = (Branch*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_AudioPort &&
+ port_type != plugin->uris.lv2_CVPort &&
+ port_type != plugin->uris.lv2_ControlPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case BRANCH_INPUT:
+ plugin->input_type = port_type;
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Branch* plugin = (const Branch*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT &&
+ o->subject != BRANCH_OUTPUT1 &&
+ o->subject != BRANCH_OUTPUT2) {
+ fprintf(stderr, "Bad subject %d\n", o->subject);
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ fprintf(stderr, "Bad key %d\n", o->subject);
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = &plugin->input_type;
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Branch* plugin = (Branch*)malloc(sizeof(Branch));
+
+ map_uris(&plugin->uris, features);
+ plugin->input_type = plugin->uris.lv2_ControlPort;
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+runBranch_ia_oaoa(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Branch* plugin = (Branch*)instance;
+
+ /* Input (array of floats of length sample_count) */
+ const float* input = plugin->input;
+
+ /* First Output (array of floats of length sample_count) */
+ float* output1 = plugin->output1;
+
+ /* Second Output (array of floats of length sample_count) */
+ float* output2 = plugin->output2;
+
+ float in;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ in = input[s];
+
+ output1[s] = in;
+ output2[s] = in;
+ }
+}
+
+static void
+runBranch_ic_ococ(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Branch* plugin = (Branch*)instance;
+
+ /* Input (float value) */
+ const float input = *(plugin->input);
+
+ /* First Output (pointer to float value) */
+ float* output1 = plugin->output1;
+
+ /* Second Output (pointer to float value) */
+ float* output2 = plugin->output2;
+
+ output1[0] = input;
+ output2[0] = input;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Branch* plugin = (Branch*)instance;
+
+ if (plugin->input_type == plugin->uris.lv2_AudioPort ||
+ plugin->input_type == plugin->uris.lv2_CVPort) {
+ runBranch_ia_oaoa(instance, sample_count);
+ } else {
+ runBranch_ic_ococ(instance, sample_count);
+ }
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/branch",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/dahdsr.c b/src/dahdsr.c
new file mode 100644
index 0000000..a4b9c65
--- /dev/null
+++ b/src/dahdsr.c
@@ -0,0 +1,416 @@
+/*
+ An LV2 plugin to generate DAHDSR envelopes Gate and (re)trigger
+ Copyright 2011 David Robillard
+ Copyright 2004 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "common.h"
+#include "uris.h"
+
+#define DAHDSR_GATE 0
+#define DAHDSR_TRIGGER 1
+#define DAHDSR_DELAY 2
+#define DAHDSR_ATTACK 3
+#define DAHDSR_HOLD 4
+#define DAHDSR_DECAY 5
+#define DAHDSR_SUSTAIN 6
+#define DAHDSR_RELEASE 7
+#define DAHDSR_OUTPUT 8
+
+typedef enum {
+ IDLE,
+ DELAY,
+ ATTACK,
+ HOLD,
+ DECAY,
+ SUSTAIN,
+ RELEASE
+} DAHDSRState;
+
+typedef struct {
+ const float* gate;
+ const float* trigger;
+ const float* delay;
+ const float* attack;
+ const float* hold;
+ const float* decay;
+ const float* sustain;
+ const float* release;
+ float* output;
+ float srate;
+ float inv_srate;
+ float last_gate;
+ float last_trigger;
+ float from_level;
+ float level;
+ uint32_t delay_is_cv;
+ uint32_t attack_is_cv;
+ uint32_t hold_is_cv;
+ uint32_t decay_is_cv;
+ uint32_t sustain_is_cv;
+ uint32_t release_is_cv;
+ DAHDSRState state;
+ uint32_t samples;
+ URIs uris;
+} Dahdsr;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Dahdsr* plugin = (Dahdsr*)instance;
+
+ switch (port) {
+ case DAHDSR_GATE:
+ plugin->gate = (const float*)data;
+ break;
+ case DAHDSR_TRIGGER:
+ plugin->trigger = (const float*)data;
+ break;
+ case DAHDSR_DELAY:
+ plugin->delay = (const float*)data;
+ break;
+ case DAHDSR_ATTACK:
+ plugin->attack = (const float*)data;
+ break;
+ case DAHDSR_HOLD:
+ plugin->hold = (const float*)data;
+ break;
+ case DAHDSR_DECAY:
+ plugin->decay = (const float*)data;
+ break;
+ case DAHDSR_SUSTAIN:
+ plugin->sustain = (const float*)data;
+ break;
+ case DAHDSR_RELEASE:
+ plugin->release = (const float*)data;
+ break;
+ case DAHDSR_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Dahdsr* plugin = (Dahdsr*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case DAHDSR_DELAY:
+ plugin->delay_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_ATTACK:
+ plugin->attack_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_HOLD:
+ plugin->hold_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_DECAY:
+ plugin->decay_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_SUSTAIN:
+ plugin->sustain_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_RELEASE:
+ plugin->release_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Dahdsr* plugin = (Dahdsr*)malloc(sizeof(Dahdsr));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->srate = (float)sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ plugin->delay_is_cv = 0;
+ plugin->attack_is_cv = 0;
+ plugin->hold_is_cv = 0;
+ plugin->decay_is_cv = 0;
+ plugin->sustain_is_cv = 0;
+ plugin->release_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Dahdsr* plugin = (Dahdsr*)instance;
+
+ plugin->last_gate = 0.0f;
+ plugin->last_trigger = 0.0f;
+ plugin->from_level = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Dahdsr* plugin = (Dahdsr*)instance;
+
+ /* Gate */
+ const float* gate = plugin->gate;
+
+ /* Trigger */
+ const float* trigger = plugin->trigger;
+
+ /* Delay Time (s) */
+ const float* delay = plugin->delay;
+
+ /* Attack Time (s) */
+ const float* attack = plugin->attack;
+
+ /* Hold Time (s) */
+ const float* hold = plugin->hold;
+
+ /* Decay Time (s) */
+ const float* decay = plugin->decay;
+
+ /* Sustain Level */
+ const float* sustain = plugin->sustain;
+
+ /* Release Time (s) */
+ const float* release = plugin->release;
+
+ /* Envelope Out */
+ float* output = plugin->output;
+
+ /* Instance Data */
+ float srate = plugin->srate;
+ float inv_srate = plugin->inv_srate;
+ float last_gate = plugin->last_gate;
+ float last_trigger = plugin->last_trigger;
+ float from_level = plugin->from_level;
+ float level = plugin->level;
+ DAHDSRState state = plugin->state;
+ uint32_t samples = plugin->samples;
+
+ float elapsed;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float dl = delay[s * plugin->delay_is_cv];
+ const float at = attack[s * plugin->attack_is_cv];
+ const float hl = hold[s * plugin->hold_is_cv];
+ const float dc = decay[s * plugin->decay_is_cv];
+ const float st = sustain[s * plugin->sustain_is_cv];
+ const float rl = release[s * plugin->release_is_cv];
+
+ /* Convert times into rates */
+ const float del = dl > 0.0f ? inv_srate / dl : srate;
+ const float att = at > 0.0f ? inv_srate / at : srate;
+ const float hld = hl > 0.0f ? inv_srate / hl : srate;
+ const float dec = dc > 0.0f ? inv_srate / dc : srate;
+ const float rel = rl > 0.0f ? inv_srate / rl : srate;
+
+ const float gat = gate[s];
+ const float trg = trigger[s];
+ const float sus = f_clip(st, 0.0f, 1.0f);
+
+ /* Initialise delay phase if gate is opened and was closed, or
+ we received a trigger */
+ if ((trg > 0.0f && !(last_trigger > 0.0f))
+ || (gat > 0.0f && !(last_gate > 0.0f))) {
+ if (del < srate) {
+ state = DELAY;
+ } else if (att < srate) {
+ state = ATTACK;
+ } else {
+ state = hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE
+ : IDLE)));
+ level = 1.0f;
+ }
+ samples = 0;
+ }
+
+ /* Release if gate was open and now closed */
+ if (state != IDLE && state != RELEASE
+ && last_gate > 0.0f && !(gat > 0.0f)) {
+ state = rel < srate ? RELEASE : IDLE;
+ samples = 0;
+ }
+
+ if (samples == 0) {
+ from_level = level;
+ }
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ level = 0;
+ break;
+ case DELAY:
+ samples++;
+ elapsed = (float)samples * del;
+ if (elapsed > 1.0f) {
+ state = att < srate ? ATTACK
+ : (hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE
+ : IDLE))));
+ samples = 0;
+ }
+ break;
+ case ATTACK:
+ samples++;
+ elapsed = (float)samples * att;
+ if (elapsed > 1.0f) {
+ state = hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE
+ : IDLE)));
+ level = 1.0f;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (1.0f - from_level);
+ }
+ break;
+ case HOLD:
+ samples++;
+ elapsed = (float)samples * hld;
+ if (elapsed > 1.0f) {
+ state = dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE
+ : IDLE));
+ samples = 0;
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (float)samples * dec;
+ if (elapsed > 1.0f) {
+ state = gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE
+ : IDLE);
+ level = sus;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (sus - from_level);
+ }
+ break;
+ case SUSTAIN:
+ level = sus;
+ break;
+ case RELEASE:
+ samples++;
+ elapsed = (float)samples * rel;
+ if (elapsed > 1.0f) {
+ state = IDLE;
+ level = 0.0f;
+ samples = 0;
+ } else {
+ level = from_level - elapsed * from_level;
+ }
+ break;
+ default:
+ /* Should never happen */
+ level = 0.0f;
+ }
+
+ output[s] = level;
+
+ last_gate = gate[s];
+ last_trigger = trigger[s];
+ }
+
+ plugin->last_gate = last_gate;
+ plugin->last_trigger = last_trigger;
+ plugin->from_level = from_level;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/dahdsr",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/difference.c b/src/difference.c
new file mode 100644
index 0000000..9e76e0a
--- /dev/null
+++ b/src/difference.c
@@ -0,0 +1,188 @@
+/*
+ An LV2 plugin to calculate the difference of two signals.
+ Copyright 2011 David Robillard
+ Copyright 2004 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "vector_op.h"
+
+#define DIFFERENCE_MINUEND 0
+#define DIFFERENCE_SUBTRAHEND 1
+#define DIFFERENCE_DIFFERENCE 2
+
+typedef struct {
+ const float* minuend;
+ const float* subtrahend;
+ float* difference;
+ uint32_t minuend_is_cv;
+ uint32_t subtrahend_is_cv;
+ uint32_t difference_is_cv;
+ URIs uris;
+} Difference;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Difference* plugin = (Difference*)instance;
+
+ switch (port) {
+ case DIFFERENCE_MINUEND:
+ plugin->minuend = (const float*)data;
+ break;
+ case DIFFERENCE_SUBTRAHEND:
+ plugin->subtrahend = (const float*)data;
+ break;
+ case DIFFERENCE_DIFFERENCE:
+ plugin->difference = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Difference* plugin = (Difference*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case DIFFERENCE_MINUEND:
+ plugin->minuend_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case DIFFERENCE_SUBTRAHEND:
+ plugin->subtrahend_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ plugin->difference_is_cv = plugin->minuend_is_cv || plugin->subtrahend_is_cv;
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Difference* plugin = (const Difference*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT ||
+ o->subject != DIFFERENCE_DIFFERENCE) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = (plugin->difference_is_cv
+ ? &plugin->uris.lv2_CVPort
+ : &plugin->uris.lv2_ControlPort);
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Difference* plugin = (Difference*)malloc(sizeof(Difference));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->minuend_is_cv = 0;
+ plugin->subtrahend_is_cv = 0;
+ plugin->difference_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ const Difference* const plugin = (Difference*)instance;
+ const float* const minuend = plugin->minuend;
+ const float* const subtrahend = plugin->subtrahend;
+ float* const difference = plugin->difference;
+
+ VECTOR_OP(-, difference,
+ minuend, plugin->minuend_is_cv,
+ subtrahend, plugin->subtrahend_is_cv);
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/difference",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/fmod.c b/src/fmod.c
new file mode 100644
index 0000000..9284d9d
--- /dev/null
+++ b/src/fmod.c
@@ -0,0 +1,199 @@
+/*
+ An LV2 plugin to modulate a frequency by a signal.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "math_func.h"
+#include "uris.h"
+
+#define FMOD_FREQUENCY 0
+#define FMOD_MODULATOR 1
+#define FMOD_OUTPUT 2
+
+typedef struct {
+ const float* frequency;
+ const float* modulator;
+ float* output;
+ uint32_t frequency_is_cv;
+ uint32_t modulator_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
+} Fmod;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Fmod* plugin = (Fmod*)instance;
+
+ switch (port) {
+ case FMOD_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case FMOD_MODULATOR:
+ plugin->modulator = (const float*)data;
+ break;
+ case FMOD_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Fmod* plugin = (Fmod*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case FMOD_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case FMOD_MODULATOR:
+ plugin->modulator_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Fmod* plugin = (const Fmod*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT || o->subject != FMOD_OUTPUT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = (plugin->output_is_cv
+ ? &plugin->uris.lv2_CVPort
+ : &plugin->uris.lv2_ControlPort);
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Fmod* plugin = (Fmod*)malloc(sizeof(Fmod));
+
+ if (plugin) {
+ plugin->frequency_is_cv = 0;
+ plugin->modulator_is_cv = 0;
+ plugin->output_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Fmod* plugin = (Fmod*)instance;
+
+ /* Frequency to Modulate (array of floats of length 1 or sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* LFO Input (array of floats of length 1 or sample_count) */
+ const float* modulator = plugin->modulator;
+
+ /* Output Frequency (array of floats of length 1 or sample_count) */
+ float* output = plugin->output;
+
+ if (!plugin->output_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
+ }
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ const float mod = modulator[s * plugin->modulator_is_cv];
+ const float scale = (float)EXPF(M_LN2 * mod);
+
+ output[s] = scale * freq;
+ }
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/fmod",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/include/common.h b/src/include/common.h
new file mode 100644
index 0000000..26a405a
--- /dev/null
+++ b/src/include/common.h
@@ -0,0 +1,54 @@
+/*
+ Common definitions.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef blop_common_h
+#define blop_common_h
+
+#include "math_func.h"
+
+/* Handy constants and macros */
+
+#ifndef SMALLEST_FLOAT
+/** Smallest generated non-zero float, used for pre-empting denormals */
+#define SMALLEST_FLOAT (1.0 / (float)0xFFFFFFFF)
+#endif
+
+/*
+ * Clip without branch (from http://musicdsp.org)
+ */
+
+static inline float
+f_min (float x, float a)
+{
+ return a - (a - x + FABSF (a - x)) * 0.5f;
+}
+
+static inline float
+f_max (float x, float b)
+{
+ return (x - b + FABSF (x - b)) * 0.5f + b;
+}
+
+static inline float
+f_clip (float x, float a, float b)
+{
+ return 0.5f * (FABSF (x - a) + a + b - FABSF (x - b));
+}
+
+#endif /* blop_common_h */
diff --git a/src/include/interpolate.h b/src/include/interpolate.h
new file mode 100644
index 0000000..237008c
--- /dev/null
+++ b/src/include/interpolate.h
@@ -0,0 +1,74 @@
+#ifndef blop_interpolate_h
+#define blop_interpolate_h
+
+#include "blop_config.h"
+#include "math_func.h"
+
+/**
+ Interpolate between p0 and n0 taking the previous (p1) and next (n1) points
+ into account, using a 3rd order polynomial (a.k.a. cubic spline).
+ @param interval Normalised time interval between intepolated sample and p0
+ @param p1 Sample two previous to interpolated one
+ @param p0 Previous sample to interpolated one
+ @param n0 Sample following interpolated one
+ @param n1 Sample following n0
+ @return Interpolated sample.
+
+ Adapted from Steve Harris' plugin code
+ swh-plugins-0.2.7/ladspa-util.h::cube_interp
+ http://plugin.org.uk/releases/0.2.7/
+*/
+static inline float
+interpolate_cubic(float interval,
+ float p1,
+ float p0,
+ float n0,
+ float n1)
+{
+ return p0 + 0.5f * interval * (n0 - p1 +
+ interval * (4.0f * n0 + 2.0f * p1 - 5.0f * p0 - n1 +
+ interval * (3.0f * (p0 - n0) - p1 + n1)));
+}
+
+/**
+ Interpolate between p0 and n0 taking the previous (p1) and next (n1) points
+ into account, using a 5th order polynomial.
+ @param interval Normalised time interval between intepolated sample and p0
+ @param p1 Sample two previous to interpolated one
+ @param p0 Previous sample to interpolated one
+ @param n0 Sample following interpolated one
+ @param n1 Sample following n0
+ @return Interpolated sample.
+
+ Adapted from http://www.musicdsp.org/archive.php?classid=5#62
+*/
+static inline float
+interpolate_quintic(float interval,
+ float p1,
+ float p0,
+ float n0,
+ float n1)
+{
+ return p0 + 0.5f * interval * (n0 - p1 +
+ interval * (n0 - 2.0f * p0 + p1 +
+ interval * ( 9.0f * (n0 - p0) + 3.0f * (p1 - n1) +
+ interval * (15.0f * (p0 - n0) + 5.0f * (n1 - p1) +
+ interval * ( 6.0f * (n0 - p0) + 2.0f * (p1 - n1))))));
+}
+
+/**
+ Linear interpolation
+*/
+static inline float
+f_lerp (float value,
+ float v1,
+ float v2)
+{
+ value -= LRINTF (value - 0.5f);
+ value *= (v2 - v1);
+ value += v1;
+
+ return value;
+}
+
+#endif /* blop_interpolate_h */
diff --git a/src/include/lp4pole_filter.h b/src/include/lp4pole_filter.h
new file mode 100644
index 0000000..310fbbe
--- /dev/null
+++ b/src/include/lp4pole_filter.h
@@ -0,0 +1,137 @@
+/*
+ Header for lp4pole_filter struct, and functions to run instance.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ Originally originally appeared in CSound as Timo Tossavainen's (sp?)
+ implementation from the Stilson/Smith CCRMA paper.
+
+ See http://musicdsp.org/archive.php?classid=3#26
+
+ Originally appeared in the arts softsynth by Stefan Westerfeld:
+ http://www.arts-project.org/
+
+ First ported to LADSPA by Reiner Klenk (pdq808[at]t-online.de)
+
+ Tuning and stability issues (output NaN) and additional audio-rate
+ variant added by Mike Rawes (mike_rawes[at]yahoo.co.uk)
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef blop_lp4pole_filter_h
+#define blop_lp4pole_filter_h
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "common.h"
+
+typedef struct {
+ float f;
+ float coeff;
+ float fb;
+ float in1;
+ float in2;
+ float in3;
+ float in4;
+ float inv_nyquist;
+ float out1;
+ float out2;
+ float out3;
+ float out4;
+ float max_abs_in;
+} LP4PoleFilter;
+
+/**
+ Allocate a new LP4PoleFilter instance.
+ @param sample_rate Intended playback (DAC) rate
+ @return Allocated LP4PoleFilter instance
+*/
+LP4PoleFilter* lp4pole_new(double sample_rate);
+
+/**
+ Cleanup an existing LP4PoleFilter instance.
+ @param lpf Pointer to LP4PoleFilter instance allocated with initFilter
+*/
+void lp4pole_cleanup(LP4PoleFilter* lpf);
+
+/**
+ Initialise filter.
+ @param lpf Pointer to LP4PoleFilter instance allocated with initFilter
+*/
+void lp4pole_init(LP4PoleFilter* lpf);
+
+/**
+ Set up filter coefficients for given LP4Pole instance.
+ @param lpf Pointer to LP4PoleFilter instance
+ @param cutoff Cutoff frequency in Hz
+ @param resonance Resonance [Min=0.0, Max=4.0]
+*/
+static inline void
+lp4pole_set_params(LP4PoleFilter* lpf,
+ float cutoff,
+ float resonance)
+{
+ float fsqd;
+ float tuning;
+
+ /* Normalise cutoff and find tuning - Magic numbers found empirically :) */
+ lpf->f = cutoff * lpf->inv_nyquist;
+ tuning = f_clip(3.13f - (lpf->f * 4.24703592f), 1.56503274f, 3.13f);
+
+ /* Clip to bounds */
+ lpf->f = f_clip(lpf->f * tuning, lpf->inv_nyquist, 1.16f);
+
+ fsqd = lpf->f * lpf->f;
+ lpf->coeff = fsqd * fsqd * 0.35013f;
+
+ lpf->fb = f_clip(resonance, -1.3f, 4.0f) * (1.0f - 0.15f * fsqd);
+
+ lpf->f = 1.0f - lpf->f;
+}
+
+/**
+ Run given LP4PoleFilter instance for a single sample.
+ @param lpf Pointer to LP4PoleFilter instance
+ @param in Input sample
+ @return Filtered sample
+*/
+static inline float
+lp4pole_run(LP4PoleFilter* lpf,
+ float in)
+{
+ const float abs_in = fabsf(16.0f * in); /* ~24dB unclipped headroom */
+
+ lpf->max_abs_in = f_max(lpf->max_abs_in, abs_in);
+
+ in -= lpf->out4 * lpf->fb;
+ in *= lpf->coeff;
+
+ lpf->out1 = in + 0.3f * lpf->in1 + lpf->f * lpf->out1; /* Pole 1 */
+ lpf->in1 = in;
+ lpf->out2 = lpf->out1 + 0.3f * lpf->in2 + lpf->f * lpf->out2; /* Pole 2 */
+ lpf->in2 = lpf->out1;
+ lpf->out3 = lpf->out2 + 0.3f * lpf->in3 + lpf->f * lpf->out3; /* Pole 3 */
+ lpf->in3 = lpf->out2;
+ lpf->out4 = lpf->out3 + 0.3f * lpf->in4 + lpf->f * lpf->out4; /* Pole 4 */
+ lpf->in4 = lpf->out3;
+
+ /* Simple hard clip to prevent NaN */
+ lpf->out4 = f_clip(lpf->out4, -lpf->max_abs_in, lpf->max_abs_in);
+
+ lpf->max_abs_in *= 0.999f;
+
+ return lpf->out4;
+}
+
+#endif /* blop_lp4pole_filter_h */
diff --git a/src/include/math_func.h b/src/include/math_func.h
new file mode 100644
index 0000000..60f7ce0
--- /dev/null
+++ b/src/include/math_func.h
@@ -0,0 +1,48 @@
+/*
+ * Provide double fallbacks for environments lacking sinf and
+ * friends (e.g. Solaris)
+ */
+
+#ifndef math_func_h
+#define math_func_h
+
+#include <math.h>
+#include "blop_config.h"
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846 /* pi */
+#endif
+
+#ifndef M_LN10
+# define M_LN10 2.30258509299404568402 /* log_e(10) */
+#endif
+
+#ifndef M_LN2
+# define M_LN2 0.69314718055994530942 /* log_e(2) */
+#endif
+
+#ifdef HAVE_SINF
+/* Use float functions */
+#define SINF(x) sinf(x)
+#define COSF(x) cosf(x)
+#define FABSF(x) fabsf(x)
+#define FLOORF(x) floorf(x)
+#define EXPF(x) expf(x)
+#define POWF(x,p) powf(x,p)
+#define COPYSIGNF(s,d) copysignf(s,d)
+#define LRINTF(x) lrintf(x)
+
+#else
+/* Use double functions */
+#define SINF(x) sin(x)
+#define COSF(x) cos(x)
+#define FABSF(x) fabs(x)
+#define FLOORF(x) floor(x)
+#define EXPF(x) exp(x)
+#define POWF(x,p) pow(x)
+#define COPYSIGNF(s,d) copysign(s,d)
+#define LRINTF(x) lrint(x)
+
+#endif
+
+#endif
diff --git a/src/include/uris.h b/src/include/uris.h
new file mode 100644
index 0000000..0c35628
--- /dev/null
+++ b/src/include/uris.h
@@ -0,0 +1,59 @@
+/*
+ Common URIs used by plugins.
+ Copyright 2012 David Robillard
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef blop_uris_h
+#define blop_uris_h
+
+#include <string.h>
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+typedef struct {
+ LV2_URID atom_URID;
+ LV2_URID lv2_AudioPort;
+ LV2_URID lv2_CVPort;
+ LV2_URID lv2_ControlPort;
+ LV2_URID morph_currentType;
+} URIs;
+
+static inline void
+map_uris(URIs* uris,
+ const LV2_Feature* const* features)
+{
+ LV2_URID_Map* map = NULL;
+ for (int i = 0; features[i]; ++i) {
+ if (!strcmp(features[i]->URI, LV2_URID__map)) {
+ map = (LV2_URID_Map*)features[i]->data;
+ break;
+ }
+ }
+
+ if (map) {
+ uris->atom_URID = map->map(map->handle, LV2_ATOM__URID);
+ uris->lv2_AudioPort = map->map(map->handle, LV2_CORE__AudioPort);
+ uris->lv2_CVPort = map->map(map->handle, LV2_CORE__CVPort);
+ uris->lv2_ControlPort = map->map(map->handle, LV2_CORE__ControlPort);
+ uris->morph_currentType = map->map(map->handle, LV2_MORPH__currentType);
+ } else {
+ memset(uris, 0, sizeof(*uris));
+ }
+}
+
+#endif /* blop_uris_h */
diff --git a/src/include/vector_op.h b/src/include/vector_op.h
new file mode 100644
index 0000000..f261ff8
--- /dev/null
+++ b/src/include/vector_op.h
@@ -0,0 +1,44 @@
+/*
+ Apply a C arithmetical operator to two sample buffers.
+ Copyright 2012-2014 David Robillard
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef BLOP_VECTOR_OP_H
+#define BLOP_VECTOR_OP_H
+
+#define VECTOR_OP(op, output, input1, input1_is_cv, input2, input2_is_cv) \
+ switch ((input1_is_cv << 1) + input2_is_cv) { \
+ case 0: /* 00 (control * control) */ \
+ output[0] = input1[0] op input2[0]; \
+ break; \
+ case 1: /* 01 (control * cv) */ \
+ for (uint32_t s = 0; s < sample_count; ++s) { \
+ output[s] = input1[0] op input2[s]; \
+ } \
+ break; \
+ case 2: /* 10 (cv * control) */ \
+ for (uint32_t s = 0; s < sample_count; ++s) { \
+ output[s] = input1[s] op input2[0]; \
+ } \
+ break; \
+ case 3: /* 11 (cv * cv) */ \
+ for (uint32_t s = 0; s < sample_count; ++s) { \
+ output[s] = input1[s] op input2[s]; \
+ } \
+ break; \
+ }
+
+#endif /* BLOP_VECTOR_OP_H */
diff --git a/src/include/wavedata.h b/src/include/wavedata.h
new file mode 100644
index 0000000..97b2986
--- /dev/null
+++ b/src/include/wavedata.h
@@ -0,0 +1,193 @@
+/*
+ Structures to represent a set of wavetables.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef blop_wavedata_h
+#define blop_wavedata_h
+
+#include "blop_config.h"
+#include "math_func.h"
+#include "interpolate.h"
+#include "common.h"
+
+/* Functions identifying wavedata dlls */
+#define BLOP_DLSYM_SAWTOOTH "blop_get_sawtooth"
+#define BLOP_DLSYM_SQUARE "blop_get_square"
+#define BLOP_DLSYM_PARABOLA "blop_get_parabola"
+
+/*
+ * Structure holding a single segment of sample data
+ * along with information relating to playback.
+ */
+typedef struct {
+ unsigned long sample_count; /* Sample count */
+ float* samples_lf; /* Sample data played back at amplitude
+ inversely proportional to frequency */
+ float* samples_hf; /* Sample data played back at amplitude
+ proportional to frequency */
+ unsigned long harmonics; /* Max harmonic content of sample data */
+
+ float phase_scale_factor; /* Phase scale factor for playback */
+ float min_frequency; /* Minimum playback frequency */
+ float max_frequency; /* Maximum playback frequency */
+ float range_scale_factor; /* Blend scale factor for cross fading */
+} Wavetable;
+
+/*
+ * Structure holding the wavetable data and playback state
+ */
+typedef struct {
+ void* data_handle; /* Data DLL handle */
+ unsigned long table_count; /* Number of wavetables in wavedata */
+ Wavetable** tables; /* One or more wavetables, plus pair of
+ extra tables for frequency extremes */
+ unsigned long* lookup; /* Wavetable lookup vector */
+ unsigned long lookup_max; /* For clipping lookup indices */
+
+ float sample_rate; /* Sample rate */
+ float nyquist; /* Nyquist rate (sample_rate / 2) */
+
+ /* Playback state */
+ float frequency; /* Current playback frequency */
+ float abs_freq; /* Absolute playback frequency */
+ float xfade; /* Crossfade factor for fading */
+ Wavetable* table; /* Wavetable to playback */
+} Wavedata;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int wavedata_load(Wavedata* w,
+ const char* bundle_path,
+ const char* lib_name,
+ const char* wdat_descriptor_name,
+ double sample_rate);
+
+void wavedata_unload(Wavedata* w);
+
+/*****************************************************************************
+ * Description: Get interpolated sample from current wavetable in wavedata
+ * at given phase offset
+ *
+ * Arguments: w Wavedata containing playback state and data
+ * phase Phase offset [0.0, sample_rate]
+ *
+ * Returns: Interpolated sample
+ *
+ * Notes: Cubic (or quintic) interpolation requires four consecutive
+ * samples for operation:
+ *
+ * phase
+ * :
+ * p1 p0 : n0 n1
+ * | | x | |
+ * : :
+ * <-o->
+ * :
+ * interval
+ *
+ * Phase values less than one make p0 the first sample in
+ * the table - p1 will be the last sample, as a previous
+ * sample does not exist. To avoid checking for this case,
+ * a copy of the last sample is stored before the first
+ * sample in each table.
+ * Likewise, if the phase means p0 is the last sample, n0
+ * and n1 will be the first and second samples respectively.
+ * Copies of these samples are stored after the last sample
+ * in each table.
+ *
+ *****************************************************************************/
+static inline float
+wavedata_get_sample(Wavedata* w,
+ float phase)
+{
+ float* samples_hf = w->table->samples_hf;
+ float* samples_lf = w->table->samples_lf;
+ float p1, p0, n0, n1;
+ float phase_f;
+ long int index;
+
+ /* Scale phase to map to position in wavetable */
+ phase *= w->table->phase_scale_factor;
+
+ /* Get position of first contributing sample (p1) */
+ index = LRINTF((float)phase - 0.5f);
+ phase_f = (float)index;
+
+ index %= w->table->sample_count;
+
+ /* Cross-fade table pairs */
+ /* Previous two samples */
+ p1 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
+ index++;
+ p0 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
+ index++;
+ /* Next two samples */
+ n0 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
+ index++;
+ n1 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
+
+ /* Return interpolated sample */
+ return interpolate_cubic(phase - phase_f, p1, p0, n0, n1);
+}
+
+/*****************************************************************************
+ * Description: Get wavetable to use for playback frequency.
+ *
+ * Arguments: w Wavedata object (contains all table info)
+ * frequency Playback frequency
+ *
+ * Notes: The lookup vector used to determine the wavetable
+ * is indexed by harmonic number.
+ *
+ * The maximum playback frequency for a wavetable is
+ * determined by its harmonic content and the sample rate,
+ * and equals sample_rate / 2 / max_harmonic_in_table.
+ *
+ *****************************************************************************/
+static inline void
+wavedata_get_table(Wavedata* w,
+ float frequency)
+{
+ unsigned long harmonic;
+
+ w->frequency = frequency;
+ w->abs_freq = (float)FABSF((float)frequency);
+
+ /* Get highest harmonic possible in frequency */
+ harmonic = LRINTF(w->nyquist / w->abs_freq - 0.5f);
+
+ /* Clip so lookup is within bounds */
+ if (harmonic > w->lookup_max) {
+ harmonic = w->lookup_max;
+ }
+
+ /* Set playback table */
+ w->table = w->tables[w->lookup[harmonic]];
+
+ /* Get cross fade factor */
+ w->xfade = f_max(w->table->max_frequency - w->abs_freq, 0.0f) * w->table->range_scale_factor;
+ w->xfade = f_min(w->xfade, 1.0f);
+}
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+#endif /* blop_wavedata_h */
diff --git a/src/include/wdatutil.h b/src/include/wdatutil.h
new file mode 100644
index 0000000..9a0810a
--- /dev/null
+++ b/src/include/wdatutil.h
@@ -0,0 +1,141 @@
+/*
+ Code to generate wavedata dl containing pre-calculated wavetables.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef blop_wdatutil_h
+#define blop_wdatutil_h
+
+#include <stdio.h>
+#include <stdint.h>
+#include "math_func.h"
+#include "wavedata.h"
+
+#define WAVE_TYPE_COUNT 3
+
+extern const char* wave_names[];
+extern const char* wave_descriptions[];
+extern unsigned long wave_first_harmonics[];
+extern unsigned long wave_harmonic_intervals[];
+
+/** Get actual maximum harmonic from given harmonic, h, and wavetype, w */
+#define ACTUAL_HARM(h, w) h - (h - wave_first_harmonics[w]) % wave_harmonic_intervals[w]
+
+/** Get minimum harmonic content in given wavetype, w */
+#define MIN_HARM(w) wave_first_harmonics[w]
+
+/** Get minimum extra harmonic content possible in given wavetype, w */
+#define MIN_EXTRA_HARM(w) wave_harmonic_intervals[w]
+
+/** Get frequency from MIDI note, n */
+#define FREQ_FROM_NOTE(n) 6.875f * POWF(2.0f, (float)(n + 3) / 12.0f)
+
+/** Get max harmonic from given frequency, f, at sample rate, r */
+#define HARM_FROM_FREQ(f, r) (unsigned long)((float)r / f / 2.0f)
+
+/*
+ * A single wavetable will have a range of pitches at which their samples
+ * may be played back.
+ *
+ * The upper bound is determined by the maximum harmonic present in the
+ * waveform - above this frequency, the higher harmonics will alias.
+ *
+ * The lower bound is chosen to be the higher bound of the previous wavetable
+ * (or a pre-defined limit if there is no such table).
+ */
+
+typedef enum {
+ SAW,
+ SQUARE,
+ PARABOLA
+} Wavetype;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * Description: Allocate new wavedata struct
+ *
+ * Arguments: sample_rate Sample rate to use when generating data
+ *
+ * Returns: Pointer to wavedata on success
+ * NULL (0) on failure
+ *
+ * Notes: No wavetables are allocated. Use wavedata_add_table
+ ******************************************************************************/
+Wavedata* wavedata_new(double sample_rate);
+
+/*******************************************************************************
+ * Description: Destroy allocated wavedata and any tables
+ *
+ * Arguments: w Wavedata struct to cleanup
+ ******************************************************************************/
+void wavedata_cleanup(Wavedata* w);
+
+/*******************************************************************************
+ * Description: Add new wavetable information to wavedata file object
+ *
+ * Arguments: w Wavedata to add table to
+ * sample_count Number of samples in wavetable
+ * harmonics Maximum harmonics present in table
+ *
+ * Returns: 0 on success
+ * -1 otherwise
+ ******************************************************************************/
+int wavedata_add_table(Wavedata* w,
+ uint32_t sample_count,
+ unsigned long harmonics);
+
+/*******************************************************************************
+ * Description: Initialise all wavetables in wavedata with a waveform
+ * generated from Fourier series.
+ *
+ * Arguments: w Wavedata to generate data for
+ * wavetype Wavetype to generate
+ * gibbs_comp Compensation for Gibbs' effect:
+ * 0.0: none (wave will overshoot)
+ * 1.0: full (wave will not overshoot)
+ *
+ * Notes: Compensation for Gibbs' Effect will reduce the degree
+ * of overshoot and ripple at the transitions. A value of 1.0
+ * will pretty much eliminate it.
+ ******************************************************************************/
+void wavedata_generate_tables(Wavedata* w,
+ Wavetype wavetype,
+ float gibbs_comp);
+
+/*******************************************************************************
+ * Description: Write wavedata as a c header file
+ *
+ * Arguments: w Wavedata to write
+ * wdat_fp Pointer to output file
+ * prefix Prefix to use in declarations. If this is null
+ * declarations are prefixed with 'wdat'.
+ *
+ * Returns: 0 on success
+ * -1 otherwise
+ ******************************************************************************/
+int wavedata_write(Wavedata* w,
+ FILE* wdat_fp,
+ const char* prefix);
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+#endif /* blop_wdatutil_h */
diff --git a/src/interpolator.c b/src/interpolator.c
new file mode 100644
index 0000000..e47fbe3
--- /dev/null
+++ b/src/interpolator.c
@@ -0,0 +1,144 @@
+/*
+ An LV2 plugin to generate a smooth audio signal from a control source.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+
+#define INTERPOLATOR_INPUT 0
+#define INTERPOLATOR_OUTPUT 1
+
+/**
+ Mutated spline interpolator using only two previous samples and one next.
+ @param interval Normalised time interval between inteprolated sample and p0
+ @param p1 Sample two previous to interpolated one
+ @param p0 Previous sample to interpolated one
+ @param n0 Sample following interpolated one
+ @return Interpolated sample.
+*/
+static inline float
+interpolate(float interval,
+ float p1,
+ float p0,
+ float n0)
+{
+ return p0 + 0.5f * interval * (n0 - p1 +
+ interval * (4.0f * n0 + 2.0f * p1 - 5.0f * p0 - n0 +
+ interval * (3.0f * (p0 - n0) - p1 + n0)));
+}
+
+typedef struct {
+ const float* input;
+ float* output;
+ float p1;
+ float p0;
+} Interpolator;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Interpolator* plugin = (Interpolator*)instance;
+
+ switch (port) {
+ case INTERPOLATOR_INPUT:
+ plugin->input = (const float*)data;
+ break;
+ case INTERPOLATOR_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Interpolator* plugin = (Interpolator*)malloc(sizeof(Interpolator));
+ if (!plugin) {
+ return NULL;
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Interpolator* plugin = (Interpolator*)instance;
+
+ plugin->p1 = 0.0f;
+ plugin->p0 = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Interpolator* plugin = (Interpolator*)instance;
+
+ /* Control Input (float value) */
+ const float input = *(plugin->input);
+
+ /* Interpolated Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* We use two previous values and the input as the 'next' one */
+ float p1 = plugin->p1;
+ float p0 = plugin->p0;
+
+ const float inv_scount = 1.0f / (float)sample_count;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float interval = (float)s * inv_scount;
+
+ output[s] = interpolate(interval, p1, p0, input);
+ }
+
+ plugin->p1 = p0;
+ plugin->p0 = input;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/interpolator",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ NULL,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/lp4pole.c b/src/lp4pole.c
new file mode 100644
index 0000000..7d2eb6b
--- /dev/null
+++ b/src/lp4pole.c
@@ -0,0 +1,206 @@
+/*
+ An LV2 plugin simulating a 4 pole low pass resonant filter.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "lp4pole_filter.h"
+#include "common.h"
+#include "uris.h"
+
+#define LP4POLE_CUTOFF 0
+#define LP4POLE_RESONANCE 1
+#define LP4POLE_INPUT 2
+#define LP4POLE_OUTPUT 3
+
+typedef struct {
+ const float* cutoff;
+ const float* resonance;
+ const float* input;
+ float* output;
+ LP4PoleFilter* lpf;
+ uint32_t cutoff_is_cv;
+ uint32_t resonance_is_cv;
+ URIs uris;
+} Lp4pole;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ Lp4pole* plugin = (Lp4pole*)instance;
+
+ lp4pole_cleanup(plugin->lpf);
+
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Lp4pole* plugin = (Lp4pole*)instance;
+
+ switch (port) {
+ case LP4POLE_CUTOFF:
+ plugin->cutoff = (const float*)data;
+ break;
+ case LP4POLE_RESONANCE:
+ plugin->resonance = (const float*)data;
+ break;
+ case LP4POLE_INPUT:
+ plugin->input = (const float*)data;
+ break;
+ case LP4POLE_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Lp4pole* plugin = (Lp4pole*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case LP4POLE_CUTOFF:
+ plugin->cutoff_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case LP4POLE_RESONANCE:
+ plugin->resonance_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Lp4pole* plugin = (Lp4pole*)malloc(sizeof(Lp4pole));
+
+ if (plugin) {
+ plugin->lpf = lp4pole_new(sample_rate);
+ if (!plugin->lpf) {
+ free(plugin);
+ return NULL;
+ }
+ plugin->cutoff_is_cv = 0;
+ plugin->resonance_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Lp4pole* plugin = (Lp4pole*)instance;
+
+ lp4pole_init(plugin->lpf);
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Lp4pole* plugin = (Lp4pole*)instance;
+
+ /* Cutoff Frequency (array of floats of length 1 or sample_count) */
+ const float* cutoff = plugin->cutoff;
+
+ /* Resonance (array of floats of length 1 or sample_count) */
+ const float* resonance = plugin->resonance;
+
+ /* Input (array of floats of length sample_count) */
+ const float* input = plugin->input;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ LP4PoleFilter* lpf = plugin->lpf;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float co = cutoff[s * plugin->cutoff_is_cv];
+ const float res = resonance[s * plugin->resonance_is_cv];
+ const float in = input[s];
+
+ /* TODO: There is no branching in this function.
+ Would it actually be faster to check if co or res has changed?
+ */
+ lp4pole_set_params(lpf, co, res);
+
+ output[s] = lp4pole_run(lpf, in);
+ }
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/lp4pole",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/lp4pole_filter.c b/src/lp4pole_filter.c
new file mode 100644
index 0000000..7d54691
--- /dev/null
+++ b/src/lp4pole_filter.c
@@ -0,0 +1,55 @@
+/*
+ lp4pole filter admin.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ See lp4pole_filter.h for history
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "lp4pole_filter.h"
+
+LP4PoleFilter*
+lp4pole_new(double sample_rate)
+{
+ LP4PoleFilter* lpf;
+
+ lpf = (LP4PoleFilter*)malloc(sizeof(LP4PoleFilter));
+
+ if (lpf) {
+ lpf->inv_nyquist = 2.0f / sample_rate;
+ lp4pole_init(lpf);
+ }
+
+ return lpf;
+}
+
+void
+lp4pole_cleanup(LP4PoleFilter* lpf)
+{
+ if (lpf) {
+ free(lpf);
+ }
+}
+
+void
+lp4pole_init(LP4PoleFilter* lpf)
+{
+ lpf->in1 = lpf->in2 = lpf->in3 = lpf->in4 = 0.0f;
+ lpf->out1 = lpf->out2 = lpf->out3 = lpf->out4 = 0.0f;
+ lpf->max_abs_in = 0.0f;
+}
diff --git a/src/product.c b/src/product.c
new file mode 100644
index 0000000..007d853
--- /dev/null
+++ b/src/product.c
@@ -0,0 +1,187 @@
+/*
+ An LV2 plugin to calculate the product of two signals.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "vector_op.h"
+
+#define PRODUCT_MULTIPLICAND 0
+#define PRODUCT_MULTIPLIER 1
+#define PRODUCT_PRODUCT 2
+
+typedef struct {
+ const float* input1;
+ const float* input2;
+ float* output;
+ uint32_t input1_is_cv;
+ uint32_t input2_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
+} Product;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Product* plugin = (Product*)instance;
+
+ switch (port) {
+ case PRODUCT_MULTIPLICAND:
+ plugin->input1 = (const float*)data;
+ break;
+ case PRODUCT_MULTIPLIER:
+ plugin->input2 = (const float*)data;
+ break;
+ case PRODUCT_PRODUCT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Product* plugin = (Product*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case PRODUCT_MULTIPLICAND:
+ plugin->input1_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case PRODUCT_MULTIPLIER:
+ plugin->input2_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ plugin->output_is_cv = plugin->input1_is_cv || plugin->input2_is_cv;
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Product* plugin = (const Product*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT || o->subject != PRODUCT_PRODUCT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = (plugin->output_is_cv
+ ? &plugin->uris.lv2_CVPort
+ : &plugin->uris.lv2_ControlPort);
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Product* plugin = (Product*)malloc(sizeof(Product));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->input1_is_cv = 0;
+ plugin->input2_is_cv = 0;
+ plugin->output_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ const Product* const plugin = (Product*)instance;
+ const float* const input1 = plugin->input1;
+ const float* const input2 = plugin->input2;
+ float* const output = plugin->output;
+
+ VECTOR_OP(*, output,
+ input1, plugin->input1_is_cv,
+ input2, plugin->input2_is_cv);
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/product",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/pulse.c b/src/pulse.c
new file mode 100644
index 0000000..29e1001
--- /dev/null
+++ b/src/pulse.c
@@ -0,0 +1,225 @@
+/*
+ An LV2 plugin to generate a bandlimited variable pulse waveform.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "wavedata.h"
+
+#define PULSE_FREQUENCY 0
+#define PULSE_PULSEWIDTH 1
+#define PULSE_OUTPUT 2
+
+typedef struct {
+ const float* frequency;
+ const float* pulsewidth;
+ float* output;
+ float phase;
+ uint32_t frequency_is_cv;
+ uint32_t pulsewidth_is_cv;
+ Wavedata wdat;
+ URIs uris;
+} Pulse;
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Pulse* plugin = (Pulse*)instance;
+
+ switch (port) {
+ case PULSE_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case PULSE_PULSEWIDTH:
+ plugin->pulsewidth = (const float*)data;
+ break;
+ case PULSE_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Pulse* plugin = (Pulse*)malloc(sizeof(Pulse));
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case PULSE_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case PULSE_PULSEWIDTH:
+ plugin->pulsewidth_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Pulse* plugin = (Pulse*)malloc(sizeof(Pulse));
+ if (!plugin) {
+ return NULL;
+ }
+
+ if (wavedata_load(&plugin->wdat, bundle_path, "sawtooth_data",
+ BLOP_DLSYM_SAWTOOTH, sample_rate)) {
+ free(plugin);
+ return 0;
+ }
+
+ plugin->frequency_is_cv = 0;
+ plugin->pulsewidth_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ Pulse* plugin = (Pulse*)instance;
+
+ wavedata_unload(&plugin->wdat);
+ free(instance);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Pulse* plugin = (Pulse*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Pulse* plugin = (Pulse*)instance;
+
+ /* Frequency (array of float of length sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Pulse Width (array of float of length sample_count) */
+ const float* pulsewidth = plugin->pulsewidth;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ Wavedata* wdat = &plugin->wdat;
+ float phase = plugin->phase;
+
+ float last_pwidth = pulsewidth[0];
+ float pwidth = f_clip(last_pwidth, 0.0f, 1.0f);
+ float dc_shift = 1.0 - (2.0 * pwidth);
+ float phase_shift = pwidth * wdat->sample_rate;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ if (freq != wdat->frequency) {
+ /* Frequency changed, look up table to play */
+ wavedata_get_table(wdat, freq);
+ }
+
+ const float this_pwidth = pulsewidth[s * plugin->pulsewidth_is_cv];
+ if (this_pwidth != last_pwidth) {
+ /* Pulsewidth changed, recalculate */
+ last_pwidth = this_pwidth;
+ pwidth = f_clip(this_pwidth, 0.0f, 1.0f);
+ dc_shift = 1.0f - (2.0f * pwidth);
+ phase_shift = pwidth * wdat->sample_rate;
+ }
+
+ /* Get samples from sawtooth and phase shifted inverted sawtooth,
+ with approriate DC offset */
+ output[s] = wavedata_get_sample(wdat, phase)
+ - wavedata_get_sample(wdat, phase + phase_shift)
+ + dc_shift;
+
+ /* Update phase, wrapping if necessary */
+ phase += wdat->frequency;
+ if (phase < 0.0f) {
+ phase += wdat->sample_rate;
+ } else if (phase > wdat->sample_rate) {
+ phase -= wdat->sample_rate;
+ }
+ }
+ plugin->phase = phase;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/pulse",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/quantiser.c b/src/quantiser.c
new file mode 100644
index 0000000..ed3ae1d
--- /dev/null
+++ b/src/quantiser.c
@@ -0,0 +1,461 @@
+/*
+ An LV2 plugin to quantise an input to a set of fixed values.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "math_func.h"
+#include "common.h"
+
+#define QUANTISER_RANGE_MIN 0
+#define QUANTISER_RANGE_MAX 1
+#define QUANTISER_MATCH_RANGE 2
+#define QUANTISER_MODE 3
+#define QUANTISER_COUNT 4
+#define QUANTISER_VALUE_START 5
+#define QUANTISER_INPUT (QUANTISER_MAX_INPUTS + 5)
+#define QUANTISER_OUTPUT (QUANTISER_MAX_INPUTS + 6)
+#define QUANTISER_OUTPUT_CHANGED (QUANTISER_MAX_INPUTS + 7)
+
+typedef struct {
+ const float* min;
+ const float* max;
+ const float* match_range;
+ const float* mode;
+ const float* count;
+ const float* values[QUANTISER_MAX_INPUTS];
+ const float* input;
+ float* output_changed;
+ float* output;
+ float svalues[QUANTISER_MAX_INPUTS + 2];
+ float temp[QUANTISER_MAX_INPUTS + 2];
+ float last_found;
+} Quantiser;
+
+/*
+ * f <= m <= l
+*/
+static inline void
+merge(float* v,
+ int f,
+ int m,
+ int l,
+ float* temp)
+{
+ int f1 = f;
+ int l1 = m;
+ int f2 = m + 1;
+ int l2 = l;
+ int i = f1;
+
+ while ((f1 <= l1) && (f2 <= l2)) {
+ if (v[f1] < v[f2]) {
+ temp[i] = v[f1];
+ f1++;
+ } else {
+ temp[i] = v[f2];
+ f2++;
+ }
+ i++;
+ }
+ while (f1 <= l1) {
+ temp[i] = v[f1];
+ f1++;
+ i++;
+ }
+ while (f2 <= l2) {
+ temp[i] = v[f2];
+ f2++;
+ i++;
+ }
+ for (i = f; i <= l; i++) {
+ v[i] = temp[i];
+ }
+}
+
+/*
+ * Recursive Merge Sort
+ * Sort elements in unsorted vector v
+*/
+static inline void
+msort(float* v,
+ int f,
+ int l,
+ float* temp)
+{
+ int m;
+
+ if (f < l) {
+ m = (f + l) / 2;
+ msort(v, f, m, temp);
+ msort(v, m + 1, l, temp);
+ merge(v, f, m, l, temp);
+ }
+}
+
+/*
+ * Binary search for nearest match to sought value in
+ * ordered vector v of given size
+*/
+static inline int
+fuzzy_bsearch(float* v,
+ int size,
+ float sought)
+{
+ int f = 0;
+ int l = size - 1;
+ int m = ((l - f) / 2);
+
+ while ((l - f) > 1) {
+ if (v[m] < sought) {
+ f = (l - f) / 2 + f;
+ } else {
+ l = (l - f) / 2 + f;
+ }
+
+ m = ((l - f) / 2 + f);
+ }
+
+ if (sought < v[m]) {
+ if (m > 0) {
+ if (FABSF(v[m] - sought) > FABSF(v[m - 1] - sought)) {
+ m--;
+ }
+ }
+ } else if (m < size - 1) {
+ if (FABSF(v[m] - sought) > FABSF(v[m + 1] - sought)) {
+ m++;
+ }
+ }
+
+ return m;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Quantiser* plugin = (Quantiser*)instance;
+
+ plugin->last_found = 0.0f;
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Quantiser* plugin = (Quantiser*)instance;
+
+ switch (port) {
+ case QUANTISER_RANGE_MIN:
+ plugin->min = (const float*)data;
+ break;
+ case QUANTISER_RANGE_MAX:
+ plugin->max = (const float*)data;
+ break;
+ case QUANTISER_MATCH_RANGE:
+ plugin->match_range = (const float*)data;
+ break;
+ case QUANTISER_MODE:
+ plugin->mode = (const float*)data;
+ break;
+ case QUANTISER_COUNT:
+ plugin->count = (const float*)data;
+ break;
+ case QUANTISER_INPUT:
+ plugin->input = (const float*)data;
+ break;
+ case QUANTISER_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ case QUANTISER_OUTPUT_CHANGED:
+ plugin->output_changed = (float*)data;
+ break;
+ default:
+ if (port >= QUANTISER_VALUE_START && port < QUANTISER_OUTPUT) {
+ plugin->values[port - QUANTISER_VALUE_START] = (float*)data;
+ }
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Quantiser* plugin = (Quantiser*)malloc(sizeof(Quantiser));
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Quantiser* plugin = (Quantiser*)instance;
+
+ /* Range Min (float value) */
+ float min = *(plugin->min);
+
+ /* Range Max (float value) */
+ float max = *(plugin->max);
+
+ /* Match Range (float value) */
+ const float match_range = FABSF(*(plugin->match_range));
+
+ /* Mode (float value) */
+ const float mode = *(plugin->mode);
+
+ /* Count (float value) */
+ const float count = *(plugin->count);
+
+ /* Input (array of float of length sample_count) */
+ const float* input = plugin->input;
+
+ /* Output (array of float of length sample_count) */
+ float* output = plugin->output;
+
+ /* Output Changed (array of float of length sample_count) */
+ float* output_changed = plugin->output_changed;
+
+ /* Instance Data */
+ float* temp = plugin->temp;
+ float* values = plugin->svalues;
+ float last_found = plugin->last_found;
+
+ int md = LRINTF(mode);
+ int n = LRINTF(count);
+ int i;
+ float in;
+ float out_changed;
+ float range;
+ float offset;
+ float found = last_found;
+ int found_index = 0;
+
+ /* Clip count if out of range */
+ n = n < 1 ? 1 : (n > QUANTISER_MAX_INPUTS ? QUANTISER_MAX_INPUTS : n);
+
+ /* Swap min and max if wrong way around */
+ if (min > max) {
+ range = min;
+ min = max;
+ max = range;
+ }
+ range = max - min;
+
+ /* Copy and sort required values */
+ for (i = 0; i < n; i++) {
+ values[i + 1] = *(plugin->values[i]);
+ }
+
+ msort(values, 1, n, temp);
+
+ /* Add wrapped extremes */
+ values[0] = values[n] - range;
+ values[n + 1] = values[1] + range;
+
+ if (md < 1) {
+ /* Extend mode */
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ in = input[s];
+
+ if (range > 0.0f) {
+ if ((in < min) || (in > max)) {
+ offset = FLOORF((in - max) / range) + 1.0f;
+ offset *= range;
+ in -= offset;
+
+ /* Quantise */
+ found_index = fuzzy_bsearch(values, n + 2, in);
+
+ /* Wrapped */
+ if (found_index == 0) {
+ found_index = n;
+ offset -= range;
+ } else if (found_index == n + 1) {
+ found_index = 1;
+ offset += range;
+ }
+
+ found = values[found_index];
+
+ /* Allow near misses */
+ if (match_range > 0.0f) {
+ if (in < (found - match_range)) {
+ found -= match_range;
+ } else if (in > (found + match_range)) {
+ found += match_range;
+ }
+ }
+ found += offset;
+ } else {
+ /* Quantise */
+ found_index = fuzzy_bsearch(values, n + 2, in);
+ if (found_index == 0) {
+ found_index = n;
+ found = values[n] - range;
+ } else if (found_index == n + 1) {
+ found_index = 1;
+ found = values[1] + range;
+ } else {
+ found = values[found_index];
+ }
+
+ if (match_range > 0.0f) {
+ if (in < (found - match_range)) {
+ found -= match_range;
+ } else if (in > (found + match_range)) {
+ found += match_range;
+ }
+ }
+ }
+ } else {
+ /* Min and max the same, so only one value to quantise to */
+ found = min;
+ }
+
+ /* Has quantised output changed? */
+ if (FABSF(found - last_found) > 2.0001f * match_range) {
+ out_changed = 1.0f;
+ last_found = found;
+ } else {
+ out_changed = 0.0f;
+ }
+
+ output[s] = found;
+ output_changed[s] = out_changed;
+ }
+ } else if (md == 1) {
+ /* Wrap mode */
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ in = input[s];
+
+ if (range > 0.0f) {
+ if ((in < min) || (in > max)) {
+ in -= (FLOORF((in - max) / range) + 1.0f) * range;
+ }
+
+ /* Quantise */
+ found_index = fuzzy_bsearch(values, n + 2, in);
+ if (found_index == 0) {
+ found_index = n;
+ } else if (found_index == n + 1) {
+ found_index = 1;
+ }
+
+ found = values[found_index];
+
+ /* Allow near misses */
+ if (match_range > 0.0f) {
+ if (in < (found - match_range)) {
+ found -= match_range;
+ } else if (in > (found + match_range)) {
+ found += match_range;
+ }
+ }
+ } else {
+ /* Min and max the same, so only one value to quantise to */
+ found = min;
+ }
+
+ /* Has quantised output changed? */
+ if (FABSF(found - last_found) > match_range) {
+ out_changed = 1.0f;
+ last_found = found;
+ } else {
+ out_changed = 0.0f;
+ }
+
+ output[s] = found;
+ output_changed[s] = out_changed;
+ }
+ } else {
+ /* Clip mode */
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ in = input[s];
+
+ if (range > 0.0f) {
+ /* Clip to range */
+ if (in < min) {
+ found_index = 1;
+ } else if (in > max) {
+ found_index = n;
+ } else {
+ /* Quantise */
+ found_index = fuzzy_bsearch(values + 1, n, in) + 1;
+ }
+
+ found = values[found_index];
+
+ /* Allow near misses */
+ if (match_range > 0.0f) {
+ if (in < (found - match_range)) {
+ found -= match_range;
+ } else if (in > (found + match_range)) {
+ found += match_range;
+ }
+ }
+ } else {
+ /* Min and max the same, so only one value to quantise to */
+ found = min;
+ }
+
+ /* Has quantised output changed? */
+ if (FABSF(found - last_found) > match_range) {
+ out_changed = 1.0f;
+ last_found = found;
+ } else {
+ out_changed = 0.0f;
+ }
+
+ output[s] = found;
+ output_changed[s] = out_changed;
+ }
+ }
+ plugin->last_found = last_found;
+}
+
+static const LV2_Descriptor descriptor = {
+ QUANTISER_URI,
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/random.c b/src/random.c
new file mode 100644
index 0000000..45d8de8
--- /dev/null
+++ b/src/random.c
@@ -0,0 +1,237 @@
+/*
+ An LV2 plugin to generate a random wave of varying frequency and smoothness.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include <time.h>
+#include "math_func.h"
+#include "common.h"
+#include "uris.h"
+
+#define RANDOM_FREQUENCY 0
+#define RANDOM_SMOOTH 1
+#define RANDOM_OUTPUT 2
+
+typedef struct {
+ const float* frequency;
+ const float* smooth;
+ float* output;
+ float nyquist;
+ float inv_nyquist;
+ float phase;
+ float value1;
+ float value2;
+ uint32_t frequency_is_cv;
+ uint32_t smooth_is_cv;
+ URIs uris;
+} Random;
+
+float inv_rand_max;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Random* plugin = (Random*)instance;
+
+ switch (port) {
+ case RANDOM_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case RANDOM_SMOOTH:
+ plugin->smooth = (const float*)data;
+ break;
+ case RANDOM_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Random* plugin = (Random*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case RANDOM_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case RANDOM_SMOOTH:
+ plugin->smooth_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Random* plugin = (Random*)malloc(sizeof(Random));
+ if (!plugin) {
+ return NULL;
+ }
+
+ srand((int)time((time_t*)0));
+
+ inv_rand_max = 2.0f / (float)RAND_MAX;
+
+ plugin->nyquist = (float)sample_rate / 2.0f;
+ plugin->inv_nyquist = 1.0f / plugin->nyquist;
+
+ plugin->value1 = rand() * inv_rand_max - 1.0f;
+ plugin->value2 = rand() * inv_rand_max - 1.0f;
+
+ plugin->frequency_is_cv = 0;
+ plugin->smooth_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Random* plugin = (Random*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Random* plugin = (Random*)instance;
+
+ /* Frequency (Hz) (array of floats of length 1 or sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Wave smoothness (array of floats of length 1 or sample_count) */
+ const float* smooth = plugin->smooth;
+
+ /* Output (array of floats of length sample_count) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ float nyquist = plugin->nyquist;
+ float inv_nyquist = plugin->inv_nyquist;
+ float phase = plugin->phase;
+ float value1 = plugin->value1;
+ float value2 = plugin->value2;
+
+ float result;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float freq = f_clip(frequency[s * plugin->frequency_is_cv],
+ 0.0f, nyquist);
+
+ const float smth = f_clip(smooth[s * plugin->smooth_is_cv],
+ 0.0f, 1.0f);
+
+ const float interval = (1.0f - smth) * 0.5f;
+
+ if (phase < interval) {
+ result = 1.0f;
+ } else if (phase > (1.0f - interval)) {
+ result = -1.0f;
+ } else if (interval > 0.0f) {
+ result = COSF((phase - interval) / smth * M_PI);
+ } else {
+ result = COSF(phase * M_PI);
+ }
+
+ result *= (value2 - value1) * 0.5f;
+ result -= (value2 + value1) * 0.5f;
+
+ output[s] = result;
+
+ phase += freq * inv_nyquist;
+ if (phase > 1.0f) {
+ phase -= 1.0f;
+ value1 = value2;
+ value2 = (float)rand() * inv_rand_max - 1.0f;
+ }
+ }
+
+ plugin->phase = phase;
+ plugin->value1 = value1;
+ plugin->value2 = value2;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/random",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/ratio.c b/src/ratio.c
new file mode 100644
index 0000000..30873c2
--- /dev/null
+++ b/src/ratio.c
@@ -0,0 +1,202 @@
+/*
+ An LV2 plugin to calculate the ratio of two signals.
+ Copyright 2011 David Robillard
+ Copyright 2004 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "math_func.h"
+#include "common.h"
+#include "uris.h"
+
+#define RATIO_NUMERATOR 0
+#define RATIO_DENOMINATOR 1
+#define RATIO_OUTPUT 2
+
+typedef struct {
+ const float* numerator;
+ const float* denominator;
+ float* output;
+ uint32_t numerator_is_cv;
+ uint32_t denominator_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
+} Ratio;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Ratio* plugin = (Ratio*)instance;
+
+ switch (port) {
+ case RATIO_NUMERATOR:
+ plugin->numerator = (const float*)data;
+ break;
+ case RATIO_DENOMINATOR:
+ plugin->denominator = (const float*)data;
+ break;
+ case RATIO_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Ratio* plugin = (Ratio*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case RATIO_NUMERATOR:
+ plugin->numerator_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case RATIO_DENOMINATOR:
+ plugin->denominator_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ plugin->output_is_cv = plugin->numerator_is_cv || plugin->denominator_is_cv;
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Ratio* plugin = (const Ratio*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT || o->subject != RATIO_OUTPUT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = (plugin->output_is_cv
+ ? &plugin->uris.lv2_CVPort
+ : &plugin->uris.lv2_ControlPort);
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Ratio* plugin = (Ratio*)malloc(sizeof(Ratio));
+
+ if (plugin) {
+ plugin->numerator_is_cv = 0;
+ plugin->denominator_is_cv = 0;
+ plugin->output_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Ratio* plugin = (Ratio*)instance;
+
+ /* Numerator (array of floats of length sample_count) */
+ const float* numerator = plugin->numerator;
+
+ /* Denominator (array of floats of length sample_count) */
+ const float* denominator = plugin->denominator;
+
+ /* Output (array of floats of length sample_count) */
+ float* output = plugin->output;
+
+ if (!plugin->output_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
+ }
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float n = numerator[s * plugin->numerator_is_cv];
+ float d = denominator[s * plugin->denominator_is_cv];
+
+ d = COPYSIGNF(f_max(FABSF(d), 1e-16f), d);
+
+ output[s] = n / d;
+ }
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/ratio",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/sawtooth.c b/src/sawtooth.c
new file mode 100644
index 0000000..31c9057
--- /dev/null
+++ b/src/sawtooth.c
@@ -0,0 +1,194 @@
+/*
+ An LV2 plugin to generate a bandlimited sawtooth waveform.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "wavedata.h"
+
+#define SAWTOOTH_FREQUENCY 0
+#define SAWTOOTH_OUTPUT 1
+
+typedef struct {
+ const float* frequency;
+ float* output;
+ float phase;
+ uint32_t frequency_is_cv;
+ Wavedata wdat;
+ URIs uris;
+} Sawtooth;
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Sawtooth* plugin = (Sawtooth*)instance;
+
+ switch (port) {
+ case SAWTOOTH_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case SAWTOOTH_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Sawtooth* plugin = (Sawtooth*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case SAWTOOTH_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Sawtooth* plugin = (Sawtooth*)malloc(sizeof(Sawtooth));
+ if (!plugin) {
+ return NULL;
+ }
+
+ if (wavedata_load(&plugin->wdat, bundle_path, "sawtooth_data",
+ BLOP_DLSYM_SAWTOOTH, sample_rate)) {
+ free(plugin);
+ return 0;
+ }
+
+ plugin->frequency_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ Sawtooth* plugin = (Sawtooth*)instance;
+
+ wavedata_unload(&plugin->wdat);
+ free(instance);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Sawtooth* plugin = (Sawtooth*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Sawtooth* plugin = (Sawtooth*)instance;
+
+ /* Frequency (array of float of length 1 or sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ Wavedata* wdat = &plugin->wdat;
+ float phase = plugin->phase;
+
+ for (uint32_t s = 0; s < sample_count; s++) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ if (freq != wdat->frequency) {
+ /* Frequency changed, look up table to play */
+ wavedata_get_table(wdat, freq);
+ }
+
+ output[s] = wavedata_get_sample(wdat, phase);
+
+ /* Update phase, wrapping if necessary */
+ phase += wdat->frequency;
+ if (phase < 0.0f) {
+ phase += wdat->sample_rate;
+ } else if (phase > wdat->sample_rate) {
+ phase -= wdat->sample_rate;
+ }
+ }
+ plugin->phase = phase;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/sawtooth",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/sequencer.c b/src/sequencer.c
new file mode 100644
index 0000000..939401b
--- /dev/null
+++ b/src/sequencer.c
@@ -0,0 +1,216 @@
+/*
+ An LV2 plugin to simulate an analogue style step sequencer.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "math_func.h"
+#include "common.h"
+
+#define SEQUENCER_GATE 0
+#define SEQUENCER_TRIGGER 1
+#define SEQUENCER_LOOP_POINT 2
+#define SEQUENCER_RESET 3
+#define SEQUENCER_VALUE_GATE_CLOSED 4
+#define SEQUENCER_VALUE_START 5
+#define SEQUENCER_OUTPUT (SEQUENCER_MAX_INPUTS + 5)
+
+typedef struct {
+ const float* gate;
+ const float* trigger;
+ const float* loop_steps;
+ const float* reset;
+ const float* value_gate_closed;
+ const float* values[SEQUENCER_MAX_INPUTS];
+ float* output;
+ float srate;
+ float inv_srate;
+ float last_gate;
+ float last_trigger;
+ float last_value;
+ unsigned int step_index;
+} Sequencer;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Sequencer* plugin = (Sequencer*)instance;
+
+ switch (port) {
+ case SEQUENCER_GATE:
+ plugin->gate = (const float*)data;
+ break;
+ case SEQUENCER_TRIGGER:
+ plugin->trigger = (const float*)data;
+ break;
+ case SEQUENCER_LOOP_POINT:
+ plugin->loop_steps = (const float*)data;
+ break;
+ case SEQUENCER_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ case SEQUENCER_RESET:
+ plugin->reset = (const float*)data;
+ break;
+ case SEQUENCER_VALUE_GATE_CLOSED:
+ plugin->value_gate_closed = (const float*)data;
+ break;
+ default:
+ if (port >= SEQUENCER_VALUE_START && port < SEQUENCER_OUTPUT) {
+ plugin->values[port - SEQUENCER_VALUE_START] = (const float*)data;
+ }
+ break;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Sequencer* plugin = (Sequencer*)malloc(sizeof(Sequencer));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->srate = (float)sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Sequencer* plugin = (Sequencer*)instance;
+
+ plugin->last_gate = 0.0f;
+ plugin->last_trigger = 0.0f;
+ plugin->last_value = 0.0f;
+ plugin->step_index = 0;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Sequencer* plugin = (Sequencer*)instance;
+
+ /* Gate */
+ const float* gate = plugin->gate;
+
+ /* Step Trigger */
+ const float* trigger = plugin->trigger;
+
+ /* Loop Steps */
+ const float loop_steps = *(plugin->loop_steps);
+
+ /* Reset to Value on Gate Close */
+ const float reset = *(plugin->reset);
+
+ /* Value used when gate closed */
+ float value_gate_closed = *(plugin->value_gate_closed);
+
+ /* Step Values */
+ float values[SEQUENCER_MAX_INPUTS];
+
+ /* Output */
+ float* output = plugin->output;
+
+ float last_gate = plugin->last_gate;
+ float last_trigger = plugin->last_trigger;
+ float last_value = plugin->last_value;
+
+ unsigned int step_index = plugin->step_index;
+ unsigned int loop_index = LRINTF(loop_steps);
+ int rst = reset > 0.0f;
+ int i;
+
+ loop_index = loop_index == 0 ? 1 : loop_index;
+ loop_index = (loop_index > SEQUENCER_MAX_INPUTS)
+ ? SEQUENCER_MAX_INPUTS
+ : loop_index;
+
+ for (i = 0; i < SEQUENCER_MAX_INPUTS; i++) {
+ values[i] = *(plugin->values[i]);
+ }
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ if (gate[s] > 0.0f) {
+ if (trigger[s] > 0.0f && !(last_trigger > 0.0f)) {
+ if (last_gate > 0.0f) {
+ step_index++;
+ if (step_index >= loop_index) {
+ step_index = 0;
+ }
+ } else {
+ step_index = 0;
+ }
+ }
+
+ output[s] = values[step_index];
+
+ last_value = values[step_index];
+ } else {
+ if (rst) {
+ output[s] = value_gate_closed;
+ } else {
+ output[s] = last_value;
+ }
+
+ step_index = 0;
+ }
+ last_gate = gate[s];
+ last_trigger = trigger[s];
+ }
+
+ plugin->last_gate = last_gate;
+ plugin->last_trigger = last_trigger;
+ plugin->last_value = last_value;
+ plugin->step_index = step_index;
+}
+
+static const LV2_Descriptor descriptor = {
+ SEQUENCER_URI,
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/square.c b/src/square.c
new file mode 100644
index 0000000..0136124
--- /dev/null
+++ b/src/square.c
@@ -0,0 +1,195 @@
+/*
+ An LV2 plugin to generate a bandlimited square waveform.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "wavedata.h"
+
+#define SQUARE_FREQUENCY 0
+#define SQUARE_OUTPUT 1
+
+typedef struct {
+ const float* frequency;
+ float* output;
+ float phase;
+ uint32_t frequency_is_cv;
+ Wavedata wdat;
+ URIs uris;
+} Square;
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Square* plugin = (Square*)instance;
+
+ switch (port) {
+ case SQUARE_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case SQUARE_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Square* plugin = (Square*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case SQUARE_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Square* plugin = (Square*)malloc(sizeof(Square));
+ if (!plugin) {
+ return NULL;
+ }
+
+ if (wavedata_load(&plugin->wdat, bundle_path, "square_data",
+ BLOP_DLSYM_SQUARE, sample_rate)) {
+ free(plugin);
+ return NULL;
+ }
+
+ plugin->frequency_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ Square* plugin = (Square*)instance;
+
+ wavedata_unload(&plugin->wdat);
+ free(instance);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Square* plugin = (Square*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Square* plugin = (Square*)instance;
+
+ /* Frequency (array of float of length sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ Wavedata* wdat = &plugin->wdat;
+ float phase = plugin->phase;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ if (freq != wdat->frequency) {
+ /* Frequency changed, look up table to play */
+ wavedata_get_table(wdat, freq);
+ }
+
+ /* Get interpolated sample */
+ output[s] = wavedata_get_sample(wdat, phase);
+
+ /* Update phase, wrapping if necessary */
+ phase += wdat->frequency;
+ if (phase < 0.0f) {
+ phase += wdat->sample_rate;
+ } else if (phase > wdat->sample_rate) {
+ phase -= wdat->sample_rate;
+ }
+ }
+ plugin->phase = phase;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/square",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/sum.c b/src/sum.c
new file mode 100644
index 0000000..3023733
--- /dev/null
+++ b/src/sum.c
@@ -0,0 +1,185 @@
+/*
+ An LV2 plugin to calculate the sum of two signals.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "vector_op.h"
+
+#define SUM_INPUT1 0
+#define SUM_INPUT2 1
+#define SUM_OUTPUT 2
+
+typedef struct {
+ const float* input1;
+ const float* input2;
+ float* output;
+ uint32_t input1_is_cv;
+ uint32_t input2_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
+} Sum;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Sum* plugin = (Sum*)instance;
+
+ switch (port) {
+ case SUM_INPUT1:
+ plugin->input1 = (const float*)data;
+ break;
+ case SUM_INPUT2:
+ plugin->input2 = (const float*)data;
+ break;
+ case SUM_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Sum* plugin = (Sum*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case SUM_INPUT1:
+ plugin->input1_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case SUM_INPUT2:
+ plugin->input2_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ plugin->output_is_cv = plugin->input1_is_cv || plugin->input2_is_cv;
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Sum* plugin = (const Sum*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT || o->subject != SUM_OUTPUT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = (plugin->output_is_cv
+ ? &plugin->uris.lv2_CVPort
+ : &plugin->uris.lv2_ControlPort);
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Sum* plugin = (Sum*)malloc(sizeof(Sum));
+
+ if (plugin) {
+ plugin->input1_is_cv = 0;
+ plugin->input2_is_cv = 0;
+ plugin->output_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ const Sum* const plugin = (Sum*)instance;
+ const float* const input1 = plugin->input1;
+ const float* const input2 = plugin->input2;
+ float* const output = plugin->output;
+
+ VECTOR_OP(+, output,
+ input1, plugin->input1_is_cv,
+ input2, plugin->input2_is_cv);
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/sum",
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/sync_pulse.c b/src/sync_pulse.c
new file mode 100644
index 0000000..0f24c80
--- /dev/null
+++ b/src/sync_pulse.c
@@ -0,0 +1,213 @@
+/*
+ An LV2 plugin to generate a non-bandlimited variable-pulse waveform with gate
+ for trigger and sync.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "common.h"
+
+#define SYNCPULSE_FREQUENCY 0
+#define SYNCPULSE_PULSEWIDTH 1
+#define SYNCPULSE_GATE 2
+#define SYNCPULSE_OUTPUT 3
+
+typedef struct {
+ const float* frequency;
+ const float* pulsewidth;
+ const float* gate;
+ float* output;
+ float srate;
+ float phase;
+ uint32_t frequency_is_cv;
+ uint32_t pulsewidth_is_cv;
+ URIs uris;
+} SyncPulse;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ SyncPulse* plugin = (SyncPulse*)instance;
+
+ switch (port) {
+ case SYNCPULSE_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case SYNCPULSE_PULSEWIDTH:
+ plugin->pulsewidth = (const float*)data;
+ break;
+ case SYNCPULSE_GATE:
+ plugin->gate = (const float*)data;
+ break;
+ case SYNCPULSE_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ SyncPulse* plugin = (SyncPulse*)malloc(sizeof(SyncPulse));
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case SYNCPULSE_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case SYNCPULSE_PULSEWIDTH:
+ plugin->pulsewidth_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ SyncPulse* plugin = (SyncPulse*)malloc(sizeof(SyncPulse));
+
+ if (plugin) {
+ plugin->srate = (float)sample_rate;
+ plugin->frequency_is_cv = 0;
+ plugin->pulsewidth_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ }
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ SyncPulse* plugin = (SyncPulse*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ SyncPulse* plugin = (SyncPulse*)instance;
+
+ /* Frequency (array of float of length sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Pulse Width (array of float of length sample_count) */
+ const float* pulsewidth = plugin->pulsewidth;
+
+ /* Gate (array of float of length sample_count) */
+ const float* gate = plugin->gate;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ float phase = plugin->phase;
+ float srate = plugin->srate;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ if (gate[s] > 0.0f) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ const float pw = pulsewidth[s * plugin->pulsewidth_is_cv];
+ const float pwidth = f_clip(pw, 0.0f, 1.0f) * srate;
+
+ if (phase < pwidth) {
+ output[s] = 1.0f;
+ } else {
+ output[s] = -1.0f;
+ }
+
+ phase += freq;
+ if (phase < 0.0f) {
+ phase += srate;
+ } else if (phase > srate) {
+ phase -= srate;
+ }
+ } else {
+ output[s] = 0.0f;
+ phase = 0.0f;
+ }
+ }
+
+ plugin->phase = phase;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/sync_pulse",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/sync_square.c b/src/sync_square.c
new file mode 100644
index 0000000..38fdaf5
--- /dev/null
+++ b/src/sync_square.c
@@ -0,0 +1,201 @@
+/*
+ An LV2 plugin to generate a non-bandlimited square waveform with gate for
+ trigger and sync.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+
+#define SYNCSQUARE_FREQUENCY 0
+#define SYNCSQUARE_GATE 1
+#define SYNCSQUARE_OUTPUT 2
+
+typedef struct {
+ const float* frequency;
+ const float* gate;
+ float* output;
+ float srate;
+ float nyquist;
+ float phase;
+ uint32_t frequency_is_cv;
+ URIs uris;
+} SyncSquare;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ SyncSquare* plugin = (SyncSquare*)instance;
+
+ switch (port) {
+ case SYNCSQUARE_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case SYNCSQUARE_GATE:
+ plugin->gate = (const float*)data;
+ break;
+ case SYNCSQUARE_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ SyncSquare* plugin = (SyncSquare*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case SYNCSQUARE_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ SyncSquare* plugin = (SyncSquare*)malloc(sizeof(SyncSquare));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->srate = (float)sample_rate;
+ plugin->nyquist = (float)(sample_rate / 2.0f);
+ plugin->frequency_is_cv = 0;
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ SyncSquare* plugin = (SyncSquare*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ SyncSquare* plugin = (SyncSquare*)instance;
+
+ /* Frequency (array of float of length 1 or sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Gate (array of float of length sample_count) */
+ const float* gate = plugin->gate;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ float phase = plugin->phase;
+ float srate = plugin->srate;
+ float nyquist = plugin->nyquist;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ if (gate[s] > 0.0f) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+
+ if (phase < nyquist) {
+ output[s] = 1.0f;
+ } else {
+ output[s] = -1.0f;
+ }
+
+ phase += freq;
+ if (phase < 0.0f) {
+ phase += srate;
+ } else if (phase > srate) {
+ phase -= srate;
+ }
+ } else {
+ output[s] = 0.0f;
+ phase = 0.0f;
+ }
+ }
+
+ plugin->phase = phase;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/sync_square",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/tracker.c b/src/tracker.c
new file mode 100644
index 0000000..dd628bc
--- /dev/null
+++ b/src/tracker.c
@@ -0,0 +1,245 @@
+/*
+ An LV2 plugin to shape a signal in various ways.
+ Copyright 2011 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "common.h"
+#include "uris.h"
+
+#define TRACKER_GATE 0
+#define TRACKER_HATTACK 1
+#define TRACKER_HDECAY 2
+#define TRACKER_LATTACK 3
+#define TRACKER_LDECAY 4
+#define TRACKER_INPUT 5
+#define TRACKER_OUTPUT 6
+
+typedef struct {
+ const float* gate;
+ const float* hattack;
+ const float* hdecay;
+ const float* lattack;
+ const float* ldecay;
+ const float* input;
+ float* output;
+ float coeff;
+ float last_value;
+ uint32_t hattack_is_cv;
+ uint32_t hdecay_is_cv;
+ uint32_t lattack_is_cv;
+ uint32_t ldecay_is_cv;
+ URIs uris;
+} Tracker;
+
+static void
+cleanup(LV2_Handle instance)
+{
+ free(instance);
+}
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Tracker* plugin = (Tracker*)instance;
+
+ switch (port) {
+ case TRACKER_GATE:
+ plugin->gate = (const float*)data;
+ break;
+ case TRACKER_HATTACK:
+ plugin->hattack = (const float*)data;
+ break;
+ case TRACKER_HDECAY:
+ plugin->hdecay = (const float*)data;
+ break;
+ case TRACKER_LATTACK:
+ plugin->lattack = (const float*)data;
+ break;
+ case TRACKER_LDECAY:
+ plugin->ldecay = (const float*)data;
+ break;
+ case TRACKER_INPUT:
+ plugin->input = (const float*)data;
+ break;
+ case TRACKER_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Tracker* plugin = (Tracker*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case TRACKER_HATTACK:
+ plugin->hattack_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case TRACKER_HDECAY:
+ plugin->hdecay_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case TRACKER_LATTACK:
+ plugin->lattack_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case TRACKER_LDECAY:
+ plugin->ldecay_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Tracker* plugin = (Tracker*)malloc(sizeof(Tracker));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->coeff = 2.0f * M_PI / (float)sample_rate;
+
+ plugin->hattack_is_cv = 0;
+ plugin->hdecay_is_cv = 0;
+ plugin->lattack_is_cv = 0;
+ plugin->ldecay_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Tracker* plugin = (Tracker*)instance;
+
+ plugin->last_value = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Tracker* plugin = (Tracker*)instance;
+
+ /* Gate (array of floats of length sample_count) */
+ const float* gate = plugin->gate;
+
+ /* Gate High Attack Rate (array of floats of length 1 or sample_count) */
+ const float* hattack = plugin->hattack;
+
+ /* Gate High Decay Rate (array of floats of length 1 or sample_count) */
+ const float* hdecay = plugin->hdecay;
+
+ /* Gate Low Attack Rate (array of floats of length 1 or sample_count) */
+ const float* lattack = plugin->lattack;
+
+ /* Gate Low Decay Rate (array of floats of length 1 or sample_count) */
+ const float* ldecay = plugin->ldecay;
+
+ /* Input (array of floats of length sample_count) */
+ const float* input = plugin->input;
+
+ /* Output (array of floats of length sample_count) */
+ float* output = plugin->output;
+
+ /* Instance Data */
+ float coeff = plugin->coeff;
+ float last_value = plugin->last_value;
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float in = input[s];
+ const float ha = hattack[s * plugin->hattack_is_cv];
+ const float hd = hdecay[s * plugin->hdecay_is_cv];
+ const float la = lattack[s * plugin->lattack_is_cv];
+ const float ld = ldecay[s * plugin->ldecay_is_cv];
+
+ float rate;
+ if (gate[s] > 0.0f) {
+ rate = in > last_value ? ha : hd;
+ } else {
+ rate = in > last_value ? la : ld;
+ }
+
+ rate = f_min(1.0f, rate * coeff);
+ last_value = last_value * (1.0f - rate) + in * rate;
+
+ output[s] = last_value;
+ }
+
+ plugin->last_value = last_value;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/tracker",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/triangle.c b/src/triangle.c
new file mode 100644
index 0000000..09c01c2
--- /dev/null
+++ b/src/triangle.c
@@ -0,0 +1,232 @@
+/*
+ An LV2 plugin to generate a bandlimited slope-variable triangle waveform.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
+#include "wavedata.h"
+
+#define TRIANGLE_FREQUENCY 0
+#define TRIANGLE_SLOPE 1
+#define TRIANGLE_OUTPUT 2
+
+typedef struct {
+ const float* frequency;
+ const float* slope;
+ float* output;
+ float phase;
+ float min_slope;
+ float max_slope;
+ uint32_t frequency_is_cv;
+ uint32_t slope_is_cv;
+ Wavedata wdat;
+ URIs uris;
+} Triangle;
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ Triangle* plugin = (Triangle*)instance;
+
+ switch (port) {
+ case TRIANGLE_FREQUENCY:
+ plugin->frequency = (const float*)data;
+ break;
+ case TRIANGLE_SLOPE:
+ plugin->slope = (const float*)data;
+ break;
+ case TRIANGLE_OUTPUT:
+ plugin->output = (float*)data;
+ break;
+ }
+}
+
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Triangle* plugin = (Triangle*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_ControlPort &&
+ port_type != plugin->uris.lv2_CVPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+
+ switch (o->subject) {
+ case TRIANGLE_FREQUENCY:
+ plugin->frequency_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ case TRIANGLE_SLOPE:
+ plugin->slope_is_cv = (port_type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Triangle* plugin = (Triangle*)malloc(sizeof(Triangle));
+ if (!plugin) {
+ return NULL;
+ }
+
+ if (wavedata_load(&plugin->wdat, bundle_path, "parabola_data",
+ BLOP_DLSYM_PARABOLA, sample_rate)) {
+ free(plugin);
+ return 0;
+ }
+
+ plugin->min_slope = 2.0f / plugin->wdat.sample_rate;
+ plugin->max_slope = 1.0f - plugin->min_slope;
+
+ plugin->frequency_is_cv = 0;
+ plugin->slope_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
+ return (LV2_Handle)plugin;
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ Triangle* plugin = (Triangle*)instance;
+
+ wavedata_unload(&plugin->wdat);
+ free(instance);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ Triangle* plugin = (Triangle*)instance;
+
+ plugin->phase = 0.0f;
+}
+
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Triangle* plugin = (Triangle*)instance;
+
+ /* Frequency (array of float of length 1 or sample_count) */
+ const float* frequency = plugin->frequency;
+
+ /* Slope (array of float of length 1 or sample_count) */
+ const float* slope = plugin->slope;
+
+ /* Output (pointer to float value) */
+ float* output = plugin->output;
+
+ /* Instance data */
+ Wavedata* wdat = &plugin->wdat;
+ float phase = plugin->phase;
+ const float min_slope = plugin->min_slope;
+ const float max_slope = plugin->max_slope;
+
+ float last_slope = slope[0];
+ float slp = f_clip(last_slope, min_slope, max_slope);
+ float phase_shift = slp * wdat->sample_rate;
+ float scale = 1.0f / (8.0f * (slp - (slp * slp)));
+
+ for (uint32_t s = 0; s < sample_count; ++s) {
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ if (freq != wdat->frequency) {
+ /* Frequency changed, look up table to play */
+ wavedata_get_table(wdat, freq);
+ }
+
+ const float this_slope = slope[s * plugin->slope_is_cv];
+ if (this_slope != last_slope) {
+ /* Slope changed, recalculate */
+ last_slope = this_slope;
+ slp = f_clip(this_slope, min_slope, max_slope);
+ phase_shift = slp * wdat->sample_rate;
+ scale = 1.0f / (8.0f * (slp - (slp * slp)));
+ }
+
+ /* Get samples from parabola and phase shifted inverted parabola,
+ and scale to compensate */
+ output[s] = (wavedata_get_sample(wdat, phase)
+ - wavedata_get_sample(wdat, phase + phase_shift)) * scale;
+
+ /* Update phase, wrapping if necessary */
+ phase += wdat->frequency;
+ if (phase < 0.0f) {
+ phase += wdat->sample_rate;
+ } else if (phase > wdat->sample_rate) {
+ phase -= wdat->sample_rate;
+ }
+ }
+ plugin->phase = phase;
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { NULL, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/blop/triangle",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ extension_data,
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/wavedata.c b/src/wavedata.c
new file mode 100644
index 0000000..910577f
--- /dev/null
+++ b/src/wavedata.c
@@ -0,0 +1,79 @@
+/*
+ Oscillator wave data loading.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "blop_config.h"
+#include "wavedata.h"
+
+#ifdef _WIN32
+# include <windows.h>
+# define dlopen(path, flags) LoadLibrary(path)
+# define dlclose(lib) FreeLibrary((HMODULE)lib)
+# define dlsym(lib, sym) GetProcAddress((HMODULE)lib, sym)
+# define snprintf _snprintf
+#else
+# include <dlfcn.h>
+#endif
+
+int
+wavedata_load(Wavedata* w,
+ const char* bundle_path,
+ const char* lib_name,
+ const char* wdat_descriptor_name,
+ double sample_rate)
+{
+ const size_t bundle_len = strlen(bundle_path);
+ const size_t lib_name_len = strlen(lib_name);
+ const size_t ext_len = strlen(BLOP_SHLIB_EXT);
+ const size_t path_len = bundle_len + lib_name_len + ext_len + 2;
+ int retval = -1;
+
+ char* lib_path = (char*)malloc(path_len);
+ snprintf(lib_path, path_len, "%s%s%s",
+ bundle_path, lib_name, BLOP_SHLIB_EXT);
+
+ void* handle = dlopen(lib_path, RTLD_NOW);
+ free(lib_path);
+
+ if (handle) {
+ // Avoid pedantic warnings about fetching functions with dlsym
+ typedef void (*VoidFunc)(void);
+ typedef VoidFunc (*VoidFuncGetter)(void*, const char*);
+ VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym;
+
+ typedef int (*DescFunc)(Wavedata*, unsigned long);
+ DescFunc desc_func = (DescFunc)dlfunc(handle, wdat_descriptor_name);
+ if (desc_func) {
+ retval = desc_func(w, (unsigned long)sample_rate);
+ w->data_handle = handle;
+ return retval;
+ }
+ }
+
+ return retval;
+}
+
+void
+wavedata_unload(Wavedata* w)
+{
+ dlclose(w->data_handle);
+}
diff --git a/src/wavegen.c b/src/wavegen.c
new file mode 100644
index 0000000..c722e04
--- /dev/null
+++ b/src/wavegen.c
@@ -0,0 +1,310 @@
+/*
+ A program to generate c header files containing pre-calculated wavedata.
+ Copyright 2011 David Robillard
+ Copyright 2002 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include "wdatutil.h"
+#include "wavedata.h"
+#include "common.h"
+
+static void
+usage(void)
+{
+ int i;
+
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Generate bandlimited wavedata and write as c header file\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Usage: wavegen -w <Wavename> -r <Sample Rate> -f <Note> -s <Note Step>\n");
+ fprintf(stderr, " -m <Samples> [-o <Output Filename>] [-p <Prefix>]\n");
+ fprintf(stderr, " [-g <Factor>] [-q] [-t] [-h]\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -w, --wave Name of wave to generate (case insensitive)\n");
+ fprintf(stderr, " -r, --rate Intended playback rate in Samples/Second\n");
+ fprintf(stderr, " -f, --first First MIDI note to generate table for\n");
+ fprintf(stderr, " -s, --step Number of MIDI notes to skip for next table\n");
+ fprintf(stderr, " -m, --min Minimum table size in samples\n");
+ fprintf(stderr, " -o, --output Output Filename, name of file to output\n");
+ fprintf(stderr, " If not given, output is to stdout\n");
+ fprintf(stderr, " -p, --prefix Prefix for declarations in header\n");
+ fprintf(stderr, " -g, --gibbs Compensate for Gibbs' effect\n");
+ fprintf(stderr, " -q, --quiet Surpress stderr output\n");
+ fprintf(stderr, " -t, --test Don't actually generate data\n");
+ fprintf(stderr, " -h, --help Print this text and exit\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Supported waves:\n");
+
+ for (i = 0; i < WAVE_TYPE_COUNT; i++) {
+ fprintf(stderr, " %s (%s)\n", wave_names[i], wave_descriptions[i]);
+ }
+
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Gibbs' Effect\n");
+ fprintf(stderr, " Gibbs' effect causes overshoot in waves generated from finite\n");
+ fprintf(stderr, " Fourier Series. Compensation can be applied, which will result in\n");
+ fprintf(stderr, " a waveform that sounds slightly less bright.\n");
+ fprintf(stderr, " Use the --gibbs option to set degree of compensatation, from 0.0\n");
+ fprintf(stderr, " (no compensation) to 1.0 (full compensation)\n");
+ fprintf(stderr, "\n");
+}
+
+/**
+ Create bandlimited wavedata header files for various
+ waveforms
+*/
+int
+main(int argc,
+ char** argv)
+{
+ int option_index;
+ int opt;
+ const char* options = "w:r:f:s:m:o:p:g:qth";
+ struct option long_options[] = {
+ { "wave", 1, 0, 'w' },
+ { "rate", 1, 0, 'r' },
+ { "first", 1, 0, 'f' },
+ { "step", 1, 0, 's' },
+ { "min", 1, 0, 'm' },
+ { "output", 1, 0, 'o' },
+ { "prefix", 0, 0, 'p' },
+ { "gibbs", 1, 0, 'g' },
+ { "quiet", 0, 0, 'q' },
+ { "test", 0, 0, 't' },
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+ int wavetype = -1;
+ long sample_rate = -1;
+ long first_note = -1;
+ long note_step = -1;
+ long min_table_size = -1;
+ const char* filename = NULL;
+ FILE* file;
+ const char* prefix = NULL;
+ float gibbs = 0.0f;
+ int quiet = 0;
+ int test = 0;
+
+ Wavedata* w;
+ float freq;
+ uint32_t sample_count;
+ unsigned long max_harmonic_hf;
+ unsigned long max_harmonic_lf;
+ unsigned long i;
+
+ size_t strcmplen;
+ size_t len1;
+ size_t len2;
+
+ /* Parse arguments */
+ if (argc == 1) {
+ usage();
+ exit(-1);
+ }
+
+ opterr = 0;
+ while ((opt = getopt_long(argc, argv, options, long_options, &option_index)) != -1) {
+ switch (opt) {
+ case 'w':
+ for (i = 0; i < WAVE_TYPE_COUNT; i++) {
+ len1 = strlen(optarg);
+ len2 = strlen(wave_names[i]);
+ strcmplen = len1 < len2 ? len1 : len2;
+
+ if (!strncmp(optarg, wave_names[i], strcmplen)) {
+ wavetype = i;
+ }
+ }
+ if (wavetype == -1) {
+ fprintf(stderr, "Unrecognised option for Wave: %s\n", optarg);
+ exit(-1);
+ }
+ break;
+ case 'r':
+ sample_rate = (long)atoi(optarg);
+ break;
+ case 'f':
+ first_note = (long)atoi(optarg);
+ break;
+ case 's':
+ note_step = (long)atoi(optarg);
+ break;
+ case 'm':
+ min_table_size = (long)atoi(optarg);
+ break;
+ case 'o':
+ filename = optarg;
+ break;
+ case 'p':
+ prefix = optarg;
+ break;
+ case 'g':
+ gibbs = atof(optarg);
+ break;
+ case 'q':
+ quiet = -1;
+ break;
+ case 't':
+ test = -1;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ break;
+ default:
+ usage();
+ exit(-1);
+ }
+ }
+
+ /* Check basic arguments */
+ if (wavetype == -1) {
+ if (!quiet) {
+ fprintf(stderr, "No wavetype specified.\n");
+ }
+ exit(-1);
+ }
+
+ if (sample_rate == -1) {
+ if (!quiet) {
+ fprintf(stderr, "No sample rate specified.\n");
+ }
+ exit(-1);
+ }
+
+ if (first_note == -1) {
+ if (!quiet) {
+ fprintf(stderr, "No first note specified.\n");
+ }
+ exit(-1);
+ }
+
+ if (note_step == -1) {
+ if (!quiet) {
+ fprintf(stderr, "No note step specified.\n");
+ }
+ exit(-1);
+ }
+
+ if (min_table_size == -1) {
+ if (!quiet) {
+ fprintf(stderr, "No minimum table size specified.\n");
+ }
+ exit(-1);
+ }
+
+ if (gibbs < 0.0f || gibbs > 1.0f) {
+ if (!quiet) {
+ fprintf(stderr, "Gibbs compensation clamped to [0.0, 1.0]\n");
+ fprintf(stderr, " Supplied value: %.2f\n", gibbs);
+ }
+ gibbs = gibbs < 0.0f ? 0.0f : gibbs;
+ gibbs = gibbs > 1.0f ? 1.0f : gibbs;
+ if (!quiet) {
+ fprintf(stderr, " Clamped to: %.2f\n", gibbs);
+ }
+ }
+
+ if (note_step < 1) {
+ if (!quiet) {
+ fprintf(stderr, "Using minimum note step of 1\n");
+ }
+ note_step = 1;
+ }
+
+ /* Get file to write to */
+ if (!filename) {
+ file = stdout;
+ } else {
+ file = fopen(filename, "w");
+ }
+
+ w = wavedata_new(sample_rate);
+
+ if (!w) {
+ if (!quiet) {
+ fprintf(stderr, "Unable to create wavedata\n");
+ }
+
+ exit(-1);
+ }
+
+ freq = FREQ_FROM_NOTE(first_note);
+ max_harmonic_lf = HARM_FROM_FREQ(freq, sample_rate);
+ max_harmonic_hf = max_harmonic_lf;
+
+ for (i = 0; max_harmonic_hf > MIN_HARM(wavetype); i += note_step) {
+ freq = FREQ_FROM_NOTE(first_note + i + note_step);
+ max_harmonic_hf = HARM_FROM_FREQ(freq, sample_rate);
+
+ max_harmonic_hf = ACTUAL_HARM(max_harmonic_hf, wavetype);
+ max_harmonic_lf = ACTUAL_HARM(max_harmonic_lf, wavetype);
+
+ while (max_harmonic_lf == max_harmonic_hf) {
+ i += note_step;
+ freq = FREQ_FROM_NOTE(first_note + i + note_step);
+ max_harmonic_hf = HARM_FROM_FREQ(freq, sample_rate);
+ max_harmonic_hf = ACTUAL_HARM(max_harmonic_hf, wavetype);
+ }
+
+ if (max_harmonic_lf > MIN_EXTRA_HARM(wavetype)) {
+ sample_count = max_harmonic_lf * 2;
+ sample_count = sample_count < min_table_size ? min_table_size : sample_count;
+
+ if (wavedata_add_table(w, sample_count, max_harmonic_lf)) {
+ if (!quiet) {
+ fprintf(stderr, "Could not add wavetable to wavedata\n");
+ }
+
+ wavedata_cleanup(w);
+ exit(-1);
+ }
+ }
+ max_harmonic_lf = max_harmonic_hf;
+ }
+
+ if (!quiet) {
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Generating %s wave\n", wave_names[wavetype]);
+ fprintf(stderr, " Sample Rate: %ld\n", sample_rate);
+ if (gibbs > 0.0f) {
+ fprintf(stderr, " Gibbs' compensation factor: %+.2f\n\n", gibbs);
+ }
+ }
+
+ wavedata_generate_tables(w, (Wavetype)wavetype, gibbs);
+
+ if (!test) {
+ if (wavedata_write(w, file, prefix)) {
+ if (!quiet) {
+ fprintf(stderr, "Could not write to file %s!\n\n", filename);
+ }
+ } else {
+ if (!quiet) {
+ fprintf(stderr, "Written to file %s\n\n", filename);
+ }
+ }
+ }
+
+ wavedata_cleanup(w);
+
+ return 0;
+}
diff --git a/src/wdatutil.c b/src/wdatutil.c
new file mode 100644
index 0000000..86b5fb0
--- /dev/null
+++ b/src/wdatutil.c
@@ -0,0 +1,679 @@
+/*
+ Code to generate wavedata for bandlimited waveforms.
+ Copyright 2011-2014 David Robillard
+ Copyright 2003 Mike Rawes
+
+ This is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 software. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "common.h"
+#include "math_func.h"
+#include "wavedata.h"
+#include "wdatutil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void generate_sine(float* samples,
+ uint32_t sample_count);
+void generate_sawtooth(float* samples,
+ uint32_t sample_count,
+ unsigned long harmonics,
+ float gibbs_comp);
+void generate_square(float* samples,
+ uint32_t sample_count,
+ unsigned long harmonics,
+ float gibbs_comp);
+void generate_parabola(float* samples,
+ uint32_t sample_count,
+ unsigned long harmonics,
+ float gibbs_comp);
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+const char* wave_names[] = {
+ "saw",
+ "square",
+ "parabola"
+};
+
+const char* wave_descriptions[] = {
+ "Sawtooth Wave",
+ "Square Wave",
+ "Parabola Wave"
+};
+
+unsigned long wave_first_harmonics[] = {
+ 1,
+ 1,
+ 1
+};
+
+unsigned long wave_harmonic_intervals[] = {
+ 1,
+ 2,
+ 1
+};
+
+Wavedata*
+wavedata_new(double sample_rate)
+{
+ Wavedata* w;
+
+ w = (Wavedata*)malloc(sizeof(Wavedata));
+
+ if (!w) {
+ return 0;
+ }
+
+ w->data_handle = 0;
+ w->table_count = 0;
+ w->tables = 0;
+ w->lookup = 0;
+ w->lookup_max = 0;
+ w->sample_rate = (float)sample_rate;
+ w->nyquist = w->sample_rate * 0.5f;
+
+ return w;
+}
+
+void
+wavedata_cleanup(Wavedata* w)
+{
+ unsigned long ti;
+ Wavetable* t;
+
+ for (ti = 0; ti < w->table_count; ti++) {
+ t = w->tables[ti];
+ if (t) {
+ if (t->samples_hf) {
+ free(t->samples_hf);
+ }
+
+ if (t->samples_lf) {
+ free(t->samples_lf);
+ }
+
+ free(t);
+ }
+ }
+
+ free(w);
+}
+
+int
+wavedata_add_table(Wavedata* w,
+ uint32_t sample_count,
+ unsigned long harmonics)
+{
+ Wavetable** tables;
+ Wavetable* t;
+ size_t bytes;
+
+ t = (Wavetable*)malloc(sizeof(Wavetable));
+
+ if (!t) {
+ return -1;
+ }
+
+ /* Extra 3 samples for interpolation */
+ bytes = (sample_count + 3) * sizeof(float);
+
+ t->samples_lf = (float*)malloc(bytes);
+
+ if (!t->samples_lf) {
+ free(t);
+ return -1;
+ }
+
+ t->samples_hf = (float*)malloc(bytes);
+
+ if (!t->samples_hf) {
+ free(t->samples_lf);
+ free(t);
+ return -1;
+ }
+
+ bytes = (w->table_count + 1) * sizeof(Wavetable*);
+ if (w->table_count == 0) {
+ tables = (Wavetable**)malloc(bytes);
+ } else {
+ tables = (Wavetable**)realloc(w->tables, bytes);
+ }
+
+ if (!tables) {
+ free(t);
+ return -1;
+ }
+
+ t->sample_count = sample_count;
+ t->harmonics = harmonics;
+
+ if (w->lookup_max < harmonics) {
+ w->lookup_max = harmonics;
+ }
+
+ tables[w->table_count] = t;
+ w->tables = tables;
+ w->table_count++;
+
+ return 0;
+}
+
+void
+wavedata_generate_tables(Wavedata* w,
+ Wavetype wavetype,
+ float gibbs_comp)
+{
+ Wavetable* t;
+ float* samples_lf;
+ float* samples_hf;
+ unsigned long h_lf;
+ unsigned long h_hf;
+ unsigned long i;
+
+ for (i = 0; i < w->table_count; i++) {
+ t = w->tables[i];
+
+ h_lf = t->harmonics;
+
+ if (i < w->table_count - 1) {
+ h_hf = w->tables[i + 1]->harmonics;
+ } else {
+ h_hf = 1;
+ }
+
+ samples_lf = t->samples_lf;
+ samples_hf = t->samples_hf;
+ samples_lf++;
+ samples_hf++;
+
+ switch (wavetype) {
+ case SAW:
+ generate_sawtooth(samples_lf, t->sample_count, h_lf, gibbs_comp);
+ generate_sawtooth(samples_hf, t->sample_count, h_hf, gibbs_comp);
+ break;
+ case SQUARE:
+ generate_square(samples_lf, t->sample_count, h_lf, gibbs_comp);
+ generate_square(samples_hf, t->sample_count, h_hf, gibbs_comp);
+ break;
+ case PARABOLA:
+ generate_parabola(samples_lf, t->sample_count, h_lf, gibbs_comp);
+ generate_parabola(samples_hf, t->sample_count, h_hf, gibbs_comp);
+ break;
+ }
+
+ /* Basic denormalization */
+ for (uint32_t s = 0; s < t->sample_count; s++) {
+ samples_lf[s] = FABSF(samples_lf[s]) < SMALLEST_FLOAT ? 0.0 : samples_lf[s];
+ }
+
+ samples_lf--;
+ samples_lf[0] = samples_lf[t->sample_count];
+ samples_lf[t->sample_count + 1] = samples_hf[1];
+ samples_lf[t->sample_count + 2] = samples_hf[2];
+
+ for (uint32_t s = 0; s < t->sample_count; s++) {
+ samples_hf[s] = FABSF(samples_hf[s]) < SMALLEST_FLOAT ? 0.0 : samples_hf[s];
+ }
+
+ samples_hf--;
+ samples_hf[0] = samples_hf[t->sample_count];
+ samples_hf[t->sample_count + 1] = samples_hf[1];
+ samples_hf[t->sample_count + 2] = samples_hf[2];
+ }
+}
+
+static void
+wavedata_write_prototype(FILE* wdat_fp,
+ const char* data_name)
+{
+ fprintf(wdat_fp, "__attribute__((visibility(\"default\")))\n");
+ fprintf(wdat_fp, "int\n");
+ fprintf(
+ wdat_fp,
+ "blop_get_%s (Wavedata * w, unsigned long sample_rate)",
+ data_name);
+}
+
+int
+wavedata_write(Wavedata* w,
+ FILE* wdat_fp,
+ const char* data_name)
+{
+ Wavetable* t = 0;
+ unsigned long table_count;
+ unsigned long i;
+ unsigned long j;
+ unsigned long s;
+ int column;
+ /*
+ * Extra table at end
+ */
+ table_count = w->table_count + 1;
+
+ fprintf(wdat_fp, "#include \"lv2/lv2plug.in/ns/lv2core/lv2.h\"\n");
+ fprintf(wdat_fp, "#include <stdio.h>\n");
+ fprintf(wdat_fp, "#include \"wavedata.h\"\n");
+ fprintf(wdat_fp, "\n");
+ /*
+ * Function prototype
+ */
+ wavedata_write_prototype(wdat_fp, data_name);
+ fprintf(wdat_fp, ";\n\n");
+ /*
+ * Fixed data and tables
+ */
+ fprintf(wdat_fp, "unsigned long ref_count = 0;\n");
+ fprintf(wdat_fp, "unsigned long first_sample_rate = 0;\n");
+ fprintf(wdat_fp, "unsigned long table_count = %ld;\n", table_count);
+ fprintf(wdat_fp, "Wavetable tables[%ld];\n", table_count);
+ fprintf(wdat_fp, "Wavetable * ptables[%ld];\n", table_count);
+ fprintf(wdat_fp, "unsigned long lookup[%ld];\n", w->lookup_max + 1);
+ fprintf(wdat_fp, "unsigned long lookup_max = %ld;\n", w->lookup_max);
+ fprintf(wdat_fp, "\n");
+ /*
+ * Sample data
+ * Each table has an extra 3 samples for interpolation
+ */
+ for (i = 0; i < w->table_count; i++) {
+ t = w->tables[i];
+
+ fprintf(wdat_fp, "static float samples_lf_%ld[%ld] = {\n", i, t->sample_count + 3);
+
+ column = 0;
+ for (s = 0; s < t->sample_count + 3 - 1; s++, column++) {
+ if (column == 5) {
+ fprintf(wdat_fp, "\n");
+ column = 0;
+ }
+ fprintf(wdat_fp, "%+.8ef,", t->samples_lf[s]);
+ }
+
+ if (column == 5) {
+ fprintf(wdat_fp, "\n");
+ }
+
+ fprintf(wdat_fp, "%+.8ef\n", t->samples_lf[s]);
+ fprintf(wdat_fp, "};\n");
+ fprintf(wdat_fp, "\n");
+
+ fprintf(wdat_fp, "static float samples_hf_%ld[%ld] = {\n", i, t->sample_count + 3);
+
+ column = 0;
+ for (s = 0; s < t->sample_count + 3 - 1; s++, column++) {
+ if (column == 5) {
+ fprintf(wdat_fp, "\n");
+ column = 0;
+ }
+ fprintf(wdat_fp, "%+.8ef,", t->samples_hf[s]);
+ }
+
+ if (column == 5) {
+ fprintf(wdat_fp, "\n");
+ }
+
+ fprintf(wdat_fp, "%+.8ef\n", t->samples_hf[s]);
+ fprintf(wdat_fp, "};\n");
+ fprintf(wdat_fp, "\n");
+ }
+
+ fprintf(wdat_fp, "float samples_zero[%ld];\n", t->sample_count + 3);
+ fprintf(wdat_fp, "\n");
+ /*
+ * Function to get Wavedata - the sample rate is needed to calculate
+ * frequencies and related things
+ */
+ wavedata_write_prototype(wdat_fp, data_name);
+ fprintf(wdat_fp, "\n{\n");
+ fprintf(wdat_fp, "\tWavetable * t;\n");
+ fprintf(wdat_fp, "\tunsigned long ti;\n");
+ fprintf(wdat_fp, "\n");
+ /*
+ * Sample rate must be > 0
+ */
+ fprintf(wdat_fp, "\tif (sample_rate == 0)\n");
+ fprintf(wdat_fp, "\t\treturn -1;\n");
+ fprintf(wdat_fp, "\n");
+ /*
+ * First time call - set up all sample rate dependent data
+ */
+ fprintf(wdat_fp, "\tif (first_sample_rate == 0)\n");
+ fprintf(wdat_fp, "\t{\n");
+ fprintf(wdat_fp, "\t\tfirst_sample_rate = sample_rate;\n");
+ fprintf(wdat_fp, "\t\tw->sample_rate = (float) sample_rate;\n");
+ fprintf(wdat_fp, "\t\tw->nyquist = w->sample_rate / 2.0f;\n");
+ fprintf(wdat_fp, "\t\tw->table_count = table_count;\n");
+ fprintf(wdat_fp, "\t\tw->tables = ptables;\n");
+ fprintf(wdat_fp, "\t\tw->lookup = lookup;\n");
+ fprintf(wdat_fp, "\t\tw->lookup_max = lookup_max;\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\t\tfor (ti = 1; ti < table_count - 1; ti++)\n");
+ fprintf(wdat_fp, "\t\t{\n");
+ fprintf(wdat_fp, "\t\t\tt = ptables[ti];\n");
+ fprintf(wdat_fp,
+ "\t\t\tt->min_frequency = w->nyquist / (float) (ptables[ti - 1]->harmonics);\n");
+ fprintf(wdat_fp, "\t\t\tt->max_frequency = w->nyquist / (float) (t->harmonics);\n");
+ fprintf(wdat_fp, "\t\t}\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\t\tt = w->tables[0];\n");
+ fprintf(wdat_fp, "\t\tt->min_frequency = 0.0f;\n");
+ fprintf(wdat_fp, "\t\tt->max_frequency = ptables[1]->min_frequency;\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\t\tt = ptables[table_count - 1];\n");
+ fprintf(wdat_fp, "\t\tt->min_frequency = ptables[w->table_count - 2]->max_frequency;\n");
+ fprintf(wdat_fp, "\t\tt->max_frequency = w->nyquist;\n");
+ fprintf(wdat_fp, "\t\n");
+ fprintf(wdat_fp, "\t\tfor (ti = 0; ti < w->table_count; ti++)\n");
+ fprintf(wdat_fp, "\t\t{\n");
+ fprintf(wdat_fp, "\t\t\tt = w->tables[ti];\n");
+ fprintf(wdat_fp, "\t\t\tt->phase_scale_factor = (float) (t->sample_count) / w->sample_rate;\n");
+ fprintf(wdat_fp,
+ "\t\t\tt->range_scale_factor = 1.0f / (t->max_frequency - t->min_frequency);\n");
+ fprintf(wdat_fp, "\t\t}\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\t\treturn 0;\n");
+ fprintf(wdat_fp, "\t}\n");
+ /*
+ * Already called at least once, so just set up wavedata
+ */
+ fprintf(wdat_fp, "\telse if (sample_rate == first_sample_rate)\n");
+ fprintf(wdat_fp, "\t{\n");
+ fprintf(wdat_fp, "\t\tw->sample_rate = (float) sample_rate;\n");
+ fprintf(wdat_fp, "\t\tw->nyquist = w->sample_rate / 2.0f;\n");
+ fprintf(wdat_fp, "\t\tw->table_count = table_count;\n");
+ fprintf(wdat_fp, "\t\tw->tables = ptables;\n");
+ fprintf(wdat_fp, "\t\tw->lookup = lookup;\n");
+ fprintf(wdat_fp, "\t\tw->lookup_max = lookup_max;\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\t\treturn 0;\n");
+ fprintf(wdat_fp, "\t}\n");
+ /*
+ * Sample rate does not match, so fail
+ *
+ * NOTE: This means multiple sample rates are not supported
+ * This should not present any problems
+ */
+ fprintf(wdat_fp, "\telse\n");
+ fprintf(wdat_fp, "\t{\n");
+ fprintf(wdat_fp, "\t\treturn -1;\n");
+ fprintf(wdat_fp, "\t}\n");
+ fprintf(wdat_fp, "}\n");
+ fprintf(wdat_fp, "\n");
+ /*
+ * _init()
+ * Assemble tables and lookup
+ */
+ fprintf(wdat_fp, "static void\n");
+ fprintf(wdat_fp, "__attribute__ ((constructor))\n");
+ fprintf(wdat_fp, "init (void)\n");
+ fprintf(wdat_fp, "{\n");
+ fprintf(wdat_fp, "\tunsigned long max_harmonic;\n");
+ fprintf(wdat_fp, "\tunsigned long ti;\n");
+ fprintf(wdat_fp, "\tunsigned long li;\n");
+ fprintf(wdat_fp, "\n");
+
+ for (i = 0; i < w->table_count; i++) {
+ t = w->tables[i];
+
+ fprintf(wdat_fp, "\ttables[%ld].sample_count = %ld;\n", i, t->sample_count);
+ fprintf(wdat_fp, "\ttables[%ld].samples_lf = samples_lf_%ld;\n", i, i);
+ fprintf(wdat_fp, "\ttables[%ld].samples_hf = samples_hf_%ld;\n", i, i);
+ fprintf(wdat_fp, "\ttables[%ld].harmonics = %ld;\n", i, t->harmonics);
+ fprintf(wdat_fp, "\n");
+ }
+ /*
+ * Last table - uses same sample data as previous table for lf data,
+ * and zeroes for hf data
+ */
+ i = w->table_count - 1;
+ j = i + 1;
+ t = w->tables[i];
+ /*
+ * Zero silent samples
+ */
+ fprintf(wdat_fp, "\tfor (uint32_t s = 0; s < %ld; s++)\n", t->sample_count + 3);
+ fprintf(wdat_fp, "\t\tsamples_zero[s] = 0.0f;\n");
+ fprintf(wdat_fp, "\n");
+
+ fprintf(wdat_fp, "\ttables[%ld].sample_count = %ld;\n", j, t->sample_count);
+ fprintf(wdat_fp, "\ttables[%ld].samples_lf = samples_hf_%ld;\n", j, i);
+ fprintf(wdat_fp, "\ttables[%ld].samples_hf = samples_zero;\n", j);
+ fprintf(wdat_fp, "\ttables[%ld].harmonics = 1;\n", j);
+ fprintf(wdat_fp, "\n");
+ /*
+ * Get pointers to each wavetable and put them in the pointer array
+ */
+ fprintf(wdat_fp, "\tfor (ti = 0; ti < table_count; ti++)\n");
+ fprintf(wdat_fp, "\t\tptables[ti] = &tables[ti];\n");
+ fprintf(wdat_fp, "\n");
+ /*
+ * Shift all sample offsets forward by one sample
+ * !!! NO! Don't!
+ fprintf (wdat_fp, "\tfor (ti = 0; ti < table_count; ti++)\n");
+ fprintf (wdat_fp, "\t{\n");
+ fprintf (wdat_fp, "\t\tptables[ti]->samples_lf++;\n");
+ fprintf (wdat_fp, "\t\tptables[ti]->samples_hf++;\n");
+ fprintf (wdat_fp, "\t}\n");
+ fprintf (wdat_fp, "\n");
+ */
+ /*
+ * Table lookup vector indexed by harmonic
+ * Add lookup data to vector
+ */
+ fprintf(wdat_fp, "\tli = 0;");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\tfor (ti = table_count - 1; ti > 0; ti--)\n");
+ fprintf(wdat_fp, "\t{\n");
+ fprintf(wdat_fp, "\t\tmax_harmonic = ptables[ti]->harmonics;\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\t\tfor ( ; li <= max_harmonic; li++)\n");
+ fprintf(wdat_fp, "\t\t\tlookup[li] = ti;\n");
+ fprintf(wdat_fp, "\t}\n");
+ fprintf(wdat_fp, "\n");
+ fprintf(wdat_fp, "\tfor ( ; li <= lookup_max; li++)\n");
+ fprintf(wdat_fp, "\t\tlookup[li] = 0;\n");
+ fprintf(wdat_fp, "}\n");
+
+ return 0;
+}
+
+void
+generate_sawtooth(float* samples,
+ uint32_t sample_count,
+ unsigned long harmonics,
+ float gibbs_comp)
+{
+ double phase_scale = 2.0 * M_PI / (double)sample_count;
+ float scale = 2.0f / M_PI;
+ unsigned long i;
+ unsigned long h;
+ double mhf;
+ double hf;
+ double k;
+ double m;
+ double phase;
+ double partial;
+
+ if (gibbs_comp > 0.0f) {
+ /* Degree of Gibbs Effect compensation */
+ mhf = (double)harmonics;
+ k = M_PI * (double)gibbs_comp / mhf;
+
+ for (i = 0; i < sample_count; i++) {
+ samples[i] = 0.0f;
+ }
+
+ for (h = 1; h <= harmonics; h++) {
+ hf = (double)h;
+
+ /* Gibbs Effect compensation - Hamming window */
+ /* Modified slightly for smoother fade at highest frequencies */
+ m = 0.54 + 0.46 * cos((hf - 0.5 / mhf) * k);
+
+ for (i = 0; i < sample_count; i++) {
+ phase = (double)i * phase_scale;
+ partial = (m / hf) * sin(phase * hf);
+ samples[i] += (float)partial;
+ }
+ }
+
+ for (i = 0; i < sample_count; i++) {
+ samples[i] *= scale;
+ }
+ } else {
+ /* Allow overshoot */
+ for (i = 0; i < sample_count; i++) {
+ phase = (double)i * phase_scale;
+ samples[i] = 0.0f;
+
+ for (h = 1; h <= harmonics; h++) {
+ hf = (double)h;
+ partial = (1.0 / hf) * sin(phase * hf);
+ samples[i] += (float)partial;
+ }
+ samples[i] *= scale;
+ }
+ }
+}
+
+void
+generate_square(float* samples,
+ uint32_t sample_count,
+ unsigned long harmonics,
+ float gibbs_comp)
+{
+ double phase_scale = 2.0 * M_PI / (double)sample_count;
+ float scale = 4.0f / M_PI;
+ unsigned long i;
+ unsigned long h;
+ double mhf;
+ double hf;
+ double k;
+ double m;
+ double phase;
+ double partial;
+
+ if (gibbs_comp > 0.0f) {
+ /* Degree of Gibbs Effect compensation */
+ mhf = (double)harmonics;
+ k = M_PI * (double)gibbs_comp / mhf;
+
+ for (i = 0; i < sample_count; i++) {
+ samples[i] = 0.0f;
+ }
+
+ for (h = 1; h <= harmonics; h += 2) {
+ hf = (double)h;
+
+ /* Gibbs Effect compensation - Hamming window */
+ /* Modified slightly for smoother fade at highest frequencies */
+ m = 0.54 + 0.46 * cos((hf - 0.5 / pow(mhf, 2.2)) * k);
+
+ for (i = 0; i < sample_count; i++) {
+ phase = (double)i * phase_scale;
+ partial = (m / hf) * sin(phase * hf);
+ samples[i] += (float)partial;
+ }
+ }
+
+ for (i = 0; i < sample_count; i++) {
+ samples[i] *= scale;
+ }
+ } else {
+ /* Allow overshoot */
+ for (i = 0; i < sample_count; i++) {
+ phase = (double)i * phase_scale;
+ samples[i] = 0.0f;
+
+ for (h = 1; h <= harmonics; h += 2) {
+ hf = (double)h;
+ partial = (1.0 / hf) * sin(phase * hf);
+ samples[i] += (float)partial;
+ }
+ samples[i] *= scale;
+ }
+ }
+}
+
+void
+generate_parabola(float* samples,
+ uint32_t sample_count,
+ unsigned long harmonics,
+ float gibbs_comp)
+{
+ double phase_scale = 2.0 * M_PI / (double)sample_count;
+ float scale = 2.0f / (M_PI * M_PI);
+ unsigned long i;
+ unsigned long h;
+ //double mhf;
+ double hf;
+ //double k;
+ //double m;
+ double phase;
+ double partial;
+ double sign;
+
+ if (gibbs_comp > 0.0f) {
+ /* Degree of Gibbs Effect compensation */
+ //mhf = (double)harmonics;
+ //k = M_PI * (double)gibbs_comp / mhf;
+
+ for (i = 0; i < sample_count; i++) {
+ samples[i] = 0.0f;
+ }
+
+ sign = -1.0;
+
+ for (h = 1; h <= harmonics; h++) {
+ hf = (double)h;
+
+ /* Gibbs Effect compensation - Hamming window */
+ /* Modified slightly for smoother fade at highest frequencies */
+ //m = 0.54 + 0.46 * cos((hf - 0.5 / mhf) * k);
+
+ for (i = 0; i < sample_count; i++) {
+ phase = (double)i * phase_scale;
+ partial = (sign * 4.0 / (hf * hf)) * cos(phase * hf);
+ samples[i] += (float)partial;
+ }
+ sign = -sign;
+ }
+
+ for (i = 0; i < sample_count; i++) {
+ samples[i] *= scale;
+ }
+ } else {
+ /* Allow overshoot */
+ for (i = 0; i < sample_count; i++) {
+ phase = (double)i * phase_scale;
+ samples[i] = 0.0f;
+ sign = -1.0;
+
+ for (h = 1; h <= harmonics; h++) {
+ hf = (double)h;
+ partial = (sign * 4.0 / (hf * hf)) * cos(phase * hf);
+ samples[i] += (float)partial;
+ sign = -sign;
+ }
+ samples[i] *= scale;
+ }
+ }
+}
diff --git a/waf b/waf
index e22930a..ac152b9 100755
--- a/waf
+++ b/waf
@@ -1,16 +1,169 @@
#!/usr/bin/env python
+# encoding: latin-1
+# Thomas Nagy, 2005-2017
+#
+"""
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
-# Minimal waf script for projects that include waflib directly
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
-from waflib import Context, Scripting
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
-import inspect
-import os
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
-def main():
- script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main)))
- project_path = os.path.dirname(script_path)
- Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path)
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import os, sys, inspect
+
+VERSION="2.0.4"
+REVISION="7cbb714529fb8ebf6acd59fd281ce525"
+GIT="x"
+INSTALL=''
+C1='#/'
+C2='#,'
+C3='#*'
+cwd = os.getcwd()
+join = os.path.join
+
+
+WAF='waf'
+def b(x):
+ return x
+if sys.hexversion>0x300000f:
+ WAF='waf3'
+ def b(x):
+ return x.encode()
+
+def err(m):
+ print(('\033[91mError: %s\033[0m' % m))
+ sys.exit(1)
+
+def unpack_wafdir(dir, src):
+ f = open(src,'rb')
+ c = 'corrupt archive (%d)'
+ while 1:
+ line = f.readline()
+ if not line: err('run waf-light from a folder containing waflib')
+ if line == b('#==>\n'):
+ txt = f.readline()
+ if not txt: err(c % 1)
+ if f.readline() != b('#<==\n'): err(c % 2)
+ break
+ if not txt: err(c % 3)
+ txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00'))
+
+ import shutil, tarfile
+ try: shutil.rmtree(dir)
+ except OSError: pass
+ try:
+ for x in ('Tools', 'extras'):
+ os.makedirs(join(dir, 'waflib', x))
+ except OSError:
+ err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir)
+
+ os.chdir(dir)
+ tmp = 't.bz2'
+ t = open(tmp,'wb')
+ try: t.write(txt)
+ finally: t.close()
+
+ try:
+ t = tarfile.open(tmp)
+ except:
+ try:
+ os.system('bunzip2 t.bz2')
+ t = tarfile.open('t')
+ tmp = 't'
+ except:
+ os.chdir(cwd)
+ try: shutil.rmtree(dir)
+ except OSError: pass
+ err("Waf cannot be unpacked, check that bzip2 support is present")
+
+ try:
+ for x in t: t.extract(x)
+ finally:
+ t.close()
+
+ for x in ('Tools', 'extras'):
+ os.chmod(join('waflib',x), 493)
+
+ if sys.hexversion<0x300000f:
+ sys.path = [join(dir, 'waflib')] + sys.path
+ import fixpy2
+ fixpy2.fixdir(dir)
+
+ os.remove(tmp)
+ os.chdir(cwd)
+
+ try: dir = unicode(dir, 'mbcs')
+ except: pass
+ try:
+ from ctypes import windll
+ windll.kernel32.SetFileAttributesW(dir, 2)
+ except:
+ pass
+
+def test(dir):
+ try:
+ os.stat(join(dir, 'waflib'))
+ return os.path.abspath(dir)
+ except OSError:
+ pass
+
+def find_lib():
+ src = os.path.abspath(inspect.getfile(inspect.getmodule(err)))
+ base, name = os.path.split(src)
+
+ #devs use $WAFDIR
+ w=test(os.environ.get('WAFDIR', ''))
+ if w: return w
+
+ #waf-light
+ if name.endswith('waf-light'):
+ w = test(base)
+ if w: return w
+ err('waf-light requires waflib -> export WAFDIR=/folder')
+
+ dirname = '%s-%s-%s' % (WAF, VERSION, REVISION)
+ for i in (INSTALL,'/usr','/usr/local','/opt'):
+ w = test(i + '/lib/' + dirname)
+ if w: return w
+
+ #waf-local
+ dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname)
+ w = test(dir)
+ if w: return w
+
+ #unpack
+ unpack_wafdir(dir, src)
+ return dir
+
+wafdir = find_lib()
+sys.path.insert(0, wafdir)
if __name__ == '__main__':
- main()
+
+ from waflib import Scripting
+ Scripting.waf_entry_point(cwd, VERSION, wafdir)
+
+#==>
+#BZh91AY&SYÝÚcš¤ÿÿÿ°ÐÿÿÿÿÿÿÿÿÿÿÿE ‚„ 0Á#*ˆ¨bD{Ô´@#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*\ú¦Õ¶£XkP;šK²j¶WÝÎIÓi½Û¶ÍQ«Ðj®ÌÞpä_xÜú}xk{o»S©­K­Õ{w¾^÷Û»çsµ“Ox¤Œ€#,i¥ënî¶#,ܧ*ÞÀâô»vÏvw-¹½†KÐß;<Æ'»v6õÛÀî{¥uökÂYJSÓ»»½íóÛï¾W½€õÞ×Ç‹ÝÎÝÞéÜ #¯½XM·ßg#*#*#*#*4o`›#**¸¡ÃÓ¡ÝÍîà#/{³Ý0ÓÛ¹è;ÙG–ë Ð4(ë¾õí£röõéé£G¶ »ÒB¨¡‘£l=ìp#/ª¢‚T¤€ ¹ƒvÑ$ºÅP¢…$óÝ×mì#,PÞ¾ÚïMhìÃëîÏÔï±åÜ5ͺé+“¸+v0Ûˆ­šë®­÷ßuסõví#*]»î_v«§¯MïnºÔx9›Ü½Ï5õ’{y̻﷧·¾ÚêúÙö‰»rõöÞž·Ývs·6Ù³¯q›¾÷»GEûSÞŰaIU$E ô#,[w6š£ÞÎöwunÝw'mÖƒÒã'»p{eÓ*"•Sžï{—è#*  iTˆ*^ÁÈ ˜è¼ÎBãh÷»Öñ«­E÷»î÷{¾gß}÷ÃÈô}€i^ùÎH´Ç§rÊ5N ô#,ÛÞ»©VÍd ¾gx÷AÐ{yíx4×ÜæàÎXúN»öq×G»jöó{Zè‰í÷½ÔUO·vîgÞ< =â[iâñkâ>åöÛwUºwF滜ÜbÇ^÷n÷{»£&mßcyV÷.뻤¹®îRíëzò¾ÕÜÅ ÖÑÎæmÛ¯phØ»zˆÉÐÑÎÁkSkÎ7¶ë>·væÆí­ÇϽíï=ì{ÛêÇÞÞª½‹î»­ìÄïu³˜¶ôdz×{Iæ½KÍÚ.Ûsx¶#*#,ÎÙz÷µ:·±öw±ÞÝÛWŽˆP (* ¨„’FÚÛ—iÐ娥Z#,Mlλ})îô:íäé Ú7q›oO+Õ ©Û•”SŽ^=æP§{ÞºÝG!»&o»¾ÛÍð#*ÕÔ€#*%o=ÛtæÝ÷7/|ö]Žw•÷]Û}Æö½ÝÇuÇc}Ö™Ï{ÞUÎé#,º÷kÒïpzù4úò9zÏG•˜6&®tØ0eb¹Ý·×lxœïßoy½mŸ#*I:2öãGk#*÷¶xtûg§Õ}Á£z.Á϶ç³ï©¬ÜÛ®å˜fÅæàõ·mßu³ZÍw>/sË«+:íç¾¾{壹ÎÁ°3]ÀäôÝO{nÇÞiåiï7nº®°G.ÓÂÝ/T·ws«™:oU½³žÎ`UompUVž÷;2½{³Ë0lzÞm°‡wŽy§W××ßGÛOœúö#,ñîÞÚ’¥7rÝöû¯sã7»tÀ€ôÂìnÇ­ˆW;±çìÝš{ܰ^ðiÕ5¤ê·.ׯW†}ç»ë€n·ˆ@èšÅì¹@zíyWžÚûâf¯ºÊ¾ƒ #*èÙîó^ç^÷ufØg­[Þ+“³5Ø…g·¦¹}îW¯.·[G‘¨Š*Ý9ªé;iJÙÝÚûóZ™÷}ëÆuYgÊÛ‘&3Ùç#,œÇSß-Úñî‰îri5¾¨Ù[2}ö×Þ¹Ü0SY¯{·gs¶'­=㺆_'¾÷;>ÖÔ`;wn:xº¼¼o(÷6¯·ÅÁ¦ˆ#*€@4#*CF€y4hIéLQä€#Ôõ<¦‚S@„  òÕ=¦©ú§”ýQ£Fž£&F†Pi #*#*#*#*  ˆMFiO"SMSñM¦£Òš d5¦›ÒCÒh#*#*Ð#*#*“Õ)"&D#,E7©””ôÔÓA‘ #*hzš#*É#*#*#*#*B#*#*ÈÚhLbOF“52jyOPd¨#,#*#* 54ÄȦ#B2)ä'é6©êyOHf£Ôzƒ@#*€#*?þùëÛV»‰]΃r¶®ä¿NÕ¥Ô"b#ãµkºA0Œ…¨Õ–Ù—½VÚåmµFTÅ ‰î=¾ÿu±î¬^þò^X¬­WjÅZÆó!nžoôÚåÉ.ø®\ãxiqªøÖ÷r¶^A<é‘1UnÐ%_ЍD B#­ Gg[ñ&üZüLY©wsZQǬÜÍ—g8âZZ®fø3$7›×SY¾ªb@ˆÑ>ýÕ·äB·Ä(R1Xª#/De[Y6Õ™¶´–µbô¶×!jÔD”#/£Pd£!\ç9a (ƒ¡XL#*¨9D,¨EÄQ@õÀ #,‚Ûi«Wv§E±X·µÝµ&ÚÖÛkß[m¶©™™ %šM16"X ¢Ii653%„Õ2Æ@3JQ¥ÛIŒ4I@M-KE±¨0¶ŒÒY4²1a-„#/61R”i#*5K4ÅŒLb¥bÉ›H¤Ù-Q%–ZSµDBËHlÐL(ÍF5£QZ0#/ƒI²"„©6)Œ” †Æ™¦ZF0"”Ú5)FÂ[M¶²Ö´ RT3bM™&BQdÛM¶šmjJ6RTÖÆZ–Ù•2Òe2Q#`Y¡ÍY¢’RÆ‚–E1L„ÆÐ‰2¢Í#h¤ÂX¨BÆÅ&¤1šTD)ˆ£b…ˆÊcÐÈŒ’6¤Á‹,D³4%(@D2’R4iY@fhÈ ‘DRÉY61£bZEˆd²‘cYJHM‰)20R‰ŒšC1 ©4iŒi2² *,I‰™KLE3#*ØÛ$3b$Æi¦l$ÂÄmI° ,¬!$”›DDšŒPRBX‚DÑ ŠAD °TDÃ(c$¤#P™D¤¬jf£b°–“RD“ˆKJT IKbH²Ì¢‘fI¢lÊDlb$Ø™J3dL6Í1’¥,XÅHli¤4b#R²Y#`²¤&‰²HH&¤DHÙ¦¤ -BHK2›(Ê Z)3HÚ#AÒÆ‰mL‰#,(4–c!²RYLE‚i”Å(£FaƒQM#/LTH2HaRf0$’4hÄD†XLPFÉ2¦f¬ÆŠ¥*‰DLÈjF˜…"3b¥#,²š6HÑD¤’M’(ÔÀÆM›#S4XØŠi2“2˜¥‘•›L‰XˆÁS2Ô¤Ó$†2ˆ¤54Z[FÍJ”É…1) #$dÉ)Y4XÉXŒeIÌEcI¢M&Êj6ME’H¡¤l ˆÆ –Í&&ÐhÑSi ¤Ê(‹fCfD’›%24 ™²d&¬ÙXµ’ÀdÄše’$±mÆ Ö#/e°¤I„£‰”jK0”Í4¦#,’²šS&´hI1JLf¡–M‘L)eF™a Ò ¡)3F‰¶ÔªÚ0IBjfŒ¦FÍ(¤”ÌDVƒR–À¥š,Å&˜ÊË*l²lA¦[ fŒL1MˆÊQ,4„¥¯ÜktBjj‘FŒÚ(ÅF¶ ’hÒj6²H¥”¨•#,Ñ4´…FÆÂ6I¨ÚÈŒ´j2ÉŒ£$YL©1¤A†&f”Öf¬bM*ÆÔRŒšaÆU$™‘šÂÆÐ(iYE2dËI¨6,ÛE±HÑSeÚÈ™dU1¬ÔS#/lØÊLͲ[M,&4mh±dF¶M2²%L²›Y5¢›e)M1iŠÔ$d¤mEŠVX“I©%*#hªÁµA£Em*"Ål[I¬”[Q´TTš±4ÉbÄTEj,2Ñ« ÚM%#,šÔ0’ŠA6ƒ-)&)Zk±£i‰¬j’Á¢ÚH-­S[lÓJ¨HL¦jjÉ¢M‘‰”´Š,‘[RÖmŒR›M²Í*c4Ój™m¥RÉ&f©R1f˜[BA™’e²Æ„ÓÒY6ÊÊ´kD²ŒaF*,H`‰˜Ðb“, , D‰Ú#, ŒCe´ÍS0!*(dÚŠÉ4ѲdÑE‘#,–)ÙH6DVjE‘ ™’XRQf)˜š…fHDeb›I’ˆÆ²#*%!¦DÉ!¨É€ÐÒÆQ4š‚ȘZB h2PËEŠ&”Ȧ4–i@Ö”„Lb˜JY&Y!5Œ‘Q¦ZŒQ³)$£ …Œ…Qe+#L6Š“’Œ›#RE¥„Š2mFƒFÌdѤٔٔ”³6™IX¦#,#,HÔC’ZŠ£f´fˆÔ4T¦“a¦6XÖe£@‘Œ„LR#,16$©-&P£e4ÅI¶JeF ªeM’ÉL¡1Q&’@D¡¥+2KhÚÈ…¦f@È•a!²ÌQɱ³HØ£D#,f“d36&"jHH54[ QQ¨£±™l4˜b„”24²dlb”Al ¨+,²Y …X´fJl¡*Hƒm QXÑ&‹¥Q¢ƒb‚#&¤ª5L%ÂÂ#,R”51¦l¥Qª#Ji¥¢‹d¶dZ$ Z‹ØŒ¥U-4UÆ“E’Ä‘M2•”+QH12J›ˆ™¤«Q°IŠ™¨©-0¦,ÒÔd¬ZÚLRViT‰­DÐ6%2”Ô–$’ÅIFÉ¢HŒIT”†¨¤™cVd#,5R¦TÄSmIY-’4…4“Q ˆÁDÙZM¢ÙI,l˜ÒcFÑ‹’FÕ(K-б&ÖŠ´e(ÚJ©BÔ[F¤¢Å"š$¦F`Li©PjfÉ3j5IbÕ%K6ÒkBV€‹cRTQ$[b™¶imEccZ‹m&dË(„²ÙX–ÑTY•Q´ÙQJj”S’ƒ#)52P64X"M(ÄÒf±¶53bH± I[M²šk-FѬf‘¨ÉF‹%­¶ZÖ)*1%ІXÑQM$­21’U±m‹LÕ´cZËISC-l¥’Úš›d-¨ÓV&Œ¢ˆ‹FÒJ(6ÍI¨Û›6TE ¢1$™I2#"ˆÈI­ÊÙöÿÕ©?ÙüTþÇ÷žf„ŸáþPV‘ %XÀ=–¾+ûZ=5йX4i6zºõ:Å\kû¶,bƘ5#q’÷ofªlþß¼‚6Ñé¢;ÜœbQ `ÅA‚áÑÆ—DÕ$ªªª‚®Œ¤{Ïãê½^Úÿ5ÚËñ.¿Ñýž/ò6ÚkÆ@nx%„ŒEôsÑ£ýÛlvÚE‡¯×N-ÁÖZX%'uÑÝêŧlNNï2##‰F61ukŽÏEcýÓ—Z|Ä£'ütz䬚€I¥áv7§^šèÏepòrhë²wB*35S4™³(¶‘Vª©"ñן‘Ög5r#&ÃßµÌV÷x3Fe:ãK™@¤¤)€‰$HÅæ×bÈkÒ3ˆ`Wd@ÛLå¹dfôÜÒX,‘’‹×ž¼†@Öö¯þ ,?ÎÀ7p‡ ÓXѧÐnk¦Ä¿2æ’Wz H±b‚>ï÷Vˆv¼^˜­D˳b(¦¦Ð¤Y;øä¬±É"˜Ò¼lÑ1ʤ”á÷éW‰AþáÄ,x»¡j4A¡¬°Ý³Ü}Ÿè×§C•=”+9P[îãF€ÑÖè æî]P ¬smžbŽr車esn–CEsnžw6*'×uôKol[í~…x¿\Še|\ŠÛÅÍã¤Oöµ^9ÍÂøüûZë¬;÷Ì!³iå”#6Ìzeq#,¶Ó`7¯ÇçZ÷oOvÛsI´guÊ<sm±‹ª#/CLÕ‰l¦h…0X#/´£®¹]çv9GJåÌ”RëºH‹M14 eÔÿ¾qf©‰5JE èQR"ÃR°ZwmŒºdâ2Õ‚¿*)ÕSOÖÔÁ¥mOÅé‰ ¼"WûjR2sÓª€¨â¡ÿ"j˜ˆdf$“í©‹™4¶‚1Æw×Ó8æ†k–¹¿úG ¡cŠ"©l¶‰÷UuÞãb§z£Mz­õØä‘A‘LÞ³‚‰àK+:+«'ß«æ\§0rpÕ{x˜F»¾ôfÚ]FrÅ|OªÎ­i­)—Ÿ‡±·ÝÎgÚѬƒ#/Ô`òªŠS÷kõ¿SžwÐÁíNÍÚÝ95ò¨STëF ¸ÚTj/&[:5­ä¢’~N1mË&³!<ØY*2®ŠVe‹)…°´æÒ wQJ#/9Ï+ÇÜü±S¢¹Hº&¬²ª>Ü]Á¤¡ $}Ì¡_hM>]adMŽCRßó°úš¬[Òé™ýGhfLRùõ×ãë¢:eˆošÛµ|Q8((UFx¡ÄZXÇ-'“3{iXžlï‡áïºÞ½ù×SFÈTQWË&£xÚ¹Vÿk÷{y1§ÖêM¯erÉ„ýç×üÞ¯¹íÖ)Ý[›JOÃùþmzQ²&1‰$ÔR|Ôa6àAqŠ3Éž¹`ÎÞÍ;–=.4\·5ÛÎû7¯[”’ÚJ‡½Ü±h¯×-ÖEõQKH ¨ÎTi® AOh•­WG\£bѲUô¾ú¼bÐh$òhUE‚‘v£×z{q^Zms#*Éójb¡HÓ–µ%ˆþ5]#/ "1Íkf¬üL ‚õ´>º$¨ÅFHŒŠj lÖÍ L+ž÷/#,A#”…K–¾<êäåÓ kæå—à °dÕSƒ ºTx¦7J)”"’ê­)ë½ZÈ߯®x:&þ”äå—§uØ1fÂj/•×Eñká+Æø9i-Ý“…âb-#/ŸÆ(ÑÝ¢4¶ÒÓV¾Ô¥Ý„S²ŠŸFÇÉlV–ŠEFRpg©˜L’5ª:T ©:ö·çAëÛ? {áÓ%Yáðçy7¾ø„jÅÄ(‹'/õYêÏ?®!kÁ4ntáAb3Q½ç˜wEúC<Bc²î 2‚Ó×™%lœH:‹k•II˜Q™F”ÏÎéæÃâ»ÉÂvCPIÝ…;´CþVx¾T_^àé;Òwa¼‘òÕZdnDF"#âÐ<¨§¥M«£Ût{ïžûð³…QÈz䬥tñÍûòP3T%!«enbÞçÜÕu6ãZ÷Ì$¹cr#‹4Ñ,íaöå¦È0ƒg‚Ô†~ô[»ç ú>Zo_9œTbtNlžLÑÛçÆÎxQçTîPëUæPœ¹ß80âè¢shú²…;Óõõ¾¿“©¨Í‘0Οx¶ÌµêùÍBúgŠä¾UPµ:ƒÆq‰=Þ”§Óh„PíOÑ‹!jÂ3ÞOzüÚÌ8`³a#,îBÉô;¨#/÷#5K~5Ûa$^l¡zÇóŒf:ãÓ4KåQŽÑ©1 é}©Ò‡Î\_'„W¯ÝÆoxíp‰z27W3†\2¶çhömï)Œ®O±R4?¶c²=vñúöÖ˜jV£_–RuÚ­vT9¥ ,U†(ÿgÛíîÉ ¥ 6bᓺª]§Î0+6 H#/B…!¬/;©Èä¶.<Ñ:zxºº/숡ÇL! ST×ÂŽlÏ#/Òè)ø³®ÙÝ!ƒJ‡Õ-"܆0#+‰È£×á”Æœ‚ÊØiÐztVÐÞu™ú¦Â>®þwµÕHا>®G豑ä=×”ÅQJ±Üöݽ;,š<ê¦ÙÓÅÀ ŒúH&ÚÛ:á1úEßNœÕî› ¸áÒÖ«ƒ¶*#,·©4ÑãÔâí4<kÜíÝBAopÔ¡x4ða¸v”„ÿ²àø ¬¹×¾*ߟ‹áã²IeTÓ·á×KIóëJEÖ• N¿)z.ÞGr\ÓÒƒºùsŒ_©¨ì"~;ýHé³ÝŸ9ñé¦q„ÜŸ˜„±GßÛŸ‘Î×T -ñ#,®>.™iÍÈùœ @ï+[q­þj/m˜ÛCZÐwÅ"œ3vDsSBþ?*ŸÌõéÍÆ£µœÍ_}7íöâúd6CU"¦é>ù_×ÞzúW ­^¾½ÌI0UJÙ ²…D©}îño?¢ i÷;Ü®½uؼÙKÛP @ˆ¨‡Þ”)†Œð²Ýšòi™e uKTW?ùl²*‹¡<*<ïúî¿'òÿ®êZ|ÿ?ÇV¿¢¾ör[y'ÙEZ((ªE¾Ê)Ÿ6x ùöæñÇòûp«ž•7sf±GrŸ¶|†ØíĨ{«K$O÷šÛWʸIM¸— ó¤`ýU55Á)™ïÅÌxÔÒëæ—aÃLlÀY¬ÒÖLa>ìµ»Òf~T”þGÈÏ]ÃE‘¶ ΡB.¿4»)†¬û“«•Y–£ÎÇ,e„?<®Ñ^ÓÌä‹“„¿Ž„`Ýf3yÑüé´,ŸÄw[ºÄ8G àDL4vzÖèã¥<6ÛÃ;rûì8°:°(m)UER`gìÜ}TT^&j¬#/b‘dm§eÙ œÇŸfá£øuuO»~Ýð=´B(û˜U^;vŃ8™“֯ȱ£Î(×ÔM¾†ý‘xôܶ»°0¤NóOÖâmL3Âßi™e×´”ˆv³åì––%#/]L‚޼Ü厰¡Hlê!Ð~7=ÓjøqC"±*™—Í®£† ÁáPË|o|Ã)”…FgÇ‘Œ¦_bBøÕ/krSÛåµÌ>£çF7̹–ÀAAîÚ­€»Ó]¼kxÌÄES#/z¥¶×eÝ0ðMó HêÚbØqJ}™É)I¥t½›“µ™!ž"Tm¶³óUAä>6ƒ]¬ŽqœÔc8`Bü©Ùâæ½zÙ¨Cà Æ#,¾•OnlàÊTˆŒ^•%"Ñ[z±|ùÙz'+?Ù­<*š#,°;–ž )rÊPV&ìêÊŒ,¶ sÛnÏÝÃdt¾Lo˜aÄ4VÍ2’q¸ùö÷ÙAóÄMX¿$™Ë+£–ާô[þ‘&yÖYñ¯;f™Š+”ßcŒã=ºrõãƒùÑKêìæÏH„ÈánÇ+Ò#¯³Ô΄2L‹J\85ˆ±%®ƒ±ØOÿuؽ;®wyÑÌqÌâGag,¼¦2:LçÑeEÄãçN,ã¤á¾tß>‘oÛm鯙¥5 ËÚcÉ#,3D…D3[ÿ1g¸øhrÁB(ªÆ¡º²,é8^Õ s5¯˜Âa#,…‚+ Tîºûºiªö›[ž–Lýî×—DîK%ws«å’Pýóó(,EYoUeðÍÍs’[ËD8Y…B,U„Ò‘Ëö!£v²¹hð°*/Ò´)R-šÔ¸¹–¦Qä/g1$†.º´ÛÅ#,øÑ‡ƒ£†Ü'‡@»J?‘”èЛ+êž_žã2@Z¾n9wiL„Ïáå4%å:ÕQn:úVfXʇ½¸^{ÎzÐö¢Vòã`[¦ü·vÇêzXT/šÍÆß^ñ(­œGo,¿‹ô»©ûLH…¨x±D|eðåïÄ«ñåp¿žPOlÙ…äRª9Ƥ®¦Ö}RQŽ®v¸öz>¾<ÁÝ)óvØNéÇp¼;)¢8¶>å(ˆ½1ðÏ»2“ú?vºúÖÇ,ë<Pú<ߎ§íûq#,®‡Î}ïlíüñzµFN!µe±V&5Oò‡b­ð¥Óžc¹ŒA÷Në ²™c:–öQŽukB…•TpòÅÉò@WJ­øPy=½ü2ݘ÷̰Ò#,j¤¾^Þ›ð!œ¢íûhÊoÒ3c®4äDª¢>,`Æ®;[’èõC®¹Ó L7ªRðÕt«ÁOÅ”¤P×^ÇMjë)oáTøs¬ÚÏ-ZëüÝ0aC7rs‰Ôs¦÷^º§«÷2mŠu¡V±F{(–‘‡ƒöü(õæËMêéÝ,ð*xC¡„ªb߬7i [;H–§R9‡B^×ó¿;¥wV—¿ [pØœgG¶¨™åYTòXGÃmw’ sÁ&sµÅ¯Wkˆ< ”%”Ö˜÷YGòV‹|C—ni<·ìˆû“ª½Aq«”®Ô £SÖbί¾,g_¼so­øUÊlm‚‡nü?¢(†‡ð¡XÔâFŒT&]ªËÛùþüO3J;Y¬ ‹?LÛØ•U–'+ !¨I+ˆå϶ƒ*~‡‚ièœ £)àÒ§$?}nÍOh¶}È]ë»òï屌W«TñMœÊˆ«ø÷{·rfª•ìͼ)­òN/ÐvSo¬_ëò¬¾Ñh6C¢9OU¾û#,;ó gz„ͱIüuró¯ñ£3?žÎÜÈB>‰ª[o®øíAúã-ýú˜Ê¿xQhVô¿•M–ÿ âwÔ¨bj•Á¢†plXŸ/£oõsÒ`Øßf5Ÿ^éŒÁÇZ’¹Þ‹XŠ"ÍÙ ]Ù W,V6¦ý`­“õ0+ÖºòáàÄ£÷¶n‚~ʘM{ò`²ÞF#/ò®vP¢}Sµ˜ÄæÛXñÚ¸s,³TX*#/‘RlÂOÀ£y@Q}xÒ#*ùúv¸újWë4梌^lM(k•‰ðÌ"s—8ñwÎ|±¡E¸ Ýšá9t%2& DbÅbÖ˜ÁŠ•u.ì[а7]J=¹©è”ÌUçèêÌÕAüšì“§flóaÇZ˜,Þª¢pac VBµªæî™œ-B&Zj H³â6U’´ODßTX[¿w?†¸\®èã.j8Ú…Ù<‹>PÍö&ºL®zYÛ.°ú\¢’ »¥•Ÿ‘qÖ{õs6½Ýˆ´úMŽ^ì¯"áW`Ø¢f OŽ^ùXÚ6ø{mõŸ#/FŽŽ¹#7ìî¡(ü‚¬}ØßìÃ3*0i0¶ïo N?Lª<M`¨¨šþDÁx¤ƒPj'5$84©Õ˜Î-]Ô=·Z e"35% w[£yë÷=qëªö»Õ)YSWŽÝÛ›Äír)qÕw']e}$XUbŒ'Ö±m1Rßéû|lõŽ@!×àîmøÙÅùlVëFðíbIÄ©$—$Èã%…ëi·ê+oðÛþæ$Œ´GoðôÝ’Þ«süô3jPNœ¾<¸ÆîùžÞÃôôQ¤É«ÑD Õx}ßïùÄÿŽ\¢õ<Š5Ÿ&µ³Ï"Þ|0c?¢¤èLÍ=BÁ­Û, îIö0š3ꇃ«/JÑ(×6_}½Õ×Ê2¥1²lÛà“B#,Ÿe ã¹52)áÖ3¹oÓ¶24äÕ«ñm®ö-GÕ Ðzµüús®âÛèÄØ¡$çwOË\ÓÄQ¢0`h´0}$@5*øúY(E+êdX(–#/-(Ä8¦D<‡²Åœ[àçò»e¾ñd<Yãz63T¬j^TËâÐý¨¶­Â¶„E+=B`äŸcjÎu‹ŽŠD“5‘¦…DºQq{×yS¥ï6höeGŒZ«ó™—‘g¹@‹–¯»ÏVûø¹üÖªiøuxýwv³Ä‡¹÷½jÖËðüÙv@l7’¥ÞEÛv‡Ûô‹¦nö¼?¦³£â×ÚÏ|§Ç8èåèÅHàFúaºq¿‰£4Ú¾×QòJH¢¬ ¤Ñ A&ü% ƦíT „#,yQ|¡º+µiþØ&‡wj§‘hÒü’G²Ì üñ#,×p#,µY;z@å¥mãóÍs4ÑX8Œ ìÎë«‘¿CoÍÁht‘§ü8Ÿ‡‡ŒÙ„wW 3¿öݸd#/V#/ÌÑêJoìÍ^^÷‚¦X.ž5‡ª¢šEî®⬠·T‡³:€•›Ãì@øùú~ÐÁ`øóßTâùWGvƒë™Âá?Çήyü†Å/_H‰s”÷M ³÷|-çD~Ò#,eÔèÏdÁøç=ƒe²°ÜÆm5Jõ‚#/\eÚ´ñKœ" %`ÁƒSg¡2d–TK†ç|õ5ëÏ·„û¿UoÏ”ùeŸ-…ïSʦ¾g(^ÔþØTI@¼3ŠÐIR$0$X=+p_(®,·éµº1¹¯ûoVzÔºýöÇG–ÅíóFzîåV’é(&\RdPù]ƒóï™k…ª¼rmšoF#,1UÌÈúyx«å#Ètò¶ÌVÝT½ƒÛEH3½OȈ½J MFþÝ´ÿ7‡ Ûlq‚@¤¢ÍUcPð®2аp5ÿ5NÞGm3Ñ»[»¼ûØ'®iŽYÄ2‘Kóm6àö‹þýŸõ×e#>ì”Rùrñ¾#/é€Ù""0=ô õÑÓèÎÊÑ ‡ûà†Þt<$!&©ÓcºË——«Íòòí×å͉*÷iÿ4Ãñò®«y±Ö×5Ük@ÛñFŽI­S[Àu‘Ùí˜ðƒ@MãÕYÁa@°ð¤#,üÔtÖ2£–—Ü‚Q7ÎS™³%‘,ë¢ÿô‡'ÄJ´rùCONÉ×£˜êí‹€´r¸F–|¦W“íÒ¡½<`u¬ï^·XNźiDb¼·ÍyÔgï×(í«ê„]G‚ä£P¹ab‹¸YŠÚ:DÀ–¿» GA~;Zùf@¿ôGIÖ–DyÚí ÝŠCK6»ÕyµÒ>í®{•#,^ÈìHÎ#…jž1{D,êœ_âëa®Jƒ`Ä(…F¶r”/r³Å~ztÄ›Ðt¨&ëå¤-g­ÔÛ…X[ÅŒð6ÕDnïаvôÏŸÃ–ÚÆÍ@I‹óª']¨òš+'^ç¦x©CšnC{qe¼‹,#/J"\ÇoÚõÁÓŸ:î;Ô3À!ÞåÔ:ä{p^ÍZ2r]pé"³¹”8ôã lvŽ…±ÊOúk[œ_ÁF×Q_Õœ€‡>°:怤ï–ܾ¾L¼H™°'*X>£êzúÀó‘åÿÔÓ‰#£’ï?õ„}ÝLàðBI ‚Um­Ng³K(d1ëGKÕ“ÄSw’ä“À%ŸÔïÌØaà#r\/*¸û#/9Î[Ùú|ö9rèÞ~•Û»ô¨&ï#,P“/ðý#*”#*”ˆ=¿×¾hOò\·½—<Åvú+¬ìÊÿ.Š[>¦ãâúìù<uÈÁ¦°Iù¬%/—¯ mÕe-Ë¡‡aÏÙ«Õ㪡ÝìÆÀ/_ódp—?2¯w¶Ì">BzëØ½ŒC¯ ܪJ(°!#/,MÔÆy§ñj:”"µ í B ‚ 'Óùë¿›ñk‚&Ýêlß`þõè|üq^3mTÇÈ8R±“ôb]¢_“…«[Õÿª#,ÍQGh*"BŽØÝs‡ÿáË3 ×ß*ÊéE̹iãT&b",ƒöŸmH€#/ÞëàæŠŒ½#,£§2#®Øœ“§îõ™œ«¿^ñ\ÿo§ŒŽ¿gÊgôE»íq¦¢‚ÛY à3ÖÿU®‘+ûÎSL|gÔ»68Q4@¹è D.j›tW6!?RÙŽ}«eøäkÐìJloM#,‡êJ#/zdm/v–Æßvxˆf²_Z‚[>zúè)邇ä}®`] Ù«Ù8$üÞÚÂt¨›å—û~pû¿ìÔuÍp¡Ð0-wÂ1ŽûuÃß,{7‚¦f ×fÙSåðÚ¦X¬¾)â ´„ü°sú¹O4@/?Y³þÁ+œ.é$\|¿[Ð#*é þY#P‹Ñø‡¬»-HóMÑôÖç¸.C¡²›ÞßNáö|¾§Œy.®û/ç鏨¦våßbJ܉Èj]Óý’>ë'_ï>¯ß Q¡ô룶Y¡§£áÃ+w]PïœH>ûøzÔ#,šãg¯¢d1H÷ÿdc’ƾ,Õ~B"ÑYñÌ=Ñöôôë×íñ¢ëŠh Š@©Aà×iU€ìróßpn•›Ü‰.ëniü¼sñxÎ< XɺQTéî=9éý+;JkÛ~s_‘ûûñûìI¸eôËAb™ˆ„<ã‚Åÿ};0êœÝ úyiáÓ—ù8“§gx`Mj—k¶èAb]—v÷p#üåÅ]]ËAyžßÕ·¯.§ þ;3ÚyK¢ª]q-ÂB`¶¶C»¶Ñü4Y:E\ÀÌŸK"KQ”Óxoîäx`P ’…¾íÎ"”[†Wæš/Pý˸G#*©F!)qIÑfâNÓÏåïí©\ègдãós-çý˜ŠL2Þ9É+D˜#ƒˆLÎo{<8itñͰrµ“@úâÀ@’,~nÿ3Ïb°p–Fmèâ]ðþ-#/!Î#/rfžöÙjµÛëåôt™Diô¢›j¥c ´(ñ –¨/ðhªïY‚÷|¢¸ß¯?[³ G©-;ìb‚6Ö‰4d‚Û#,¯hªcW¦~ãj#,0Î_ÇÊ©!WúI%¸N¾|µ4°I³3‹ÄóŠ¿›?ûm‰ è·uèCƒSŽª8¶ÆAi*së|ÊF,DÔ3Î$÷M¤Ø°Œ^]~ìœ-¼d7­àè‡ÆájN™ü{ÈPe>HË)~Tw’ÂÜ‘Bc~=6ÃaÑÒw÷‰4UUH#/Âr[“EÆçt¾6¹æøÞŽæ"ö#*ßãEâ±ýs0 –#* CÍ%Á7Äý›i\š€T¤Œ=Ú™îÃð«…p2óÎÈzc Fk#iÄî•Ð1sNFÉ÷¯§@ÛJÜä°¿Ei˜£o޾Íiâ½_C‡Ï´ÆïO·ÿ‚vð³¾MD6㱋͗ŸlY,'yŒf)VÕûÞíRzNša£É¤ƒÛ¶©~¥y:&)Þ<ͺ⛪`תËV°…S8çtn_od›å|>839 #,fçÓZIQ³¶ª„±ÈFG­F!´ê¾°ÞüßåqmÄ?AÄ/p™Ú7ýMHI%õÁ®\jÁQ3±ñ¸)_ô{½VD¹4›a}“-±Ap"ÆéƯIÌÞj¿ð=è4ß!äi"F/cÇhí8²¿ÉaÆî[õ™M&G>ö)Œ¬Žˆñ⬒…¸ïà7T㦒`h_Uñ?´ óA¬¯úî†Jô#)&…4œü#ëÄ:*7å¥6ÂfŽŒ.†žªÅ'¬ÌIL„ °5uîP!]{í¶¾¦Á#,ôsÄ÷‚ˆr“$Å .3&=ßÖoÓj“­mÓœð;’aתÍcFm=MAbÐ#†éUD`o]h/uãOŸÈ宓¤ h&¬Opšˆq¡Í w)Œ…DË .îrÇÖDTDRÄô©å¡6”\®:`Ìh1ÓJ? q¯-<Ä|*¡´:sk‡åL†=þyÏeÏ@ÜUá*1•E‚ƒVÚ^oZ+bÌC¦AUÎUhÌX5û?@Qè¬@Ô‚PÚ6°u~{f”Õñµ3O7ø(޵jå#òÛÍì?ÛwäÆþ¿ Ú?#*¤ÀnóY?ÀÅ‚êBù·ñÌÌ2È3m$þjן˜@º#‘·ihQgbåGÃ<<¸iƒ(‘•í"Q‡f1áEС`ƒ÷-ªÑHÓy©é¦UW‡Þ©F!kj„|:ëÍ;iUâàÎÇ0)1- #*2#/6c=$Ç7jœÜÁ™óeLÖ­a$A6.”aQAJg}D$ëžÊ:S·EÚ=eépÞÏÂBå:3£Ï¬µXæÂöó~Õׯզ߼ñßD¦?’\,éÙ„h,÷g#&œïÓ[…Ž‹À‹#/#0+iÉœÙ=IÐõ*¶`ûh±†ˆÚRË0IRp´ Mù‹„i[”ˆzxž.:à‡F»/(áÁ¹Ýl^ø;Ùßc¯ÉV-S¹ÞgÞCXA·–hîC£.˜sèhr'3u—¸JaÍ–…BPó×O«v)×?W-K·*o7ÍÝtÑêúöÊYÕzÜòÇ#,JBG¬vv©»†²^æþâMÒa-pIÙðÍÇŸ_–5ë€î–Ý.éƒ+Û‘Öê£SÎ*Ë&ßVQdóáýŽš®¯§¶Lí¸¢Ró‘àpLÂªŠ¡®#*ü_ò÷2–Qc>vKU¾œOÎ _å!öÓ>Å=NÕ:ìúÕ¯óG”éÝ·¶¡qmà¦pèÔUØäíS•Ð B}j: ÈP׌Ұ;ÅÝ@{j!Y»dº¡a‰zî×wžKµÅ§ŽÃ1€7H¸msX¢Š<>>zâ°{,ÀæzHófÑ_>WÒ¥zßFãì\ Ã0ÓN„Qdj uT,f%à³Ï3™e˜ŽQ#=š÷`˜š&#,*‘Zi @6²;È™ Ã{†¢ŠEòóò×2lÞ#½Ã, c¸¹hÔ$l;^Õp‘^Ñ¥bÈžÒ‹O(Dþ3²§,v<WGÇò€Êɸפ0u¹VO)r™ n)¤›Õ¤–¡u ÍraØÀ°!ÞÛîp/ÎzDœq“ƒ†á{MdÀ~— µCt·ìçš,0p¨¨S"Ðoœ*ñ“!WTðCyp2b2£k“Æëuç¬4ImÇ0XjkT£®µ‘‘‘éqíÚ+ b!Èj#,§Ôš#çÑᎦ”oöɽªsµmÌq÷÷ôœ”´ìåsþ\ã¡kΔ }°Â±A' ?EÛ``,\;ßGéIHYz$Ìð©2SgÒëdGJZÓoý¿ÞÕäÒ‰Èlîí(PÞ{>è•cº.uYÁ8cÆ#,µw3s³0Ìܤ‚éW‘ÛÆ v+!£@÷jhê1m&pÁD5ÐÔ:ÚdJ0­(Ä0ÃçhÐØ‰ý0¨ŒÄ#,¥Ë#6PºËlˆÇYbD0Nè÷Õn)±vö~´ìÿ«¿^6äRðŲ#/2J`±@GPÀÃ.ªº½{õ· ‹cLŒQ`š1 ²e!£%°Y`]Q5C­ž[…dÍÐ1‚É˨Eb+aQW¡ÍJmdŠ£h·ÃçÛèõ÷;RîX‹$ê€àÕÓ–ë ¥ú53#*ñZ3+Š­12“˜Nó¨ôÊh¦5`±|]£m„Ê—sV÷$ïAÞÚr+q›eeé°„º,å€#*DÅ‘1è¨8íÍ‚pðvîò§òÐ4Ù•NMÖÓÙñV"tpÁÒ€ÜOº5â1”A”ËÃF±ýÇÁÌz,uèý,–g«ë|Ç¡þ~ªŠä6Èò¼„Þö޵ S¶!tm#/mD¼ ùHõ£œ¦È³. ŽTKB™m#/Ú)HË#cJX†ìƒ’£[ÔÁ¯«açsÇŸê©rÚÑ8r&Aõ…r®¹Š¥‰ÁµZ¦}òÖnb:^;QM…MølÎÁò»’µgŽSâ7}„;LØA"A#»ãQ'â+v“ 8Y)ETßB‡ýƒÕº~1‹Û&ÂôJ)—špÂåJÜ£Åâ¤cI·“É¡’f(L| Yœ,gR¯õ¹Ù(@æ Q4°…#/FÌd«lǪ#*cWéÐÖgÄÊI%]-¢à~ÍV’§é5Ζsë´ËÈkrMj’ˆ(©ÂDÄ#,Éâq#lø©.ÝŒ‘ü3²éƒ#/ß°§éÈÁ–btÞ®pš¨¬ãfˆÂuXT¢ÖžÄ±`Œ–Ÿæ÷ ÿv{„#,#,^)sËŸç¯øËæ×ÝiÄxBœº¥ri€4ùë:-#_b‘¸….U»1¹÷¾Ååð/:1±zcõ{64#*ÂTÁb%…2lí&YY›9t¦jb¢Â¬1M#µ’Pȳ"$èëE„4“€ë#®bšjŠ1Ò(£‚Þ66 “x†[ü.…ÀMH†Ò+J‡,µÆŠ) ­PÞ]°J"íECF•‹#¡FFà™"d´©0ÔV†ÜŒêÈÔDcÓ1iHÛb!‹M).É/éçŠÆïã.M3#*œ†„›ÜŸáQMæJ祃Çr+åΟŸ<ùóÇE1¤ÞEÁCJá^°òÔJXÇžt{šî¼ß:œK¬/¬÷Yîóªz §no¶µ|áî>Ú|÷NF7”‚S•"ÝËÐÏùéÅU Õúïµ2Œ£×‹Ü9ÜLá¸ãL–[!§s\†‰`¶V+²ùo.ÊœSïÃ<ûK1Æp&ݱh†MŸV>7"<úôQ·èrÐ,”$¹ NÝ®Xk|\ùŸ^ñ{¤(3Ç9§èu!Ç.󎺸Hñ.>Y¦è¤`í…fKLµíQe ¤w|«;TD¦»„øCørš›nC¾#/6_)t©òØm²£kÛßTiÛ6nÍÁ­€çÄÌVõ£Š‡‘µg"ª0–0Xw$|¤h”èÌT;KŸ ûó:»:/GêÇãÛt™1Üy’@Ê`Ÿæ™]¸‹,.%’?èN5ðÑ=ÛÝn³}‰´†?2Ä(áa0R£è¥x¶D±¯g_>x8¯‹œF‰ÚtõË÷ÆlªuÕªžC’¢Ò¡ó{爽ªcu$\P”` Çp¹Œj¢~yµy玟–`cöxÎÀöìêç‚„Œ"dhgÒèÒÛ—&U¤ˆÅ+5PÅ1{;*ݵ—4þÏ´›êdÚ2‘OSª\¬’TÂ'\‹Ïz@þ½uÎ8dù»ßgÜy;öSÝŠ09ïÅ_×_=¦Óÿh8ˆ:i |)qÍz[}¿ÝÕ/Z í‚¬`º×ã\!Ñ\~²0劄Ü4Šlr̈;·ºýjòNmÁ,‡[ØÍe˜ì›±¯S®î…#,x *¶™tƒc%hÃwX«]6#W5É6¢·-·MY¥»¬ù{MyÞµÄaŒdv–Èx±êÒ/€¶`ÐD¡’Ö³÷«£·í©µ´ÇOÄ-ª·Ëf7ªÆ°ÓzêéúÖl“VSÝô#/ƒê}CÚͤPO¼)A7z<: ýõ¾ÎUËåÒrô³Oâ}¯ßÒSÐt"Àë*.=#,_TÚnßç/k#*ÓÏu z»@ÍC†°:okª:fu°5gèÃóÜ?wï¼Í¿ÉŽÞÏg½êƒ§•$9Dý08ÃÒüó>'­§æÒ ‡³ùyº9e—¿“¹ rÐ1ö`€‰i@ š{Óƒ¬å Ô×ù‹µÓê‹OÏCˆŠ7ß_ ÓŸïÜogox½‰{ÖØoô_”¥Œ#Œ±¥ñírÄàJì#/ACšQ¤]q¢½”4|ŠD÷ËküÝ©ãä_ØÓܺ»Lè0IcÝÏÃòý’çìú¸%|Ør#*äEP-F³72²1NÈ#/{Ç rùŸº–0›77ªwõt[KÕg Úœ ܖϯV~Êãæãë¿d¶zH ¨µµ ã#,çÅÃÓñzÉSû|¿~+íŸ&bè·¯Â^­»ÄÇæfÄúu²Aàjf.*£%^y½#/@ê—Ñgâ2Óu2–©øœ“»!ü%ÙYÉÕõêDÎÕÍô8.Ò㸅UG3ƒ)@Ä«]°±Üµ…»vîwêÜÁÛ¬?ÞM" }Ãþ#/ówˆÈ zŠÞ2‡®eS:¸!61ÐŒb·¯&dt“ÃQµBN€ Ó¥Í3ƒ¬}ÿ·wêTe4vëPL_ïZ²ú¿oÃRmûþ¿·çæ·¡RüY*ªUT¦Ž¿6»ð…š©Üá õŸ®Q÷òúß³_£ØfôÈvØê‡š>Œ-ß󷥒¡E±êvذE3jK&‰˜€Í•,eí8ÌMlUýÒôvݨ£Yn¦Š”0)…ª ö~S‹ Ú¿¼?´ó¿wÜsãŸWüGPÿ(šo6ç¬ÞpL¸~¼pÚŠ`ª¦’a[Ö)(G#/iŸõ¹–, E`ÅÊ»®­Ô³9ˤü‹`ß›8ñúçð*ãÇøy?yþJa ÜtX¡EáñŠO¥Sh)Ïç¸Uq>”ß'åV„Ê(ËËHÄÝ'Þ”T@?Ä) J©‡‹à {Ò“ö2MYL˜Ñ#/-óÕËêV¾Ïó:½”mשWËxB ꂈ#/nUECÊ#,ˤµût ˜ûg+æ­Ù©ZgTÅ–ÿmVZøŠÔ#,Ò‚“ ª…IåæVÒÿ,D@'Ó- ZWüÊàà¼\É¡¿ƒ’èZ˜s.\e—úå§ñjÅ‹çƒà{K¨uc BfD%ÏyZØ¢Âù ò6·ÀlWoÅPuˆùKJ"K;¡|Æe•ÏGOBäq(Ê/På#/”Š#,«©ÔÛËß™ÏòS­]èhl§­!ï ¦é$<5ÂbŒ9¤À§²Oò¥®+é×NXjÛ|>úæòOš>!(¾T(`£ î¹4ãU1R(¼P &ÂdÜ‚ÅZZ‡eÖh;jÿá#,S8êçt¿¥Í'Ú’èãÁ¥œ(èeþF’(pMÝ(¬$*áýv¢,QVÉüéI&Ã7ìÿåĨ {X)::|¾ãîå›kþï6?IæùíþæýŽüà#ìíú~Ÿ¨Yëè_'žgÔy¡ýÝd…¼Ao;¿_³oHÛ;1ˆºØv_hþØðµ63Àð=Oý+³Óòh”Ãõ¸ýrÈ¿#*.øÄJÀý¦¸-‡>p»èGád?Gx}¹wØÁ¶ô“n‰#,]ß².˜€äAÉ2G ƒñw2í¼_×e´§1”‡9½Æ…|tß4½íùÁGåÝ|m6%¨X×Ì¿(§öÓqãøD;‹/!ÖåîÿHðÈÛuVW?÷j¿½ÏÔM—r¹+©‡/ç¤i^4ÆDÞUHIêžÎ¿žÜ¶€¨¿•0c¾€ô÷^¥ïPÊí8jßuÖÑnv5åã( H†T9ðl+œ±pf!žƒ†3”Ñ"RXfß•‹´¹ÎçÕGûû/ãTYÅ»Nœ#òÇÉž¿TÁšW‹§•À馛µlÊï)#,¤)#/¨ó°p¸X2Ö@xä—T]Ṉ̃)iYÂÅ‘ØGÚ;ǬOꈇî÷{¶}zØÇøƒÈR(ÿÈž†ÅãMhª£”¡‡÷þ«Ö¾Áˆ¨ÕbJ`€”˜“Ý:ü â“ÖœV'—Då;ytí+,ìÙ“¹˜`)‹©l6º8•ÑR48¿NBgÆôÕxˆYþè–A#*¾Ïó䆕ûûç¿­`FS©v~>} ë¡<®—íiÍ)fjè=WX›2²ÍœÌ/!@W¸1:T®‰ ñðÆ{Å=Ö9@ý°:† i9#̳¦sX&ba  ’„ÇiWx¨ÃWâÁ÷aô»’Á„•Éa…~B‘F±Â,åå$DF¨ "…àý*©ë]ˆiçþÿ{¤E& %Ÿ Kbø`–vû€öûÓ*ýõOÙF×JÔJ&,«3Ç馬´Õ… D”U2ãb#}=©ýcôw0ÏV6ëÍ~_ÇãŽî:œñ3ÆË €ÄŽ+út0¶j ˆbWÖ¬I®˜—¦#/Õ áZÕ|2âÄþ®žOŸçÚ«¢˜ #/O9v‹²´´ó«xÓÎÀO¿4»¶ž“ÊþÎ<ÿ‡bÿ`0ÿ-¬#,;ûkúA·óòêC©“akÁ,–0¤´… ”À-`!,òO)#*Œ˜O$…AE@7ý»~ó}´„ˆ©jù #*£Ü‰"‚ 2è뇙˜±Û¿·ÿÓ³Çêû¼Üôø¾ï¹Çã6né—ÛÑñ>êe©)³ëûí¶ÎNOWé³Üìç쵂½vºñ§Õ1¤¥«]çEË]Ž÷2-‚~þõï÷Ï~Ûí±ù[£³_ßÛúFi¿wËN_«’ñ W¦1œ´sh›#/nµíü¿ÁùOµª\-ó/§½n_O=ÏÉõh¥õ;Ü5û0råŠû¥7ùH´x;wχNaïÛíü;GF±«Ö[öf!ɧgëýßkÏŒXµ.FO‹céÝ:ËVΟV· Ø>/¾Þ·ç¸exÐ=rañvÉ)¹=ÿÎ_T‚üèô ó¤q#ió}þ¨g%ÓäÚöêϧ\§ÄÄ[Ž<Ãï׿Ñôyÿ­ßœÇZ–¨¦êÑŸ»#^6ûí¬øáÔ¼¸w_ì²mðíòA°…úqçr;¾ÊløáF3…¶xÂNþª8:=ÿ6Ïȵ§£N)Õ>Ïë;ci«jÞñÕ®gº¼û·P¾çÌkXõ?¡Þgä-À-ÄqG:>ä±»«ã;­0ß‚ÙÚÑØ<²s¢E­§Ÿ÷jùÛ#*n²Í’¶ÎØ›l½€ÝϰƱÙɲ˜—¦Þ,>èØ9;¼û¼Öö¬š¦xã´[·”B.`±s6ºV03/{ž®iû~G8˜Ù§m’w/·Ÿ—öù¸óáçßÃØwn&éc½Þ’%ñü\#]ïúïÃÉlxql÷í¹¡æPÜÅ-“uÜz÷Lpã_}ëÃãº{Ó­Öq!ÞŽ :xA<f¬R§»™EJ¸lÿƒžnäø½;Î|¬±®½óì${¹5Œ”u+¿cÆÿ¸&±Ÿ£Óн¿°ÏäóùGÄì˜|ØŒö_IÄwrfñ]ƒE²öwï•ÿ`úy(;ב. 9-íÚúvÚîÊÞ½¯¿#,¢ë>¬ òª¿Ü¾*ìÂ.õåÁ“íáý<ÒðªwÃ&Ç‘v÷èûƒgé8¨ ­ 5½Û¦Ï?Û7‹ô¶Î]8Ë’Ô—+|C°GE?NþŸÓ\}\aï8gjŽ¯æ¢…4Þdzïú[ðÛÏŸÕÿ­væ=ø»ã^Tö‡Ñ h³ôkÚ]§+ãŠ'ú…£ûs«í¾#*I/üLuüÏÕ„zùG'ÏÏý7g#/3£·àï£J,@—1]ÁGf]ß]¿¡Ù#,Ú™}ë`ú¶qwÕÑXÙ³ã–s³Ðõ±£’¿Æÿ¾G#* ãwÁ¿Ï²3ÿÐÐ×úsÐAã#/isÑɇ3<ÝÀy.çòƺïù~/ñ­Ÿ}–~nmOO°ý§è?_Ú߸êïÓ·}¸ñŠhî~Ÿw’µ³öZJN¸~¿¸"¤+èûz3øËÎÙ4»<íþ–¦§ñù?(>5B¨¨›€W*¢‚P¤Å]žoÂËÈ/ü'éñÉtãûJšÍ½W.ÇïAf,hB¡€PŒ¿B,u*HG«›àÑ/€ý¶å#*€¢âôX}vj;ÿPû:Ò¬W$Ÿ“û¾ПÃÈ:môö#/}{¿…ýóê?gËžœ;sðò~bæfÙäìØgéžÇ?aßúˆî¿7'Ztë×¥uìøj¿ŸÐjBëЉËú—êO‹ÁA«¸tŽÎì ?Ÿ70Ü<¾?-;ù{#üÆ¿Ñò;¡G¼~#¨w8ᜲ·É(üÂSÇšeqú'²™¯0ñ£ù?CF§[ý1¿ŽZ¬~¥Dp?Í~ì0ÃïoáÁ.—¸on)án½Ýãô¿ökݪÙ߻箷#,ÉÇÙ«wíù¯ì°n#,ÿ"t]OÃ>¹ïŠeÛ)⸨ýÃÔyϳǗZxîa´yÇ8°/XþR@Ö$ OÊ#³Û×ÑËÐÊ> û’Ôò®QÍÏG*·ÂA‡ÖVžh¸#*SøÐmgîåjû‚B˜'毫¿Ž£gN•çñêûpæ¾E¿Öú=<ýX;8r…ÿ“?"ó 7Ño^ŽŠ™¯åaê•>rÅ&åv`ú0ðæ]\îýÓä¬É’ü‡ÆvÓÏ4Qô<ßÏøa #,#ˆôrž•QŽœ<ÓÝölëéÉ×óó$µÃ„†Æ 0=òÆÁOŠzf‹U! ûZ'Ùdܼð¯áE¹ù|¶®gXí9®ê/LpÊ׃ çõ-ßêLZOò8,†È¿“#Y^‰þâ'¥¹ƒèšW£M3¬±•ãä‡/¾â÷g+Ó?#¯€iPÇj‘Ö̧×lpzüê%ÙÇñãDºLùhâ,༉tÌàI,uü·‚ÔtŽ›#*‡Ö›ÿ_vzg«ê·ÜˆÑ|=Ü?PÃäî¬8´šýÏèp€-Ék§ƒ¯ „W´y]1üg$ëejŠáÏʲqŸF|]{ì"Ÿ*Êm#/‡- NÚØÃââ+Š'ìnîZåe5¬mŒKÌPŠÔÇöÏkÍÞ<yv\Uõ®½¦¶yô 2ùÌpòd65;™Ñ©²[-ãX—Tto®!Õ´P#*ƒºÛl]&ÞIü}¯³Ü’­ºcœ°ÃJ¼6‚–4À½³#,¯J#,M‚ýâv™[A¢Wa¢|‘W#,>ŒkÅãWÊ(ñõ™/¥þ[ÝŽ»æM¢H!%'q!;5¾ =ã¼ì=;@Ó¨:Ræ ns1`*çíã!H£ÌÖ4WŽl‚`@jâ>oáÂ#*‚«ÃâýÖÛõò_ØþñÍA¸wûðì>7­ñ‡#,‹dWƒy,¾¦ s @±#,ÈÑê ŸtDhê:lõ$7ISQEG˜[Ö“‡ÓN÷BC‘Gv­@VýviéÑg—òøÛ³ ¿³ò„0zý_iÖZ<ŽÑ=õø>t-Äôé&LÏİ>2àÍŽó×±{ñù~Î!ÇÙò²eäö#,ÀŽ)“ô[ˆÅç¸j?»Û&ØÃÒy]çѵv¸Ñås?èÃéÉ4ݦýÞ›ý‰ê©LRI͵ôÇŠUòuŒ¤öÆ/ulu³ÜYÌrs~qzúñÂNïþyÃW¶£MþÁ ;Íä‡(#,©%WªL#Ф’-t#,ã온þÿäÉT§>™OWñ¨ƒÙ%<£æú½cmø4£#*þÎylÁ¨6ÇX(àï&­4ÿgÔƒëXQÀ2§©QÈÊ¡#/?ˆf@ç9œs×ðwâó®ë1¹[—JåxO¸cf¡ iDlTŽ Ž`¢´T¢M;b4CC™ÈÆ4ž%UiAÆàQQÔÛ`H^íO"Cf®îSVe™ªŽ‰B!ÁR]”¶…±Ø£¦¨ƒšÃŒ4É)5b‰¡¡º¤µY#,X­‚0Ì£m¦© qEvz²iÕá‚aE!Â2`lRDuý:Wz®®»‡%З#[!Û¨´%~Ø‹`äY6i´þŸ²÷[Ñß"+œ8ÎHÁ0#oŸöù‡ˆÖ¬µã²ƒy…1>ÿð–†jKQgõçn{#,± »‘Á¸#,+S#.¥!„Àãù÷qý¿Ï}ùú|_ˆ3¸EäÏg™M­+h1’ŽŽª‚&q‰Ë$Ì\Ð"JL#,ÉbRTb"aCV ±6Ç#f’J¤ƒÿLˆ* WI›}~3¯ïÖš'¾G—+–v¨¯GÌšpíý8÷K¨áƒ#^¬©|:ÈŠèx¸k§a¶ÝrÊsÊÕ®Á—6ë<þ÷Ž#*Ž5›<Ý_5†î‰Û·?·€—¤Z«×åÃBþ­Ò0êsþ=\œ9¾ðÐNQ<ÓÃöÿ~·;>¼?nR?ÓÕ í¼Duä,l¹.ÃG螥”%öJ¯õ<EÔªÁ¯…í²ëpú+¶:Jß÷hèÉÝœŽ¾1Qx¿ÚPò@8h)åpÙŸŠhH$‰ íÁÞ%Úìpõx{ÿoæ¿w/Ç«_»Ä¢Z„yÊñ<\h5U6ú88 m:¾ÏrðígôJî<>!Ó’óÇg¹y´ ÂÂwÿÝûŽ.s™îWZæ˜aˆ`~ï ìÆ=á·E¦å2þ¾_ÇkOËM¾fÝý÷mæÙ>bmÅ}ÖþéïÓß1l–@L/î‹í   ôÏJ°(¤}èüáìÖ‹ŽûNó†Ùìæî M­y­ÍÄÃ*Q"·Ÿ÷ÙªGŒb”í’ú»`“ZPÑm ìMa#/Á³ݾ\Ûw7ždñÍfR¤ÙHE:P01CbGVnµ…]Ú“PÃUEöR6bq‹ Q$E…®¡‘Æ•re+-Ÿ×ª-"4<åU«œÔ1¾Io:+#/•³[(D±R²’`£$éÚN3‹Y…#ïÈJ”¿³#,#/ãB742#,. DH+F"•‹Æ^“K®Ê¼¨-F„nT‹ 2KbMo1´áj-!ñi«Œ®!ñI‚Õ-®kD´8ož) ¢#,­”i¯èÂc:´´q½,)׺èg)‚œjJ"È–Ÿö0 ÝC‹OÅDloJ£AiP+Æ¢rQÕZ ÏÐn´UÞ™QŽeu’‘ŒcdöÌèüÒ¨çƒ<‚½l8šm¶µ©ZÆ2R„õaA‚¼–#*… Èij”6(ƒD¶; .ÞÓ‹ (+]ÆŸ€ÊÊ×þ#,ËÑ EØ`XÚUëKE®{yÂØ°tꬿø{“¼Ì|»eôª)éÕbèîÏêü,Ot~_©ÙÙ¤ßë¿ÑM#*‘-2J§‰çÿÏ#,H¶¸|°úoWggÀ{¶tíŠ …\ÜžaŠA¨÷)ÿ(ošóLéÑŽe¿ ýZŸ¿ÝÝÍytŸ-ñؾåùËõKŽ˜ÈÛ!!JóyW®{)ņ[“Ú»m4êìÛÚ~ž¯ŠBDláþMQ$ë÷JÁÚœ»¿Áq²­º?–àèuÕ5+ïzȯZ|Ôq.³ñg܈Ûèü´ÁÙÓ¹ÁÛÚ}ÜÊGFþj >x÷ž~Hç<« Vé…§/»Ò\ËÁAëf$’ç*«ƒ9t`ÃíŠSÌ(P@fä³  Âr4zVÒ#zz™éª¡DüǨæ‡êÿ)Èu>€ìTWÒ÷‰à5ÿFߤqÔ¡Žs¹Îì¶Îh#¨îÆ,óôô¹ô¥óm¶Æˆâÿ­O*b“õ¸o8ç¤õ1í¨%ççì|7ݨƆ ãÔ\„køíû›‚2!©QH6 ¨Ú²¯q›$4±§’ðäx¾ÑŠe¢¦*·¹ä“¼‘0ïà:¶ììEÿ6 4òÑ×/mLúœœâCÚk\>¿^§úh¯5e2Ð?x±Bª`¢¬¯ê•¦Ë›j‘±’Ädˆ±#,D¿ŠØþœºo6Ñ/ŽÅ# ÝŠYdJ©ež¯T¿®?A5Ÿ/`êü¼­ «~#÷w|ðó¼oŠ”#bÍb¤±%Îß›ãëÊûµöÌÊìÁmêâh&7pÄ`É24U.Âhf¤3уh¦b\ ÃSU#/6EÆ*1 ±„D'© cÖ³{è« Á£Pdi°¯$`Öpfa”#/6Pu13 b2WÉèzæÒñ/nF&˜W»h=ÓxŒÇ‘Àµ§G]:ý˜VŒAØíã”6#,“qV5U#,ø0Í­X(ÜO¹jcÄD³vçÈ[ˆPŽ^3#•DsV‡Æª+™6òtà ªë àFݬt²(DΗQ,eP)*(˜-†Ó‘2ņ a¶P1í½ƒFÅ£¹v#,uiNÝ‘EÂcm'[C®Ù`Ø2©º%Èe“ÓA,éÔAýŸìQEkN¤¹Om×@a¯Nõ.]оãÏ/^AÖĪƒm‰=² *ÛÍL<ní ¡qŒÌüðbÊÂBÒƒ§“~½?#òäþ÷ì"R€…*#,½7mãÅñÚñ›úÇw©B¶¢ñâ?Î#,É#ÓøhÐâ$¡#/Ze2CÍAO›¶þpÿps«„#Ô¨*ÌïßÑÏ4 ŒøÑƼ¦ìtÍÒOW/™£Ú õŸ€–[4óêôâ:“© ê´ír¹g\¹#*ùǃ4FYd¶(Å‹ JªŸª•T@Á§Gßw†=سòàÑÄD\Üatá¥Ò!S§ã1QEQ#Ȳ:‘RŒ‰6TÂÌúìj·L§h¶š$vD­´å;ªîŸ/¼:ÂÃ×®i¬KÇ‹‰¦øz#/*ìy®½ÀÒIh•·¥¢#,ð¨ÁÙc£b‹€³#*ÜçuuJªÑT"ÜgÏëú~Û;çQ#/úÚ¥"“p6ç*‰—ë0Ò†CôêßþCù<þÜïÙëø¹ÿ‡ΨNY;ßר_ž¾ñš|2ïòFŸ£­E>õù¡9ŠS_„#/<?5ÑÄš -+A‘¸·B&:;Hž¯§¥Aœ°åŠŠJ«ºõ7N»ˆË>‹¹Ž®´Â@ƒÌimÆßZ¨ÊNЮ£ªâl17$n(ðq°ý&nÇ”huA¶œEtn9â¥èrDcxâVDi59™¢â‹g3702•SdˆÂ ˆâ„",š0,!L¬À` U;‚/‰% #*PõDŒ¥J31› ˆÝ9È0;-äèÈbæÉSG g*1±ó!¡Få]ßÍ«[jMÄ‹¬’dTtúå6ÁuhU›@p.70Ȉ›1t¹ÉŒV¤*Êø°4µ#,8´†˜úž1Ôf¤ý…my±‘Dâãp+cvÅ`j0t¡–H²ÙdŒaL„¡&­q5¬þ«Ë¿¡výÜÅîÞ ½ ?,t€×~ŽXŠ€×5\žðCªøJRsâŠ@äEcY ª XˆÉ¨aFòÏOFh&Rcõû@oÉŸ/w×Ëf”ÊáÐ¥;ÑI1iÍŠÁÍŒï£É¡ØÆ*ë{ ®9“¿¾lÚm¿i«=DLP͹Ì4³·öÜSÉ"¬PˆÕAm”Åëž1¡Nj—Øî#,qs4Õuë·æfÛ{p„'”ŽRãã¦øfFÜ›’+[])n1V6«XËið& ƒ$M·­É;û#*ž:—i™£_%äѼh½ôµÖ§®2¬ejˆcùbÀÌnpdÜ…2Q™6Íæ)‹ùÖ|ÑW¶¬Íí§ Ö>Ë¥?^#,ð4cM¬ h¡$Þã¢ã(gÊà:< Náõ(Œ¿Û§2[P™›XÒmŽ s mt(qŽf8qĘ´æ 9‡÷~òI ^8ÔA"û\hV;%d¾·öE*Éà/§KÛÖœÉ,êÓíFIîŒÞµƒÆã8o™–.¯”àų‡#,¿A¥ƒÍA#,¨òpŸ¹ŒX8™¡·/©© QÃph-36“1âÛ¾(¡}ÝsµçvŒuk}×{ gMk¾¼5.¡¥±·9¿[¬ŽöªI,³RIÝ÷9Ë=;3™#Ç-Ÿ`§…²Ç ƒßL¿S-¨¨2C¹˜äe„#/¥(·‹|âÁ7VÖ»WEùÉuh̆·[‚!B ŽŒæC‚—‹6èuÜQ¶ÔvtNAY7˜–JÇpÞ Nq°QÍ峺jß#,K¦.2a?*#,bÃ` ;mkz‡F>+¤V¬v„NŒSuÕ×ÌògeËÌ÷Z[ò{©htkv8Õ¹ÓŽ—fašm– -9мäTØvŒßg$Ï9D¡.™šÑ]®íaZu `ØåͶ2rH'’mjM ˆ0Úy›3]ö{ŽV6&<t¬[ô½™¶m¸ƒçaú̺߽ØzwÕ ziÚ\DïìÛòñÁŸ†VP§]U/ðªB’{ÌxØ÷ùí–ÔåÍŸU½äËݑƌD*£LR¦«mºJÿ׸ȓ‰È‰ÆÅuͦOÔʛ߮7œîùUÎ$ý˜¹®;®Ü\lÔ-Þe“›Öt|:ˆµŒ9RM|Tal¦ã ‡Fk& h‚&2Sn—|w-ai,‹Í=ÉE¡N "wÄ!eÌ*>{\˾iá@Ò‘^Ù¶§(­• Ôy¾¡0BBd˜wæè¢Ïú=-ºtwI^ùó¬:&†šlû^å†4üÿ°ö.·×ò„±É=y¬+ãÉë¶4@úŽˆ4ÔÅŽ.÷›ËâÇS—iÑÕim;'Ây€Ô= ¦åœ•²ç8ÈW”“í“_ÚŒo(ˆ|¾óJ’Ë¼Îø6ò.Î[h*•Îg¦˜ˆŠAf¬Ù²Jؾۓ¶Å\$Z²(ã9j/xdîØX§¥…âÝ*I7ª˜Ú#/!Õ”e«¢×¢mÒ¼…êí›j¾LÓÛ“nŽlnFpüªúåÒÜ-ØxŸs¨ŽµZ}غ £ÝblÓcMæáZ­oÉaF3Wã±f½;àjo±Í&é³MŒ-…±T ëŒb[LÑÅÔb0WVše(÷Û[äîë$âè'½û|†øKëÃyÆÎë××"M¢˜4d¼¬p,q!Nzµf嚉œ³¦®Y¼F&%mþ ½¨(ê6â÷fü[àC-|#/½›¨ Þ¤}}~ÿ¥áçúqÖºçI„‡È÷gtê¼*8z!iÄ¢“pò˜J'YB’R±Úç̉—q¨ÏÁW§ù_ô?~– §P‡_{‘é,œ.´ñó‡}aÒüM=ÀBiUSì5›y=\Â4•Ø[ö¥XnFW6¨±^h?€7xG‘o4¼R}^G;r‰0#/äôýØÊ˪ÀˆŒõ Ú_ûú=Çü)zŽüÜvx¾ªáì\Û3å>;Ý¡x†|n×s Ó¿Òÿ1i%å$ËÓ3€#Ûû|$6§ñås›Ÿ¢gfõ 뙊aØøD»–@ÏI”4ͦ‘g™˜Å¶´›Ç#,µøþðÓ¯R+,;òþKâ+Ž~Þûl@!EÚ‹1#/ƒðí–@ð<”à πÏúêÝ\Û± ŽQ°0L÷¼<AF€°Q¨#*„:ä cáb€x×h0¬¬¶Oë¶v ‘õ2Á•°9n(3ƒ=ps¯´ exæçèn«‰ª‰a¦ÁûF “û#/^ÄIÓOA[ÖøŒÁpê`”5‰µ#/i~¢ŠÇ {Øü Úìtàz\þ‘vÁŒ¡Öñï$| ùå§³´äÍA#,D¡àFìØÄݘ‚ò`\ e¾R`?‡¹ÉN¡Î]ßë¸i8Ho0;CÏ=¿Ñ:6,¯¨YבD `ÚóšÙ‡ݲQÃyg²)_ˆ~-'4æ$(AFó«À»½Ü!·6&iX¹Mµ×½kÄž?¦Æ­3Aòa‡vÊqàkì#áv×6GÄ_.ýúNç«ëS¯`‹ÂÄÇ%>Káß“ŒÔ|<;™nJsÇÊèM±ÆvÂZ‹"šbMVÊw05ª-V:¯=\;µç¬”„*^‘[ Ó-‘/ð‚¡>­Žì¯|ܱ( ˜Á@°@"oû+¼¹õ¨#/+r-;t<6+4羫béó†™õd*w_‰GÀVÞÈ뿦Ó:#¬ð©cSO”e$l½P¶o÷`¨ù?|>ñmÜÑÛêœÓCó_'ÚH¼Ôѭ솸ɻÊH^ØÊ$tø„Øt‰ ç0/)’îímç0´ì¹:¦¢NG²>}„ï&½Aé’’zê½PY±GvqamÙ1]‡BLÆrLVzž™Àßs©bãb=.½á1#,tß©¦´MhA»XŒ®¬Xñ¸]g˜ñ®˜Ûiþ–Fkl"†œM<» Ô”£ï¨žœ¿ºoFÅÓ9gö«ï¢#/™õv”ˬDBwòB˜Ä¯nŒÙ¼ºüÄZÔºXðÞ ØköcOzú¹øClô*Rzö …Äœjixz9ÂÆÌP\.Ñl©:ŠäìstC/ÉÞøÚ>͘4&]I!ŽðG#/QÓ ò‰Á=+• Ÿâ¹#,ÍqrݧXŽå“OÓm-&$vÛ#/#/M(ÂcÑAF1DÐuazë}p<3R˜tZ€ýúšÐyG9ùe¾;eºôØè±±nY,Pʹ®#,U±Ÿ÷#/g-†Ÿµ¥ÃãX^˜ŒÈ[Bì¼…¦y©Cx=}ÓŠÁd‚1 ‹y½alt°Ÿ)…°Û–{Ñk¹ã͆[ƒ¶éËk …ÈÁ…ÎG†s¾Y¾ ,ftS‘èm‘¶…ÍÒ[T%¶ôë“×ÍñàbµçkdžäÃýÞgôñMÅž¯ÉXpvêŸªÌ …G_•-_Å#,ð¾'O:òØгÝàRÜrúLgR$š.jXóµ©*–éÞ*o‰X&•®d„)ÿ4™„ãêÜGg'/ÔõvðŽ$vÊEÃÀ°´]ÔYK^< yÙîÍGàWí8ßvRtèîéƒoÙÕóh!]¼áAR¿d^ (õy!ɹŸ·9àÀJ¢ ølô‚hzÜÂí…¨ê’Ò €!6ýU#/­4ª*—ÄpÔçOKÙL%«´ VÍ\)uC»u‡'aí=ê ˆºdi¯ã]"óéþ„>ŸÏ®ŒõŒ1µd,t«/7ó\¤NǨ²…§¬ˆžA³66õíñh”}ƒåÄuÚäåëµT”¤·Ô÷@y#/>;æ5ìÒÕ bÒ–¬ ó,¡ãm/|WX×]°,§V©O”~1P;¤ñ^'VKè³óP;ñÃÉ!Vº¾i¨Õ¼2M÷^^ö:Û|“:ÂgËòlù[@Ù¬æjwr …jrGEÓ/•ÇAôµº!ý\”N†K#qb̸ÙGG‘šÍ\fúBºtå e6(àJézétÍ¥æö(áZG¯®ÖIôïïÛ°€Ì€ jDiÍnMdf¡[ Ã#Ö¸EŽ5·A¤ ñmÈŽ‚(ꪲ¥¸Ù*¢ðЛ <f›Î½–%'­»C¶”?”CNsèõ5õí±m³†ë¢Õ˽C¼Ì;wìdp—Mh¸³'ºiÕôFǦ´n¨ZãmÂR¡ ªœ½Ù°¬å§Ci|#, ¨ÆY—=5xx#ÍõoÑúÜ ¼Y{;ˆÁ‰ ã6)4jO'9×%ž“6#c2m·}ù’Ý3âöŽ."[km³èu¸}½»Zê¾/&û„Q«ǃ™è¸­›Ñ§q}M̘m¶Iö0ŠRûÖO•ÞúNÝS¬:ñ[cu¥1¿fa­ê‹ÇŒ"² [O2,ÕèoÒï`üyÓæôšE9‡”'æøÇŸO(Ï~ÔDwr%¶¾B®;”fò]Ʋªà‘eëg‡ó¦©Ò_=àÖ}úç¶àHÞŽ#Œ9#*»TµöÍQ<<§éŠØ>Ò5ûæv66Ìg_Ã1x±³Œßð#,ƒFÏv‘á(Ž#/äo‡©É¥«p¹(VŘórïøð9erþØãˆw¶j¨Á³}Ñæ«²‘͈§ó3|N>›HÛØ¡Ì#:–E¦çvÓ6ͧn'jVËà±èˆ%ÝØ‹´”Ùƒ›Áó©rñwut¯r(zµžÅðûŒ0ßBþïÎ[œq oF¼Zhå"¼Çáq8ÕVŒ¬jU°¦¡ jïЉl¡ü¼ý#,§lo´ÈšY<;ö‘áÈÛÎZC-lŸÄÏŒSxªñ¿n¸ê¸Ù²>ÛJ`ƒÀšt©aÝÌ–x6·ÆÐâ«Ë#,#/[ÖÇ]¿^ü<#a´tr÷(‚y×-»Š Ò„M@oÏÀÈ8B¸†ÓÕíØ^§‹Ö5¯’o·£éW31’ÚW»³±EŒìí³Läæ4e³8rz;:™ÁЬ×ÌXúlðf§YÐ#/‡¶‡†e¡>ܱÄ0xƒåz½ˆÄ<Ÿ|OÓ;öõ‚ðÛЄ‰Gw•-OlÑ`³ÓÒ#,¬‰jIw¢y,ûÌ9Ö—V×9ÿ!h)?-TyžúI {ÈR#/#/èAãËùÍ¢ýk:N#*uœ…Žxìý£f/y +#,pʳ§Í:^\«s–ÒŠ#,õV±õë4¤G0X¦òÒɰô´%•ƸB˾ÂÂitZ×YƼŒ’Žû© ¹°gÛË=7Ø‚—5…Ù0+UæoÖ ž-[l䣌BÂñ<G~‹³rؘX<û!¨¬Å«'\Ú¹nhªâ¢c`(±û^Žˆ­jbêã_#Ö—Dö²Ê¢¿éï±#]¯ë£š°åÓ BRË*äQÆøÕ×®ÓÁøÍœ.¤T௶º&V¿~PªØ#l-±¿Ûß'ÅfûxœE./UßNÑMªW’qI\e`!ñ³—Œï¶^úè­öºŽkyaÉmF¼sžf]y`Ùªù’q‚(rk?~£ç¦y½º_5–èË™Ü&<{l¾c1„±R/5>Ž}‰ „—•{–÷ÇïÇíÑõ¯—aÚ©°uàúß_Ào+ƒƒÏ›WÎÄ(ÆöMt¤idÅ—A\”Okéàè¸Pe…Q»’ÆÔþ¾‡—Zãú3šÄ]zH•¿‹tª”x[SÊ(E.xýpü[Œú³êÂ×FNv÷©ˆvÅò²MîÑ#*:a…Ãz¨²üì“åat¬Ž¾ª|Â"C_5“ª/ñÊçá£K«Û³;9ˆÂ!ÌÕÕÑØŠ¥´sY²ûí³wÏŽËA:-J0±š/óíΤx£š£×σ.Ìx¬Ñ›x¿»ÄøÖß_ÛïŒk0Ã+†š‹ lï×Ã!1##%}˜Àè,|äº\ø‚³UÔ\ØâÌã¦ÑûFç>çÜ\C“Ê£ÌÕa{ÞºôQ´d4´‰äsÝ#/@¸t¹åêøAúõ6Ìc=’¤W”±ßº.ŽbsÓRb)¼‡3/#*ÇLXYc<÷ê²yØê Rû™ þ+LXXe9”6;­´:ÀÔ9„diÜE[˜OƒËÝÑøn™}2yÞé'zˆ·,Ƹ™0üe³Á³`°÷»Çì뉜۹ÝçsÚþ•=—[_6EMKðõÁØù27Ý: Óé8w³¢âpÇð²?Uש-'žO½y¼m¡·ý¶WiÞ#/–~G¼2)¥Ë+,˜ÓzöÌ]A ð(F7"ã€c›ÅþµÚMå§t»á#*tý±#,]¢M«’ÐÊìaM+â¶Î'zÃuöߙԙßn*KWDþwÄá}Q”¹º@:H·5WÜÖÇ0¬ ñÁDßÊÂØ÷Y„6tÚüaäV©äQ„{øÙá=#κØ;5Y™®ûr/j´…:ÇŒzm&<Ðþ9Œñ‰½ñ÷He{Î?>°Ç í÷•L¼‘N™ãvPµ§˜Ÿñ¼õÆÐÆ»¸ë·€ô]ÊaHR0¾ß›KÜófWãMÒ{ªØ¬´xÍÅÒÑK _…_¶/YSQe`à{©(êJD8ÉÔ~.zóáx…#›p|œ– ‹^BÑtôÂÇãÒë{Nvì#eiˆ­3ÅÍ "Ñ/¹–Ž‹––?a‹ê¡RAÜÊœÍ|ÕÈïÎR{ñ:] W>YôÊ€ÝâÕ9I9°ša¯\EE&’Xã°GeqçÑ;yáòßDÔä–òYD’8¿eK#ÉÐ%g5¹©o7ÏžRÚüòbœÄ-3s“ã–‚>^·?ÛÎø£´o²)±4ûs²ú¾1m·fA3¼ß€«èéÎ6)k4ðà',…ƒ#*µ¥cd²i*⬑C¡kXZÍæQ(Ü…"$xÁG#/ ]×K§MŽ×Éd¥k'0î]qBŒ/šÐòZ¶Êª6Eß²m-Üs¤œÂ@Ä4Îzj‰À‰L-¶êXÁÕáÙ§@HŽÍp¬šÊáÕ®·.ë+×aõß ÷‚GãªÖq*^MkUt{]d¸Ê{š-z®‚¨t®6b±,ü#ÓM˺iY\jQ•óÅIJ‘#,P‰mFcËKtÖCFæ€ë1šƒRê° ŠB„r—æí‘Ÿ"àçò;†<–ÀJж˜¬#hXFêgÁð}ËÀÝÆâ#,.‹ß» Ÿd/3–Œ"÷+½…C9H2ƒ¸4&î““±²£u”Ù=QWç 9ϬM«:æ‚™Ö×óôOQiN®´¹ÒáƒÁ½ÁšñN–¬2¨•f'HÆ2‹´­æã}“¶R´&NÔ?WŃšœÉ—¯Ò¤7z¹ƒÉ@ˆ=*M~xúYguŒ÷Æø¯^‡®G;á±Q‰Ë¿Ú—nO¸r–_˜ÁOí{gÏ´à<Nß ˜ÇƒÆpZuàuŽ~ÅÄî9à^¡nü¾Ë*6XˆHZUÅ뱎߆X¿pskÅfk¿4Gä³g1#/°æ5ò=c¾Ž#,§S0õ•©¡DG-9\)-aƒU‚Ëáu°™#/ªª!%PÁÐÞûð”Œ<UÎmX=e~PI¦ÖQaç¥å®e´î¥¦ ¬î¶d‚ |6Úá;„jîÊA¬…)ãy7ü׎Yª§ÐoÂcÖ›óÄoKi™Ú§ek]um*{CS™ýX†A8ß¹#,<Ý?'%ü´øY«œÐ/ª÷Mí›C¬‘Á®¹j)êô K"mv²rЇ_ŒC4ãïVf½ÚÛSö\ÃçÅÊp§j˜×Ow™¢WÝǵÞdÄÛ½&%rx`õƒE|øœ2ÒÂ[>*¦cÇI™Ap:üúF¢ïœ„Kþ(2S=I´ç#*,º-n®ÜÖÞ÷J6OˆÎBsQecwcuÕM‘–“®•nµ[TJ`MrÌ¿4',X“Í@éˆ"ᵑ ¥ ðû¶³ðÛ#,Ÿj,4|>…\xT¿X´½„Ò•[úì¢ÃÔ·…6sççè¬#à°tŸŽ'D`ý7ï‹ã9dÀA»1¸ÆNuÝŽ…,XÀk±Xª|dt¾øªSÏc:1S;ú ×¿.W˜¡#øIuÏFîçžç&ò/¶‚ÝËç ßÏ+EÌŽ‹áŽ¿d¥^fºCf­3ÌÅ£:ë´ÛÅÄ™Û:–¤¢6m‹›èÐ9M"Ìe¥ï/ƒo9‰bç¾rÂZš•S .èîãÂÇí‚ÅI”§G%ÐWòŠÃ‡éìjN#(ÿ¢"m!ˆÄîi²kÚ%#*¸ˆl.ðÂõÐÓs³Á_=ÜЈ°™¶N­ÅqÞ±·Dz!qæ"­bhþ{cÇv ÷¨çKÀˆì÷ö{mtú8ørêÝ#/a5ÞëPMåþ$k>‚—ÂŒ+˱“¯[Å®ÔKih‚‚òžªfyß}o×#, T (gG¯µNVçfêT1§O{:¥ÉÉw){”©HtU¦®cÄJ.âоšF¨[^e¶mÄØ‹{šš&Ñx]pí/¿Ü£À{Ÿ£DÆàRRÁ¿|<*/ªªx/ )ÒTÑ`»výø@æáöè®ÓáëøIé.UÆQ³cÀ©®aØ­U^ŸÛïοa¬ÆÛ®UŸßè%Ø`éu/~¾’ü¯¬Z­9~£êpÅk¬%ŽMË-Úôq Ò¬/˜í×DK»žöÃyÆKE]cÔ®AƼüîI97Ì`Î\¯W3àï¤ô°²˜ã+„žv-‘ž›Í[sIÅÓ%4¿¬#/'IÙ3OUΙ£‡GKî´Z!'bMØÙ¥”o!M6(Rþ7È¿;°(gü¯´ãËœêšúl^žQ§ŒÏ* §§GZ1>¯rð³)Œ¬£3-0<}îŽ×ß Þ1Ú%É*ó›Þf¼J¿7e®èEòaŦÉI_HÜ]Zä¬ÁSC•H³æV“Ú¶#|oâ÷¼äÍèÃ㌅}þ|¹-°@Ϩdk¬a‹Ýºô€•S´ÿm}]#Ž<ã#,Øü£=G£ÚèÚ¦<u˜ÏhÛ^ñRælù_ÛÒ½3ƒ;ï8œZ•Ïu}ËÛ@l”/à¬ÆËsÂwDøe‹ª‰jÁW­Tƒ}Íg磟#òE̸ÎTóAϘ#/úÍÁHç/ã¾}?¯ñÂZÙÛ|9î­FÇ×8…GïÛ:çºc*ª¤)çÚ#·øwÌÊa5*ÅûÛ Ïm~ǙՈó[$™B„ecÐ=n³0ûú¼²ðù†Ž“áp¢VÖ+9,> :›º\¯OšËŽj(2 ŠýyŸ*€È–€?®-=hÛRûäˆÅúȳ^€ì0§§±Û È1#*…*¡%îàÔã%ÖåÉ×øº;„UŽŽ]n¸ÑÐòÚÖ—wÕ…—uƒÇ±t趈B‚¨L#/h_…\d×a žédòÕp˜#4à›u|ï©#, \B(`•ÐuèÝ ¨é åŽý l#ÂcXÑ|º¹°s’ÒƒxPHÒ÷¢|ÃÈC9#,Óda)æ7’QÇ(z²Ä_4iC V”ã½]³>‡yú!#J»cŒÔ*Y_Áü[Û(Ä #Q6謃žÎkOé‡cgøLKJß®k—~û+ð~Ǹ£ïpbC˜N¬Ø´4—Â]p—Dó”mRœçNŒLw·ì—uàM¬¹Æ&yŒÑ¥6åÌŒFÐ6ŠßÒœôJßnNmpÙúó–ßÏÄqˆŽÝ¦­#*‹¯hÿGÜåõÐhžNô®3ÇÙŸ5cúã"Žtdµ“‹ô½ä6úÉ¢HqZq§7Vº³­E÷ÅÆ"ø¾1ީɕhŒûà|Säùà‘Þá4Ì?Å—æôÓð³§óÍuÝwz‘J1è›·7P.êºMgÄÝ»\=:Å:cì½üå½~x"ú÷õn¶ÝgƳ] «GSA3Ùåæyöòê¾ÝTîÎG®8Ø’Û«ãyLéÜÖ5ÄZpW(æÔ·¨Y_[)Ì=N;~GŽh…nFŸºðŽ-'WXp_M¬?qزÓ7`O—ãg åßekì$³ÏF1XÆ&$‚OilQ\Lcs¶wvS¤ÉÇ\‘ (²i\ŒŸ!}¯† :ïŸ.Ñ"Bdq„­âý-”bwézÇ2çŠf¢éÍî]:hitQÑ[Kê•#„¥Càât[ζL"%&ínTÿŽtùæcÕ¾ìEZ¿^°Óû¢o0T{´¯(.}± ïí|ïŸ_7!VI{D¤©qÎ &¿\ÏätÚ—÷ÝÎ'Ö|T1¼;pŒ@;'g»B8¿Áøã~1ƒÔ‡Pœ7ÝÜGá>¿Lo= À!óÒ|u¿5'ÒT£:¹èœÇ­]$Šoåý‚­^.a@:äëðøN<Ž ó·ÏKãD<¹ï³Ë%—k±Ò”'êÿìÕÄ1²Mµ ìÄxðj["^îhF#ÅQ¯Ž¨jƒ[ӡ脱ä–V(C±±¢#*ale(vÀ»^ØÙ´&įF4 ¬:tÎz&rÎÄ^îÓÖDä=Þ(cÆžM 8ÉnyÁïLXМW§ˆõÌ‚<))KN=ojŽ—ˆ¸¥ë¨¼”Ø”ü(™¿žÒAØöäû ;!(žÈ¿Nºãª´µÜ aíÒ¡FxQˆšwbž ^VÖÌRÓ"!ªf#,.Tç^Ìg6íî›t‰ñÆò{ŠhÜ1îæbróR«àü{gÅ}Uw¡ˆk ЌՃ#*H¿Ñ^!à5;…ÈšÙå=‡`¤:Þ]"ût—F¬úxŒIèý=§Ó‡ÀÀ‘ª€²Êó¶Ù@Þâ¿.ðÙVå¯àžáßÙÓp#/ÛßgÃ]È;y¶ßm÷&žÅA4!;‹³á™ÈRöE$3õºÒ¿—Êùq^ᯇ‚‡‚ ¤QdíŽÉ½ãna*:ž§›¤RïR©æTì ˜›kÓÂ/vü2Û­>`ÖºÞÃòx¥¦æPÓ:k€W‡!HFÃÝÃç¼'ÅÖ¼‹Vxþׂ>«‡me¸uèl‡>,ÄuÜ¡´©ù5‹’1•_±LzÇô¤#/@î•}&àD#/ÕE¥Ò2;…ϹL¬`1£gšbÙa(˜xÄ~¥áOèýM¦0ï3f•~öc± ä’¸#*ZD\€­uRnN5ó¿°â!%$±0…´7étM*ÒLôçèy)ò@®ý·b(ÌÅÃ.Í¡,ÐÓ1JÍ©WÚ*NclÄJµÚC J<¬Õg˜`ú)°„‚ÏÛéaÅ|ã^f8Fëý|Aà —ÃÏ}_w‚wÄõqêügÆRÒ½ü¼J#*õª}>µ#*iýÉúSõý y{"„‚ZwŽzï¯0ü¥ Q…•p¿t p¬KÎåM?¯f¼ÂDÄò‡ˆ_*‰ Ÿ¿ëÎĨ‹êô¼4K ¦KüŽ {8ƒUËûŠ@©ETB*%o’Yh("ĤZ“l›ÖÑ­]un|ôûw*œÕÚ§œaÜl$¶*0üøPoÀ8Ôkú}9ÄŒÞá=Wß–74óì°DÕið¹wHpUH²FE (1XÀ€ˆ‘Jn#,uâƒ|¤”J…©Ê9@àR™vëé¶ñ†s0àžlܘø»#,›ÑÊJܘ*½¤K½IÌÈ "êé”ýf7°U{ïhú*N%"D¾Ë^ðýÁþ›Hˆa‹HUV`·ÇÏòŸÔ *¹T)P¦˜ j¨@nTÁýó‡í¨âûw,T\­ö"°Ðæº#* >ÊÑ›&»Ê…Ÿò‚ôã_GuÖ£#/kb¶0Qî )s—Ëêƒß2 Y°ŠBNfb>n.Z^Ïi ÜÐE!R!Qedž¾š‰²å* ï³çþDg/(Ü{ /;'èú@յбOUÈLsÌm1ÕR&Ä—wBSbíioE®xyFU#*Yê-ö]Ó?ÕKº1ÿ$…ü滦›O=›d”¥4" ZzË/ÎC霘aÄ„OÚýjhW¥ maµ:H9l›æY‹=ê5GR'üƒ‡ºcdØS꜄nKNµ¢½@ *«0[ÅhÒ†¿©~ý^ïÈ•s<­7E‰a'[C“Ÿ™ÊËö;,â=›¢ã#,¡Bÿ7lgsZ(¨Ôd× …ï3çå°H<´ÈZá ?gûàî2[}±ÂµÙ¤#*ì0ÝG‡- y!#/Ñ¿»|û`yš<†sNöhn”]Ȱ´#,þ•:½ŒPËõ¿Tüœ“)LwD5ª#/GT#,ÿ?í¶ÈD#*âi@sеxA=Þ5¼GŠ¿‰ä¢(¢’ÆÈH>Î*e;â0 Bµ»Ë9Ä)å#*lÓA©>6cÞ¡’V|ZŒ‡–T†Ýréku%Ðb '‰àB€4×r䩽#,VÔ–t]<b/®!”doëç¯fŽv²?ÕKhvÅ8Ñãý\èo³11›hʺ{@ð«óqä÷vŒ¡!ññ{A#¸wF鸯±Bþ·ü¯Þh>û‚ÛÈÃdCPì„Ùxä‘Çô±šÑŸ(/Œ<ùS‚zî{¼bߤ‘‹éÙ¢L;øÑÜŽ<ÏáÛ¹¢ÀÊEšÝ÷ ‰½B™@+7äÊ·-4!¸Å²^ÓÆ”ÔiœK “à«|>Þ9wÖKÞvSöÖêÉl¨+¿—R«óζ.nº†žºÏëu;Ú8•HCY£6ø‹~‰ì‹ü÷×f¢æO#,+”½áÎÆ[‹†ž~1æuñÂjåtHeZ7¢äP.ckS'…ȶˆÜ÷÷瀔rëþþ¹袺ußmyº­d¡÷STOaRî™àUM‹õ·=oÍphŠ7(ö¢ž¦÷¢b'?RÛXÁ{ºÕU3@2Â’¹íâú¬Ióƒ.D•kª¶Nã„í¿Ý2†³lAý£M ò€´¦ûïŒNò¸·S©3s vkuuŒHé@dcOF@šGHH¦A¨Qßçž|ïmëI×øê^cÄéü¢*´¥B«ÈÀ:Vëî‹õ­tuCZïÙ²ˆÍš3¡‚@ë…Ž!Q”ˆMèX³TVPxSŸ»¼q³ ù¾n׸Ñp#*_\z/wì€<g £ußSºäàÂî.KÞ¯~<à‚@Â×o‹ç¿ÇôØhÎ(v½ßέUxzï®(‚„> „B˜e¡®¶¨2(KPÁ2¯*#/WÖe;zôâ–ÁˆE¦sÇÊùÅÀýó\ C"†¦”ŠMÚÃÐ?ð~ñÑïŠ=Ëa„“/Ä©Â=ÌùÙ5KëA5IRjuªY8 ªJ:­³s 8Î ö b[éÛÄ_~Útâ•ÕÐOÂÜ`Ã×ÐÑïsÌzb%¡j*°N⛸Uvz³Æu)[/$"ª„@,”³‹7VõünpЉªˆÙ-Ç?]ÄÆðCò•;'ŽSøë“´˜Êû0,€ÉáéE/)©Ëd/{7\‚åhM»#\ â¦BÕ{XñvHµ#*˜pæmAá.¯#/;Џ\qÔêPè^ðtÅögiЈW!t—6ÞXï9}ï&z</'žYºÖ'Uƒù~_¼òî3Êe‰?”9züyJ`i‚'0ÔEÜÔ%útºd]ù‘N±³9‹~¾Ú¾‘H•ÎcïvÚ#,û‹½~%ºK¡™¡0B6jÊX3Tàê[ñ*±Ëçx陼܋7)¢#ùFRH¢ˆ¢Zbü!­y­~© ƒÏ“êþánÜ–ú“Ùæ–»¡‹rö?LoW RÓªH9váÚ3^îó;›"¿ׇ6;#_~{·ßªËfÜnL Ûãý¬×žG>WHxpmË"ñ¹èò÷I©Ó€PC#/&J\ºñŒ¦!™.ÆÉžX)j(°#/ɹS0"ÜÖ´€á—BÚ„.Ñä~®W1)* v÷F(N‰&QâU¬w8AÁúîrð†èɆ#/'†QÜS`"%yÂØþ,·½È,@éÜÃ#*äç7ÍÀ±Û¥‚UÕ¥ÀW‘h {­7Éîƒh±XY¡TÅP(!æˆW¾³ì®z9z©×cH²¯+Úý„a¥ž{ë´pÎÞks^GlÞ=# ª^\ï4íé?ºó£ågd5ž•øø¾*=¡éÏ>zï7÷ŸZ‚ɳ)U†ž·©ÏyY‰Ýy”7,#,C£ž5@ùr°ße£ˆ7°EH„6h„Ë^迎†jRÁ…40E"7Þ ”9Øà#'ÐZˆJ‹ß* ¾ì‚ì$–ºÛž#Ì/‚ú¹šÊ=#,ºuG“ÖyáXþ÷xúA‰Íi§‹)“OD”–ˆ—ÑáË Å<›Ãû£©‚ãÙÚ;0æ¸ò¾0ç~æÆ­îΈú¦ªbpùîýxé#,”„èÊønæè´Å3#”] ¬ÏL²Û8ök® œšÏR\6pÁ#*¶€PŒ‚‚˜N68 ‘óŠEÚ—PqAÝXK-;6¯•ùõtî³Âˆå™ÎýÜÄ·'߯O¦_œ;ä’Òs=¹xàæ_PìáŠùëlb)ÒìÞÞÐ&G®+ó+#,¼·Ó×´ÓÒ²Hí4ù)H'!áË\‚‰ò,"ŠlÛÆiA5ÅC΋Âzà #/AÓÀEävªº+×É»¨[:I¬ ÷9sÎ[ž #/R#ÌäLh# „S ¸ R.kaªÒî;3VûòéÞ’K[K72òc¾iQnÈÀM#/g›OÚ)B ô~»s°B'·ÇßP)¬³b“‡’dU1¹y=gîÅöÄeZHñNƒÕ $^\zóþ[GåÙ>«žêh´Iµ´ÏÝþµ´±w¨øKÞmrªm6Ÿ#/C”aàê<Ï5ŠH N㬅(àÊ5uíÍÅUPáæN1¥€ÜyÍÇQF7"8ªâH¹‘wFÔHį'$AÎԩƒÒ›P¢†ÛÍŒ•Â^ÖÈ”Ï/Y\¨/º¹1Fó?šc­> 1i½ðzMÚcI>mŒ* aéçÃE¾,¿äTÜ„Ôé-ƒcù½—GG׿o?þ)óß‘¿®; 6©RaCRL‘ƒ‡©ÓU·«eb„Ý÷/·÷½µ©õd$8„WŸ:6E~l†… §vÖ·ë9´­£•},ÅàˆvÒŸØÂ#/—Õ#*ŸNlÉ„³Zçôþo;ù&þ£^]é9àÉÒ„ÆÕ‘z ìÍÚp§)ÙÂ;þ½ž¬ƒÄã¥jt½ˆjR›ã´xã)­K¿Wr¦:ŠûPm9]‡C‰”TÙ¥’'Æ­Àœ'^í¦¼GNr˜j·^#,rgqž Ñ >x_Eø#/Ê8wkcÁI°`¶\&QžXŽÍqšFWV 5+°€Éš¢jXk]oÉÈÙ~jVĦ5æa?¤…s#ëxhB7©³¾èÆšHU3oF…²W¹ÖUîdõ¡ÿ0¨UB©çëº7ùOí”.tl‚3vZÿ[ÿ)ÿv°/÷;ŸzU¸yg˜¶Fb¨Â2)Ø8 ‹hPi°aJ6äCú¿Ÿû}S¸:ê¥GÆ¡ŸõwGn&w·¢©?‘ £¨1F0…}‡æ|Ú_ß~úÓTu÷PUTöì Ÿí‹'µ~„éóñ<ÙNÏÿÀ/ý°{䇧÷‘„«ÒßÑWÜW‹WÎ]—ô&W&¶†`Ô_õ¾ÄÑý“ï¶ ¼Göò1gˆ´¦ú#ÀO\„AcàB<€÷¯®Û›ä"@]ììß¼&úZç7C–ܱÀ)I â£MJ¥„&“?C#/òÁÇÔ„1’ü(ÁæÊ`¢1®¼†¬]7-Ó0ü9t8c­Ï–§Nuúò±ò¯Â‰‡ïü¼›1ïi†‰Pëig*§ÙÓÇG=Æö^ÞË'; öÑ Îb¤ÄažUï³’ÈN–V£FÙº^ÏE6ÌöïeÇw&êV2T”'ðr—F=d¼r<[áÑ?3ù;wàãÕe¾" TñD#,Ëý~!†õ÷Ç‘¯ Ç©—¥uŸW†ìgB³çÈÒ{˜jhsi–”$–Ý Zp¦¯¨C7ÙƒõQþ“ìôààûÜ>µ%úí‹´Âo §Hß]~_Ýd È¸·J¢¥†Âê‰êA/ëüpZNî•wÓa»2†‰##/¿zK5 |ðùŒû¡Q­˜éû0àþOgWn>ÉÀ7t…B6#*=,€OòˆY(ù?QJ×sO6U}¥óÿÚ0<;}‘âðBb_Äí .y”cÐ#,óhÐÀ+P@r#/½À…ˆsˆY‡¥ˆ©ª(vDro­±CšP«"•È´¸YHênѬ  f !ce,2Å^‰@…ÂÓaBf—!$àÃ]Ë#©Fí”,ŒQt(~VÀ6¡4\,/ÑÀ`[#*b"Û&´£MâðK•ŒÄÑbŒ %”LaH³H”`ƒAÐõå@åo9A,S”jCÒIw³Èʶýº¼G¨¥˜q`ƒÑÞžgTše:ëÓûâŠ=~0ñêËúºUÿ#,%ß(¦5Un3ÀkýЛ¦†º[ý›ªÅË¥.:%̆‚D’@âÌO„@OWÂÑí#,gMmþ—÷µ+1Pm)܆í5•Ó¾µFéÚIv:zÑùk9¯=£ÄM&JïPR~n¥íÉͳd•¦·#ú8g ›ÜÐ~KÞΕÏG¢¾ÚVÖMËò0‚ì„ ›Dj ‘q];vºî®åÓ6ëwy(ÅçTÔC†õ„DÝömw&¬‚·)ªvoŠ:TëêOY¥ÀýêzúõïqR¸ëŒ«ú¤á{ÑNøåt…yávl•Õ,⣀¹«QØÆØÍ4}/RŠup÷EŽOu¨ÈÔ•—.Œº¨pdïfŒÕ¬°õÕ‘Ç¥SäÓ,Aº'Ò <7Wè{L6#,‡‹AŽÊŠ–Ý÷Ú±c¥×7]·ºzº¥#â@'„šñ~ÏsÒBÖšiOõ<!Á¿Z=™/p‡f*Éûƒaò²e›B÷÷&ÃbWO˜„„2Þˆzò矰¹èX¯fK4*•"(H¦i²ÊÓ2S>·Ÿzûž£04UU#LPZbUCÓ·_f³0™d7 Ï\ôèw&îÏ1æ…¦³ˆJ9šX,œ 07ѽ…ºmíÑÆúCåª(Ñ"1°iˆážhg†Q¨˜)ï,ŠìøP-iöOÛÜóÖ‚‘“Ö#I Ûq3B#/B+Ðl7Q`Lúk¦&­c\a·Êê´xäbËSj›ãCoox¦‡Jd†¡âdäÈ­šR#4 3G£VVDÁ3ÄÌ0‚²i‹£6‚ep&¶©R¶rÓ]Ž:Ê0#h ¾[ ëóc†¨|Óg.öx™à2‡5ì{³#,µ®¤y`gÅÉprHž‡”$<Âò»‘ìˆg ¸3z{',g}l&áÛù7j\¶¼;õ÷8¢yžÝ#*Md \§4ðO/*,‰Å¹ŠÉC#*”$ÔI!¢KM²mljÞ:ÍY-«É[ÅWe¼k^-ªåY6«•]6®[^¬Æ»®ü;½z×zcT$öîtÜÖ#uë·‹cm}2l”š0W¶tRl¬ ¹®&DßUôÊ®áôÂ#*øzÀŒƒ±£çW¤@ÒÍ­žW`Ã’_†+ãÁfýqNR)j5ïia¹ÜgÔpæîè^ bE‹P×ÈOŽùþ5Ä‚t¯¶åw”¾=|ë&úJÏ•M òŸ?+‚ÜÛ}KI ²mØÙ*ÅÌ6C#@y d›2+T=9²Ê´®¾™#,u¹âm/ôè«â5‘KîM ʺñrlÒŽT:«ƒU¶(ØFi$“UõÉ¢!,»¨n”)Éo÷V°vì¯ÆÅIå ˜‡ÏͦZèÕàI[©Ï%£XŒÖ⨈òÖêmh¨MÖ·¶­yüûà,mµï.”iwjݲ×àóè¦ÿðxV¢ñöÑ8ç[ø'díêO#*TAi#/ª×‡f"*ÂɵORˆλ&F(¦“]Ê,ÂM6\l g— Ît[Ô÷‹ñÝÅ‘CÔ£(vt±Cp0 !¢˜ßÔGLñ"³ÝjÞG>´ÚÈtÍ0 PRû0&Ï&,Æ¢Pù×%¥ .’ØlcùÓêÛŽ{¹jï:9·z‚a…M÷-5Æ$9#,v½47ÜPkƒÒ‘\ΛÞ(])ÍX©Û®W–h3Ç•ûS@éD*DZaH°R¡(:ñõÐѶ §‰JÅBmj‚†ÞŽyÜ;yVfþý³×X,†Ñˆm`ïÞ†¾u'¤êÆÝPFLWÜÖ­M÷*íuÃìco©Â BFKÎCáæ¤QHPU—èQXcRAªšê\3×——ãÎnÍWwJl– º1³ÄWj5/£á~ñÉÈíP-ENÙ•øÑÁ>Uœf/3épÐÚSá’mdТe]㓺äèñØ—¹°õ¹Žù‚Tn϶§*Jˆ{‡q `ÎŽžo©š¤”ÀiDÆtÒ· È2);ž£ ' ƒ>öpAÇ*45œÎ6Fª€©Dò…òÌߪžL[p6ƒëFØ;nÀhœ/‡V0ȶ[‡CäÒY¶Û¿J-vÊjµåf4÷5I$Âp.÷SØÆ˜ÂH` š€ý_ŽfÑžär îI ¾£C&íãó¥‡>’ Ó¡¦sú=|MŽd‘Æ„j¤T &eMûñ¥U;7Ç#,ög~Ú³ÓåÀÞ¶Ô;·éNÙ–q×ÄQ_!­ùE(ü;UÓ­átd;#,.”u«ója¶ûãseÓ¤2àϳ+¢þþ‡"HÃn¶†üD¢ƒ:vtéÖú%µe¶I©§{ž#*…$:"À—NlýçÏO WJ%ðe“¦é#r9#Œ‘±èg¢UЛTÒÊ|û\RW‹ëó³çW•È‹yºlXƒÂ¡/Z¨ùq9g–5‰ÙÂTz7åäZGù¦ö†Â|¾|\Û)åep…Ðtstê“£8¥•]“Nëömݦ³Q×UˆÐ@¨Ji@KE”ÐÙPƒmI"¤_y(žjäÆ#,Þç] ÷Á2î* Ñ Ë»\aóÍ\½úµwß¾Š4׿¾‡z‹×Fù P0‚@Å’{бE/[Â#,äs“^M¢õ‡ì©7cs à—{K좎#/PP`ª‹ÈÀt’bZÑ)$ f—<-uå%ÄÓ¶×Xn~p_éWÒÅ« ÊîŽJ½ñà_'-˜òAóËò¤ !sÙ®±´Å›3ï|ÞûË3ýùÄõú}‹Þ¹¨iåhÛØø„Ì úHÄù&p¡(foÃ#*=OŠ cU:²tCµ¾ÊÞ³ÕöBôL|¬“#¡°;áø6‘æß7úÜ7ÊGý“ÜžµÌ3£¢Ù,~“‚ËÄæeÓ¿ß7“Óf+øç•#/[¸?°C‡’A[nSM…ùP6HŒCA¥Ð38JœÉú•Bµ)Ùh~Ý”"CÙ§%Y3©(³%QF-hñj¤È„A8^½þVJo“geA¶P­QI#ÊR™ÃϨ¿~`ø$,|UU8ùÍ$ÝÚð·`ÅöétLóŒíäl²‹ú0ÿ FñÁѾ3ð€”vã"mÑÙ÷Ѳà‰j-ÅÓf!š˜ÀvølBoŠN‚•AÈàÙAÁû¹#/ªÆFn82€š:@èVÖŠëŽx:pû/F½ûM„=]#,»É¼‡@Î×|Öˆ¾jÛ9˜·%BBóÌ2p'ÕÞÀÝ#/¼ç·€[LY6tå‹õu”‡Leô6š×äýYÆèm#/9!«Hä“Á€¥²s|Ò&Àû#8]·® m ¡Øˆ:6<L1© ÅN:M‹›ˆ 6*«‹Њ¨‚ŒI麨ÒkMŒÖø X¬_¡µedDkgŒÝ=¿5“Œù•ÔT‡\Ž%ÌB*ƒÞÑ8Ý̈f0½?®ÔýÖ –Ášzz0Óm®²ëfH_zw¶¬<zÀñGƤ'&Af¼(zYiáSÁd‰ÝÙƒƒáUùúî2qëP±ÉØÙw¢L)Èâ1>Ï é®; ŒqòßWœ€{jŽœÊ#*>\Urå–ι*ï&|bhXÉœN£F>c½¾Î#,¯H;náàä@2ͯ–‘¤~ Žz"Ìðfƒ‡{’zãÝ8²HŽdÜIFÍtpöìçÏ~ìhÄ}Ê#,_NS€Ï²ËvߦΠ³_ßx.ÆX~̃4JР?Š#öæˆXÓY|ø–W²«ç%——ìýí3*9ÖË’}¼6~=J ×úóÑA8=¶^øê‰º&¢‚öüý^ÅïË-¼ÖÎôeÎÙÛ{#/!#­Ïxß÷3Þ–>oÔÑG–Ð~èO½QâÁ£óÑßÛåGVÇ5®¡‹#ç©Kf¶9އ8’þë‘RÿkO¯n0ÏV2@Rƒ…tØ÷å]ÕðLŽ¢>Q’ÕI–ïYç­ž´šÁС‹Fò;þŸÂ«ý)蘺¼ý?«Í3ˆ@#*þÏòC‚nÀ¤H¤2®SrŒ Šy~äÜÍk…+01MD[ª|Žb¿Ô88¹/!úŽqáüiP5ñ¤¸^IPû*ÍB§ ÖWéê£ïéÌ=Ûµ“pÚÙnüqØÇë?¼Ì׫³Ÿ‡¿†sFÂ8o“ @#*˨†@#*—ôçü½?ïýœÿŸÍü$?‰|Ø/ü?ÕŒ,ƒëC7Ëqbûš‹Y3Ÿ¨«§ùFœéª…²Õ\*ô[fËß'¼÷NÞ“­²€¬€¿ö($ES2ï±Þg4…ò½²¯,WîÔ ™ú]3è¾6m‰ßõûpÒ¶£<4G)¥j1©­˜0®âHåiZxu‚A(‡Îª#/ª•R\@Áèú=8Ð÷IEÎ÷ctµïðÿvóÁ$i©’—•ÊÏÚjè“§}»:+­˜ÊªÝÚ$]Ñ*ñ"ÑVEŠL]Oó¶1n"Ó(|¿ÅwÞ8ð½¿?ݥϺ!°#¥PþÜ®Ÿ¶ÿå "Vÿ9{‹¦¤¾Fš0ߊŒLþx¶:ë=rý=¾wxˆÝï&”Œ0uDÄï¾à϶®‚tP¦|ÃòéÄö¨’UC¸åÇ¢ü´í禧d~úW“ýÁ®èÞ™™ ò¨§WMw-™[N¡§[¶ø"#*‚xE/"ûqrLq´¢J ‰h#wÒqÏf*eÊl¹ŸSwþ»ÖéZh€šï(Û®ö?éwbmÓ_÷/°úûÞDG•‹±öÌ÷]šz&‘÷3åeív/šBážéAEž}Þï‡/­Ôº#ò*”·ý˜`y «÷—6kæÝ¨©I3UØ×mùb<~»@ÏûtÎ\Ü먬Y\Í©µ¦ܾ.Žn“.eB)E’üH‡?©çaí‰ß(šˆ¹x#,ھݳ?÷BZ}w?/ói>ÆSõq êÃèÎnŒDH±A?\3뇡2ª»‹]zŠÑ’ØûÙA™vý¬,˜ýbrpuÞ½üâÿ¨p»ÕËo“ù‰`3Ís„MZ'´óóyv¢#**#/µHŸBÓš¯¨#,]‡·×Îz›·€ìñt3ôú´iˆv*.Z­€bk#,ü¹Qlõx¢®\‰{—ÅZ÷SžÁ œ¢CòªãýEñ°]W­ÕÉf{ífR¿½™œ[s™¶2)ë@ÞÇð#*t„ìòÖ@¤¤@+o`_à<´jyÿO©#*ùƒÑ1ð'Ëæ P¡8•$â±X¹+òr¹ó|߯Íw¬2C?ÎÇ­mÃ×>æ©@÷Å#*(\ѹD:V½ãÎLLÏD™O¨©Ë£ì·ôWÂQ{€£Çò¬êО¤sßærfF÷cããò:<#*ðÅ~Ò„Ž‘ðñæz;úpùœÑ^Þ8ÓÕ[cæ'’G­q|SÉ.;‹¿‰m“;¡”E²Ðœ?/z‚y?£A~šù°Óçà‰oG0²Ñèp[¤—òó<uJÄ…© æ~DXN¢6µû>8bw«pÛ$¼ïmèoG•*fŠw§GϽÚuz±D#׌6‹i¹buåmG)@“(¢Ç©QÅ^жèR©ý­»¶H{ÆV'Ÿ™@ÇV»é¸tu•Äe4þʽ8_ó<±ªûñ0 ¤ZO—ïøé .°#/ëOsô³ËÄšXYÑTs$ïÓö‡¢ý_{ñ€Þ)Ç—§N(5&äù&à(@ž•Äim//r¸½µrYšÎÞ‡¥û ÷-Ècôm‡ôn’¨šþ/á¤Bö³8!K~á×à #/ØBC3â³ê¹€%”=[©óVX=ê§RôÂrS-ŒU˜˜µ ]èLL,Ñ8ÀWeŒ)‹OÓ0À0›<ßïñùýM½§#¨HH„;X¥µ‘Ë~ÝõŽã…^pv§J\Ü<sDGMWHt'_/uΕ›v«nÊÊÊ~èÉÔ#,3Ð#*ƒ8IËùû5 ÷TÚž±è÷xÄD9=´šj–ÀšîøÑ4òä#*ØŸ¡Xg˜0@®½«·#,‡¦ 'vr¤ã™Y^¥žùð®Í¦·×™AçCnÝÕ[ë—åÊ•¯”6 †¿‹hÏôîGŽ9³há0 q ZÇ¿E„!&‰âùm•!CÂOb)n¾<B>1„VÆošjúyê_^Ù]—z !P 1@OVxÀWéÞþ{ãú·tPzÒôá¶ad@vQdgiOòWH–[wE¹åní.tvK-d#*Ù€¥—b9?*Q‘1Ô„H5¶ö-wß·3–t.w/ÐR>µ»{}¿açÁ‘Þ` z{Gº£àRGÑ µ\óñÕÃâ}\%$“Wq„¬ûX]IO¥޻Ʊpy¬õKÛÒ뵆¼wO­]rá³#*ìQ™QE%¯¿Ñû÷ƹ)ÌÚÕrFê™Ç+D±³Ù¿ç±ñÈB–2!rW|Ûv´Né-lQ”)«›ªDŽßæ¶Ì–tƒz‹:Sż(ø¾û¿Ùñ9[ˆs0;ʼnßóUUå§S±óV3qãû\×5iL¤¼öƒcÚÞ¾GÎ#,¾ê!%²ê‡õå÷—E¤Du½¯8º¤ýþNŠÞö÷¬åú¾7˜Ì«í-Ð`*w‘30P¤RAI*HÈ+į~Ö§±Àk“QBœMr›å}MÜÚb+ÃümÅ»T"ðõHx{—IJƒ0R\|Š#®[ZÿWÃFûëáõû,¤QÄF9oxh>€l p&#,ÂÉtÛÈ'RÚ¬Ç઄‘Ê'©ºô,µ¥vRÊø>MÉ%̉Nz]#/ˆÑF-\IÿíÙ1˜ÿKŸfÔ ìºá§‘ñõ¾!ɽ:`½þcœ}X[óÀhç¶'æäõå– Ê› |Þ›M^þXºÁÙÑäû ż‘ýöNÇ¥šßÆ6¯ïŽÎÞU°êñqïFnžnÐÚ?J¬~“PAK3,HeƒZXÜt1râ:–Wa|qí³–ŸøzĦXt´¾JZrù_–.)3‰«™ýûÔqdvåÈ®ÐæÂqzôvD:çÖEÛ|ÛØÒ#/°ŒÚÉ[r¸c Õ¯X,kåq¤mŒ˜I4:‚(!dC«×7K÷MŽT°µ%Ìc¹bÊ ,f½jÎ9¢•ß•Ù#,^›O\¸ Æ1NªGøˆ!T+æ›Ë¨îûgFcÆ'so(1Î0N0qån~ŽLNïˆzük1Åä§#/wòŠ:ô×ë:ísª Ç¼#Iò`Èø†Êö~j¸h“1.nÔ/uð¦+Iúb‚€H„V+{Üœbì17˜”7¶ÙìŒkƒ$’I™Äµ]{”ƒ‚¬4ÅÎJ_¥œ©Í§ˆÀP!pa.}^¾5·º>o3y³ìL¹áò{gßAG¥ÞÓˆtÊà­ ­]opÖª ¢ÑlY¤#/Ý#,¹I£ç£‘Ê4Oœ¿))$w²¶PFyQ^ÈB²5—ýZŠmTZ”ÊD:eøTJaˆSŸ¼éDï¶cã¿´;lì&9¸Ëœ[¯ñM¢hÿƒhi”S›DŠ_‰¹oÚG}Íj“¿¦ó¹{g^4–Ìæzü±=m/Š!Ç_¾º'<Q38|’ß·Ùgãc¤¿„,SNí—óãƒg~®%s6!éë àííL_]ö¨Yê.­IMÕ"NüÇTyñÆ·ãl÷ÇZu‡c<.SÔô’x|6)ËüÅ6Ññí3’ïNéÝçˆt%s†Ÿ#lââÁ„åx?–ÞëÙÛe÷SËlü¦8L4¡&Lèž=fõпê çNaa×øT”’œx§?»h‡œeãß-«µKº"90ûñ1Ø Ž»ÁNTdÿ³UèùÎ_µÆZG¦¸Qï¯rç)c¯c×o§Ž¶KàöäÔ¸Üö\°…ÏXLuZéñ8²QLÞÙŠX]ÑÇîßZ¾¹¢\ÙUÛ´"=bjk¦MiÉÉâ ^EJH@®d7a}«Ú¯Ä€+%]ѱ¹+]ø»¥zÜòxÞE#,ÚÅJhÕ‹ñÄÎ#,ôûj‘Ã$íãbëîÇ‚³ÏÝ·wÌÇ—“Ác¬`Óå³O °Ü¹'ˆ{8àw|{‡,àú§S­Î‡9”cįJ­nФW Ua#*·óƒ£Ú|œ œŠ÷)m˜æŒ>úÒ)§E•âô‡M, æ#,°ãu{E.Ù¾õ£Šr¼Áëis“b<í®Ü²î&~·Öã­ïç/»ãt=ÄR§ë ~†¹*£"Òø­›w0™Äsøy?š›ºÇÇç`ê±I£u04ȼ¡}²õð}!‰Ï¾¤xÏ_V`ôÖ«Ç·õéƒýÓ£\úZå}ms¢£|0g”_„Cü=2A¶ö9ÎoåðÞ·c"gõøÄ>ñ“Å’–·ù%=ãP»˜fDHÀ,Ë”8s@ç…îx9“Yæëöºôò"RØì}ÒOú¢Ñ¹ƒÜö7²Jsˆõ͵MFÌŽÉE›ý,Ÿ Ä „¶'?…WÅöû^F.!³9©GåÏ1¸æŒ'ËÇæà땎'ãñÀ¾þÜì)²‰º~knçFdݨTC)¨~ojhè3‹;X¦í†¯›º[ߥXšö¾S¯ˆ†-<­þÏÖ_2á§g~¤?GM;l¥ÜVîƒ/0VêúÌrí¶;8¬m%Èãñ?Õ=3¡pr1ÃÀ†ˆ°ª…å#/Ž 4­Þ ¢‹Òª{”(aÒCMvQ‡tí‰ujnC_?Õ¿/ØuæÌ?Ù4J¡â–Ëúþ—hòw±˜Be.(xr]æz}œxÅvÉ®<EËÙOôHƒåá˦õ¬ÚmBÁ=3¡¿7s—gÊdý&õ¸Í‰ýr@{{vâ'ù_¢rìG½Iƒ”Õ.ÃŽí,œœb¤üPªzf¡š ¡^ô›½¼(ººúã]§™š ØKŽÉ0àìE¹ˆlÐû8‚‡†ZƒØÊîB¡‚âeΞ,’ƒˆé·ÝÞž2L|Ïo‰2“ÞÅígºl¢+êÀõk¥“?R:aŽêÛØZe…%1O¿'å}Ü(~…Hvo½…§_¶g­¯ÅK†>!Œ;Í´˜ž¶ažl<¦Œ…¤õ¡x¢ŸÔäEbB"}÷°jA «w…»Ðs¡œâ»TtŒªX6ås‚ÂÀàãÍ;òÇQÂîR>ÿJ¬EÌ×§\f®‰D$’¾µ$òR‹™F6#*\Æš¤–VÐŒ`%ˆ`Aý´ $$Þ«(C/•T<#,®‚ EäÔ¶ž°È6úñiÛ  õyeGÙËäÊÁÈûcòÕjAž„ÞZ‚âó‰¬<~šû ãÇÊ7yØsâ(N&:9„Dó-^å2BÞ*™Éiüw3Ú‰ä1xësôÂÑs–­3È‚‚áp½ú££=!B#*GçøRyFkW˜—nÑ»¼¶†(€”1Ñg[™·ç’‡"#ˆ÷tÀ`Ûøzÿ‰ÃÈÖyÞ@‰g7pj þMQ!áËpÿ1g?õqN‹'ñ %D±öqóõUÇÌÝRŠÇÌ«ý⟢)¬”Àþë•ýmm6uþ£üC͈ð_ÀñíP8:ÕÞ £pQ… ˜…ã–AwØ>Pë?Ú6ÛH[þ&, yÈ܉°Úg9üçñÕðù–u¿ƒ 1æ•y>qé·OóƒCðeŽý#*8„qo0þ|©Ì:L—fíî›>ßñ»’Õææû ƒ7¤HoØFrǨoìW>ß·ô|¹ëÐ;#/H zC)!‚ã§HòÅð:ŸW>pZg(”ýÊzÜÓ£C¨*H€Ö(Ix ì÷ çü:ÃF@* Ô‚‰•®aÉAÖ]j(Û• ¹z0úb0I%ûHV0`ˆDÙßü:¾Ü~ßÈ%£ñBЈ‡Çbôrx#,¼PŠ0Gº§Ä,ЬP¾.%š6¹J¼÷bu$¢çüy\Ïþ+uäù?¹JP$§™†2ÃgÉg}ëÔß·U¤Ìúg¥úŠ_¬y³\Š~¨Hi¨ñÜþ¡€ç*1"Ú/ŸVŽ×¹ëäìçÊ·œx€>˜ë‚=Á#*‘Ù”½uêÐ\20`ûïÚákf£"Å–%ës5Ó#*~!8Õsz‘?ÈÓA|»™Ù¥Å9(öG#,J€í^Pà¨ü ¨ç¨)”éZl¤7ŽÔçP¥H!4#,´][o3:”ŵr ®œì¨h ø’—Z`)-”r\€€Àö\¶%AC³³ìÂë˜\¤<ðrã#ÐFŽ‹ÐBÄÐòBŽ˲4!ð Ò¢öTÄ0e^'Ƹã!…}ªO˜ùîÁ¹F–d*#*Qâ“@IÑ1ˆ"±ƒyxÌîTÛ]ðb GXf&i´› \ÑŸ<VîZ .ê£ùÛ#*톉¾3ÄšüôbÁé6ÖÇ­ç¥Öîh6þÀNWU®û¼¢ƒ/øàyã_|fÐü@çàê€\à£t]r[28«H[‹õòÍE X¹ÿ‰Óˆ”wxQöä™[ºw6y ‚+´`ŠÉ@XY«i/›’XwÇŸ‡kPK–ÁÃ9X§w€äGN}ß³œ–Ág&øž0œw婹šfÙeq5Ê“ÀÙß»0¦»3œãÑÊÞ§|¤ˆï‹åÓȨü<Ó…¯:µ9ë+šXá #,'ßtŠq‰SR«Þ ›¡åF·Ëæ¶×[¢º3¨fÎäæƒõ┣‚bT€ªœä]#,#,K\£0ä¬îÄ[éƒI…9låÉÉqPo¶àÕ(À;‚Ü€ç±öãÓä6#*û5c~>AtSxŒQ9üºà§»­7tY1í[mâ;y™iÅÙ"ƒn_Døér‚íTb|"ÙµšD L$Dç#*êRo«7!šß=8èŒ{i¢Ëÿ»ÐÚæ ǵ~UL˜$J ýQeUìå`¯gtþÎú;âZ9Uq¤íJWÄUï´ÏRÊl!û\Pÿ‚>i·—>ïê½Ý¹h‚«ªc³”6‘šÍ1jëÆ°Ãõßî…þ½‰Ô4hx¼¤¸Å´oµ¡úS;—EG [{èôÑ‹Õò‹oð"ÞÆårÇhJþßÛ4#="P„Â15E|1dRl/e¼õŒ–rÛ`øjÙOçÔÕÉݦÖÅ•øuÅTãGî„渼‹³¡GΔd¾"é öüÕŸeþ§gbë>Ä•„Çu&çõÉûçAü±›9ïÌ[]b®Q ‡”ÁÌ2QPÊÛtRïiÒD ®2Äa)1J©$FRÓÀÄ©%#/*’ò¯Š<¤Æâ¢ê9Íѱe)§Lá#úÊÕK´&9h?žçZéž´Æ WÓ¦ ö°íŽ|ËX•³‡¯¸zrmYæ„Ô…Ï´Çœ Hæo¥ÉÂËÉÃ#”Ûä±ëRÍ8抪£ßíÄxZZ-Ï»é_;Km߄ꮾÍq/ge±ÀÜ6ˆãÈ&šRÔFú›ÚâçgÚ®_U, §v¬¸÷OÙš"aE­ó†Òn²ýp~Ú%Ö¿Ü:AŸtP_®™ôµ6A©¨ ¬Kk;KÙËs.¹Äš`ÐhŒ†©sSFÌ(ë"‹fg*ïnBð6Qø>Y…ZX C:z(];hÍz-Ö‹C¤µtâ#OØß={û°@™a7ƒ‚èߢÒà÷·PŠü±xöPÏ:H?wJ“sÀ[žoyÑ=uœ£;–ÇÒªª*µ$$Ī)œöCé¤!ÏondªÅtMëôŽh¾ß¼ùx ÜÅ›Ærf‚9ož½¥WY4Ù¾µŽJ×TiÉqƒ\ÅalÊÈ.D‹©äŽÙŒ÷X„ûkÎ!ܦ]‹rÌï V‰ló)2š1´ uÆÆRŽj–u—‹®ãU+šo™]kÀpùÖÉ£B·ˆ‡ÑÌ?…(î‹M¯çŠmÃv0° Hpð#,žÍ·úØ-²§áÙæ.k¿€ê?5‹¸ò>€ôVÆU‡̬D:#,¿}Y.@åú¿5´Øp?>ÿÍ,]ð]Ñìöõõ4KÅóƒŸ#/~îv´¹ų̂Ë}jê´?Ý­œÜêÌæbó+«±˜™ªTµLÁT&”4|{*pÏÖN©³<¾U£Á#,Øpª†£7z9*g¬CvæYÿ\¡·Z9Ú`ð"$é?E¾ÙÏ_‚;žÈ.éÇcûˆ@L\=dȼݳÈßŇWÕø‘CC^”Xa|`Šv>]#,4Óþ+€}çÞa‹¦tǹ#,«WLÛ%åu5#,çÕÒ¡è©}Œ˜£rA6•¨)™â«ÚZ§é³s~?@t¶<5ÂÔ#,ŠÐGžá]T…¡¦Ü¾ºÞ={êpyÃTXî´Väù}::qº”Ä9@µÑs›0ÐÃÚç2a£÷Qþ«‹rp\4hóî[™,Ñß Þ¿ßúºÚz–,#0Jp¹à”噓ÏbW×^ôòùö_³­¬¢[°*×ñ€M±™~Ý…!X#*ýçG·ÃÆ£ÄEh&#*¥0Öü?_Ä„8k7ª>>\#, ¿»uL*,UO5—¤#*¯ŒÄ„q…þ‰æëònß(¦bç6¢rª£†ng#/UøkÀ\å°l#U•XRø^G|†Ç;¹ÎÚ­ j¼‹È U .&¡.sKnù¹5´2 QhéÒ2J¿IítN‚@žÚžqML#> ¯ÂÖn¥àLß#*›¦3|!‡ º1Ü´òíw‡’¹ÌM!UUd•·é×'cÅ“Èè|ûØÙ޼ׇqÐÚyàmÌ’òI*„„{.îk·cÆáÞÓuG‹®ý® ‘AS0¹v÷µIAÈ[Ó¶«:Ìá,_…E NI+^ì”.¬"4—¾ÀzÜòOMªØ¿›{Ÿ’LG<÷äü3Äbj-A%¶NÓ ¥ðœ©ß}Ú\ÍÝaî8ÀK$`êÜ2¿À0G½FÉî(°‚ͱ@th–hŽ‚†c JØÙyHÏ\´»e«—³¹ûŒ3÷¶™_ží%ˆÃ<DffQ+%}3QK×1xfrŽ]öR’P/"Ù°la!Šä¾†œíGv¨#ª8eñoŸb®sÎv¦­î´4G‘ñÞç—!kÞ‡IBƒr†Ým#,ÅC„Ji1píä#*ò-®¾¸]„okß!ås\|™N¹ vgnÓ´fð6ar½Æ[3ïK¿›åø³¡Àº6X´Á`‡[ b0|N”­“÷“Úþ+®ÌwÚ}-œMѬs uöy3§¹ORصÙt}¦[™ ³¦OCîü‹¸NÆDôú9ÅnÂþb?ߨß+÷’kÐÅ[¹ ô©;×[šë×ì¢4zfjs¡.6­4±•k{ØõÝH«> ‰Ù=$p)ËÌþ„ȯT”òç¼ðßÑë…h©¼†…E ²Î‡+iˆ²:Ï@r:Ëéä)’¸x˰an £y³;N~G©ùuõ߃WTb'\—¯@–åk:YqtÇ#£±`¸jú;§¤YlëY¹yÔ”ïŒ(g󬺡f÷YŒÁNé¬8ÝkNèX®CÚõà&Ï èk9\Ò!×¢3Ý" «ó t΂{{‡Zçb^C Œ.*ÕQ§n2¦/´a-Ur]h±oŸ?Wu”GÑnŰ“œý%U°GD‹B-CQ#Ô#,:©¾ý¸'CAÔ#xkÄ“˜H¦nß6¬œœ‚£#*O#›†÷¢6ÅS™¹ØööÁƒÑ­*6à/!*a;Ũ@Vå"VË¡Ú=±k#,·-½ 1#,FDtu>Äm‹^ë%a¬QO^;t½¬QÅs³#,X>ÄQo-×ç]Û/"¤ՠίáœf·,3\Ci½H¶ô!Õ Üe¾S{Â1 *ÉœW$Iæ[_ö ”dìíâ+ÃOˆgJ7÷Ç¥º¥éœ‚ÀBÜ7@k¤¬r#,™*'9@îe´X岸hú7幋€9-¤  ÷èmhÅ»]JwRU” q¶ÎvŒyõ¥oÄ9ƒÏ³´ë#‡›4º v·Ç²”/ÞX·— §¬­O†CÓ›/¦G>fG?~¼Oõ¨Ú¸š×¥W¡Û¿CTý»¼\–›ÄͲÒ#A#*‡EF ¥(È6à.`]F6 Žåœë€pKÀNîr%Ùå nE¼–²åg“VÄÎô[÷^TY _c¨šÇ"‹ö냹/ÔŒ#]zõ½úÖ …ЧDQ2ÖP]!¾’¶T –ç¥áºÀù<¨¼žïYg‚s„)±p‡€†=è1$rCˆxRQã¬C9ñúý~Þ½Œs¸¿i†èíÜÑzè?!#£Ÿš=pÁ®ä8Yp¶@Ø‘oDD÷ÎêF9tè³Mü,¿_¹árä÷sÑ7¨ÐôÊóçÌÞhˆÎ7ùÓ ï¿x”ž(£”#*y#,0pŽŽ²à¬«“™*PmþÿÕ·›ð÷ûG¿Ì>/¯@¸è:érýAÝÔúj£ëÒ $ú¬ô¿·©WÊ¢‰(û쵞Åü¢ô‘#/ʳ_+Þ®À‘¢Á˜ãRÅN¾Î¿^Òvò>[âcò°V^þ°ƒñÑËKE°¾ÃÀq#*“úþjÚž.sß´rs0ð‡Ï>ÎT^ÂÌ#,Õ£N'Ôe:ä®Ï÷¯W}½ypýcãYþ¾±âužXb2ÊÄ · än„-#,í[],ðg  ±ö#,~ÆX¢“µ ŽOÚ1ìgc§?ŸéXÛ÷e¿ûúzïoº#*³e©ÖU„äP§`B pú#/õ¯»ú ïþxÝ0žàoÔj ýÈæ„÷ A€ašùˆYÃbs?äÚ%¨ßùZª…Oî,“øIJYEC·ùMjù¢<?© ‘£h¼B;@.J,ƒ€Ö™#*±PŠõ–„00Ð2 gû˜ÿAm§–›ÞË-ó¤)»Û Xmþ3}’KýÕnæÁsôo‚hz:AŸGb,/¿«¼à*jLÐÚvÌ#*À‡”Ž\įg3jNïG›Ï-Áaã‰B©ŸøLcT%x²}ð#/2Rq9r°[°—ˆ¼„Ãþèfc9f@©»¬#,^#,Y±íxuƒ‹õ¹û°öõÓ}¿Üú\ô!ô_gÚkfÈhf_ØŽè- '÷Àÿdn Ü »“ç'h›*–ÈäÂ÷.ÝaššÌÀsÒacø^Øk)#,p$d¬éý¹'œaê^cH!µøl*&_ï¯fÓ·ºÖºœ›ÆþêðþªìªýRÛ:^™X¦¨[þ˜yþÙx=ð8Z ·¾Yɹ¦\’B8šjUz½_ òþü„G2\@•‘ #*5bÂÂTJò;5Ãïÿÿ7·éú#/þÜAËÚÁ©k ·EÂÁ‹ÒHÑÛèêó|庿‹ìEǪýV­8à´¾È<èè IVK%UkRÅß‚® Þ}åµ0RùÒÔQ°-¯á«´“´«úÀ¤·÷!zC`Âx„Škôþ¯Ü\½!¿] T0´#/­ä.Á)rœ±»Žl¤néÐ-#/þvâT#,N–ÍIaÐì„C‘\÷&#,;ÂÔV(»†m!àeÕ%“?æpXBÚáS»””rí+î!QÓË«ÍMVë6ç.Iëùwh5Ô,äOaQì:@Âï:{›umZ?ù•5fÔmQ¿zž„uãqè5ßG²ÁhÂÃ$ jl#b1“ƒ#/R%Ø'Rs×á#*åsÐÈFÏ¥(À—Ò«lÙNaÎåŒvÐßM—OÉ·#¶AhNï°‚MröŒ% Uµ†ôú ú¾Äíz®€ŠÈO¶¼¯^‘²É>ï°/rxÿˆí˜¨*¬&ÝÖðÔ»ÿ0i˜d•xð ~j. mÈׯþV2#,þ#* ù<É Ù%¸ºßŸúxöç·ù+˜;#,²È»#ÛI³ƒ ú¸]0ƒü”:ë.²j†A‚•…<Ó×úözúñÂáN «óibÙd^×3è"„VIû§ËDZ:ŽúJV=~ßÓ*½¶÷@ö⚊ûÀÖÿvQǪ|'Ðþ'±"ꜙQ8ÖnлêꆉÄkXe×AL‡užïçõgàùºÍoìÞ¿¨ûÌï.ý»CU³ê>Ãi!ÂhåÐIÛ£F£‘¢A£O‹h,#,ä´ƒ$÷#,'·ÄáÐê9ˆD4õ~âªà‘â-#—æ%;Ê‚J¦j ÝW:M­î`žA6a°LÏú®Ù#,æÚ—,œ_íyØœê™ß¤ü«ÇÊë+5›¿íYI0à&.Ò¿–Šbƒ#¤Ö§Ov9K.:D ±nŒsŒS;$–#/BªªwI$’Þ" 0ôÿ³ßvja¼õUÛ°~'#*¦Ä|ÅÏ]lá³4ú#,^ƒ_¢‚l =ÜáÖ1Hˆyλ#*xèšš§#¡ÄžÀn“¤éôÕ­˜v¥›dæQfåãχòµÏyéO‘ÎæGõµ÷P¯éüÇúa&fùˆ ?ôõ}zÞ—Üs:ÈTŒÕÞ7ö À’6§ö:äýoÌL¢†˜ÜÎpxß'#/q’R©Zf_ °aP¬¿…ÊŠÀ-üé·Çm@ýa1”‚$y× Ãd(kwü_ÓýÏòXnmãGâŒNÚüOK‹†ÇfÊXQ2myŽÍ­•0y*ÆÔO„?›p#,¡™ÚB@1¯üÆå$¿Ù—©µi•¥d`ŒLNËšË.sšXÚg–y|Å‚ÚÞ’ÁÂ4#/D ƃGêÞ ³h¤Lînò—dš#,u¬!çál¾ÿ¿ý¹¡·íuýÝZÈ$(i‘^Ž¥7Óòäñ"Àñó9¡rw­Õ¬1ÆvP„ Ù;àu†H#*§Žö“%#*Ôj!cû¡f'¬Ì8ȧÒûì¨;ý(µNzt¹Ê.®iÅOÝšÂSbêP„›tÓRq„Û¸\š² 6âT£u0ǘ33b¡™fî²3· “·¤{Ž»ýÁ¹´cÑ÷“Û0¨ #,Æ¢‰5Öç÷ì’NðÍÔk‡.Ô^arÈÆžó£±t©#*ަÈduQaÍ€jÓa©ë d”h]*„5†ÂI¹¨°`mЇäoWì´ìðÉ~ÏÝGò à`32ç®õ þ—Ë£%¥¿»çðUüÞk§¯]RoFJLÌ‹û•(1±ƒ`ý8RÍßó~ýÌFçvKK½Fá2™¢WYY£Y§­2'¨6C¬ k9 Z]`Þ:Ë2¹JD1Y7k¯$’I3Uk˜©šÖµ%¥­¶žf®jË^³™Y„uã.¡Ž½aGƒo{ÂkzDhhk­%Ü7‡±ëXìÅëu šibÊ‚Rh¬gù+Ÿ_¯ÖB˜È„„„@*<à/Ûøæ¥‘äG<Ÿµ€M Šƒö‚û&¬RÁ¿!ÓËÊÜãªq à1wÆŸ?Rô{/S>¥£ƒ9§D$‡ì]ÂgTORÆÛýpÁ«¤F3Ï.ó%%ùõû÷VñC³»­>´}_béãÄ3UàZi}ö„¶Có éÛSãJª¹&àÔEd&}¯AõôןÄû?Ù¹µÌ ÷Ë}…+è´.”ÊDÉ“ŽîZ‹dN…I]êìÖ D@<]A Û/p[ÂI$¡´} Ñdéÿ–ÜkÉ¡dÏ#,/KUYÀ¸|#/¶Äh)"ƒÔ¡F!¤cÑ^nëM·¤×§ |ºu›™~%>GŒbrØzb’)ûuã»[®/‰¡X>àeè{²Ss•#,#,O@SûBÍ‹68 ê}è]:7P%ÎÝü7³’D‘b¦ÎûoÛ®œfíJW,Q¦Pƒd#/Õ ~:iuø˜Eíö íîð—€ñ#*H¾)¬V)ÄU#/Paëöˆ@^·Ë¶!‡Ïæ !OŸñöýf +0Ô#,…:R‘è¹ø ¯Ý·#þ¶æÀýŸ¶ä Ü¡‡ãJá…¾G#ÙŽn»¾â©¢–¤*Ù·3Zš!¥ÀõML·P뺳#*Ñ/vkK*Šƒ”šYÒ•#ôìéÌ­:¹ö•ݨ¨U¶ãöıA<C)" ý'q;^öIë,BÅ%Ä`{ÀŪš2Å!뉊IÌIÈÜ#Ç„¿ˆ_­% Ì5§K‹mÁÞ}W#*¾HjÔ>ÒÈGí .V~­¹aMœ>Û-Ý#/‚#* Kü|}ÿ`\›Ü}Îó¡|·qòU»/ÀR“Þö(€ûëëµIõâðkÔ’Þ—°l÷Ð*Ñ=ÑQLn7"yË[ñ%J“ ÔCî»r`»ø éƒéûßäîw9ï“ÞŽó¤©mŸ`ØËŸ†ß:#,Ù2(D$V#*yΠ‡ÖÐgØèrÜøœuB,cN@wöþóô;P@òÚZΑv¤HÝE~p=ŽÝ¾)øœ:Ä=â¤T ‰£¼#,¯—h¢LLÒcùÊÁ‚ z·óé®ïyæ.æŒcÐwšrÚµ;AÙ@îõ¾š-iÿI˰=äÜ¡ö÷Q¦•E¤ÍŒ&£bŒ#!ÞuƒHYÖ¯ïu{ÖdR)³ÇUÎäâø}ú›ø ^‚>KÑy¤]o(uœ•=äþjµ¾Ï¬ B¯ú‰÷ýf­^ãWÔ?ÇGä åüa¼ýF²ßxû_l›¾Ž3%‰[£CäŸ+¾&Zˆ=ÿtÏöCÕ‚¯ªÖ G šҠ{ºv!!êÄd’Iî@¸#*ú@ö¾µ#,›¿ƒZ…\£1C`m`ÕçòWò¤RO³¬DëŽ[Ú]½$-=åšîýmžGÂP„;¥cÃszaSJ3¤ÐK¸éôÖóá2µÍ,lÒ¦(Á;ì'z#*&ÂÞ?o¦èì Œ+•}Ǫ¤¬Psù†›Ì°,Fu¶³êUCãÐcMIôDb-’‰ÖNáa_a̼àSs‹‰¨5– µ|Ì qñ;IݲXçŸäð2fKõ&ñÉ: ²Ï|< †‰D™Xïº˜Çæ™Tú’Ý;ê&#/¿¼†PgGÛ·'– pdeþÚTN[;Ô*2`‚Ò«î÷üž¥QÈ$Š¢T…œuzæùóvÄ4hɘµÖ-ÈÛ0ÑèE¹½„Ér;Þ²ºCSêáêM½œÈ¦aûS<a‘$Ed¿À(‚Û%4ËùöOrxž£¤»Ɖ#,¶0`‡êí;ÌDùÄj¹P]Š6U+¹wï:w ú žnŸC™éï¡<Mç›ÖŠàìßÂt²#/(=¦Ó^ãWw ¥8½Ù0ðüÉmÎ#,„"…<Ë™U(½Íg·Ãàí}ßR|“ôÇOw`SƒìªLʨD.•ú-ý¡ýÊ€~M$‰¡É?ªmQÿmRR±¿õ8Ør +¼4 £ )$PXuÚðÅɌڕ¥(d*‡{˜£ËÏÖüZú? ¼ŸÌ~ú_(™‘9 h”ä^°öž¤Jãd«[áÙUVÔ‘Ê*æ#//ÿBgîw!¼·VxÍî"vl÷Úâ§´#/«dâCfãoÏèo~3h‡HHw‘œŠ)eÊ×fÜÏßÚþ6¾õüª2û³T3‹ºàuT§Qñ&cçùé'A^¯lSòÈí»ÄÓ¦¿uß»gNŸ,åyž'€F>:Ï/Wçïö1?@a÷P¥(CÔ(T-w!¬À‰î«`3%˰°?Œèi¢>ÓϯOçš báßÁŸ3°h´”{YåpÊK2{Õ‘ìšÞj4õ ¹s2Aa¹ª·¬Q¤ŒýÉu±yP4UŒU‚U©“8—‰˜G ¾ÕD}åÒÉ"q?µÌØ:Ú¬ #*§` ;Ã÷Õ;¦–ž@ƒcc%&D½•$ôD^Ã*B"rbQTÔ¼CУ$:@H:&À!©©kõž8vÐõú#,>Q FÆGFhþ÷ìÔÎ¥ETÖpEŠœ¨#/€#/AØÂ’E:oµ#,›¼?,Jwn5)©À(üøšÕ…xˆÇÊ‚ĉ"ýïá=³ñ?{u'ÖuòV÷~iUúê© ‘^ª.Þ{½”‰~›I;(Ñ[…àeryc#*šB|zäØl…6%34¯—y¶ù4k•^šæéµÙ#,• ˆ+-KnëË̺¬òv´KH¬ SwöS¥=>¿_ßœ¿Öóƒ.û½3ÛésìÞ]‚‡zùîº|™È_¸ kÕˆ"#ƒíó=Ãc˜Ç Ð ÜcN³cøÀµ˜‡ëÐ, èä…ˆ-ꔑŒT‘#* 3 ˜!¨“«¤tÀÖ<riÄÀNœ®ÀÒ-´SÅKÉå(ºïæíáÚz)uÂKžm:ιÓÔ/!ÂýõB¥èãHÍzœ:ó+·pþ©î¢’s­qBpï ÌuPó€°âàQØDèû6”m;â¸w6ÉÑÌ]®†£¯×;o®ß…¶¸!ÈSŠPÍ’ãCvÕ#/¨aïóî2íwd£Ô{?5›v åßd²Ðy²þÞzCÁÁétÝr(›º¥99>à?‡¸ù°à-*WœõöTöýgÏ õGö¨­s_¤:ŸFÖŽæôzêT?Ä$‡ô"lûÅ¡V–žiš¬Ðôä/ #/]ÐÂe#,êYêY%Y$‘÷þÉ ƒìÆÈÝ Ý ;E· a¥¬S#,eKCÆ6È@ß`’ÿ“Úó»iªJbÏ}R*—Tñý…÷Ÿ}¿B È#ÙGVIÅÏ!C'$/Ÿcülób‚$ò!<d™#J)ß#,ò(Åú€éì²ùŽ :º¾_hõ•%¦âŠà/¿`·æ†ô,¤ÇW}Zà@’é- ʶ(õ¢3¤⟘oãÞ¢Š¸?¥3¼å­ÛŸÃz¾®¯ë„9q¡|ÈFÖ>íàĬƒ‘“¨tˆ$VF1AIgƒ; ®$‹½=7FÍ#,Æ8;‹êKôšÊ}'ãû~Ù ýŠíûÁµ}†¡ÐÕ¦Pü3²­ÉW€hGõÇÚjÆ¿ÌV4Õ)‰úÈSý³ï1sbwá5È‹(¢ úŠUZ*`æ1œ(0#,‡nD²zHöDß Gªåxé “bLmˆL!÷0¤ÉCÕ8¬2âÊpㄈ .b© @Á ‹ü)ù’*ÈRúœ¾`ôP{ þ]½‡^–Ëž°a#/Nh…"”°Y.-“CŠÄÁw¾çvføE `zN}#/:“R)¨/Ø;.'ê…ÓžþÓgyAS|!žõ{ïy©©l×ñû¬—#*€©DÏDQæë9)Ò>}º‡©Né Þô@ì`ösT øÜ “ !À8MçP÷ÙRx`ç`rÀb*6â,™{ŽA<CS $[˜"Uš#,^¤ÝóRŸœöy~óáN>ˆËÝÏ-ËçEYÀžìô Ó¤ª„¡@‰³³2âÌ~ŽUù"qa7uÒ ÞÅ’”…dÐG¨ÌÚLíý¹8æÉüD‡ß’©è¶U”’ö¾_†÷¡$U#*M?+ aܤ¸™“¶Ø8M^Ž1—5é¢_e:³5d©M1Ç"üú@”H­ÿ²¸?çIÆYÄm2c×gpº½@õ‚*ªU'l›Š+”ä½%–Jf¥¬(A©|»„o*8¹hÅFÁßÜ>ÿ‘,~¶©Ÿx>YØ<<¼{pv›Ìdö|Gsx5Ö휇!¦Ð[®MÑÐôðâ#4›Rêy#/¾EyuéË£‹°¦+&qGbd^®›H¥x[‚„õSþNã,pß78l#*Äx‡zþ}šõcg,MHömÌ3¡é•#,t?a6ƒ¨ïNƒ‹q¤bB:1äA«ÀFÑ,1@)X'3…Ê+‰ò„ó‡“ÉQòùúŽ «Ø#,ª´hlD›2Ú<m*¶žî®žD;veÑ„Xm#(#*è?!®úêƒ^“Å#*=ޤ(ç¥xé]»Õ3ÝGòÑÚ1#,þ#ãc"žICÇÜJN—nóBV$I 6ÒâwÝ»¨Þgº(êû“ëüçðíœëúÀ#/“P}‡ÄËÍ÷möÿ°Ö.»C'?ð?{ èÓ˜[?lOÇõÖ"šÉ1ñ‡{\æp‡•[¼»”§9oñsù/ÙGãùBëN¶†ÐÌâù¿.vkõ¹ûÒSŸ°Å3š­ãg'Ÿû˜ürnìë+Ž,ßXÎ#*sáöaú«¶wúÎÜ~ÚÚ²×Ï`ݤvþÆIÏ#/sáN*j€JHˆÝ’¥òÔÂa»BƒhîÀêb*ßS#*ºÁdKøC®’NÏ´'Øyý=Ÿ­ªUW< lA;áAÍàR£H{0ÚöKƒ@!Æè\öx*k̸ýñ÷ò3*÷'±˜ÑùÔ‚Ç¢##Ÿ¢ ,€ÀŸÅÚ(ø‡pÀ6$éyx&J@2ƒ¤L h«Ú$#*l½IÁÛÏWV‚ÑÝßúw›Hd?¨öXnŸ-{{˜AY¬úçØèý­*{ɬ6CÇÜLÒ/úò2'èGÖW›j¡Zƒ½û lbU6á#/{‘‚8Ãgcq¿¢ôÍ^Ðà`#*ØÕHnhn¬UTX&†”Öìû½_½öÿwÆ&GñÕµz¼Y#*#/½À‚‘½ô»®Þvê5ãvëm?~ý/Fð?­µÄâ(Ä}ïž#/ÈR9®q!5ÀÿÜS!ÎȹçŽ#,W$Ð[È£Mù/ß_xg6)Ù¶PS(c¬> V›ÄâbV>_Âñ ˆa$³}øƒ€C"X  &hÆß»®}î¹[œÙzgžo)$ƒô€?œ5Ô?#/ÓÛîôûÙ\®ÛX}¡õiðü¶„O`Ðõ Ä>Ôt#/ôK„#*ËäžRǼÑÓ‰Ä@ÀùÆL×åßîº<1Å8ƒ˜»±òK9ðú¨èïÚT$$ÜÀ¤®Ÿ ì8ŽÄ:÷#,6Û«uý¡¡ 謅¶ýWä°îâ=ÀvÕ«-Cí"(¨ˆ¨¢«/F¡EUTCï¨Ð3ýêüö1-¨`»üfk‡êÅ+Ûšœt‹ÁkѬFÚz"R8°l-ЦÛ,º¯È»À˜ª‚1ˆ2$¸à*-ŒÓâsê?ÔW÷åcÅ\q;•ééóT%4ÂÔôþ¬4H*üÂãó<s&Ä¥ü' ïžÓe¨$;a¿rÉR½´ ¹Önw¬ln9¾ÓNS’_ã–O'ÊUfÞmçæ8(ýióȃmfP?×#*û‹Ãf[» JõUu_D#óGh"duwNÅÍÇ섌>×½P¹âec»¿QÊ^r«ÿ³‰ì#/¬ÀBCLʆt«ð÷Os«ù5÷#’#¯ôU–k2¥¯t=é¯õ½ F$ÙÛfð.B³Œ š_m“ꊋ#/eFŸÁ>Ý]¼ªœÆ»{Ší2W´Pk4£Ä¢Ñ„ˆ’H#*Ñ€\˜#;X`™çÄ#/ Laö¤£ù/Ïü°ñ67#*l‰b/?§ûæHäg·ó?WÕ˧Ÿ¤×v°0™3U¼µ[]ÂuhïD¤’Ø*1',ŸCÄù>ðê‰ Ë¹í¾è¹+0­ßùm‚\ý»:ž¤æ|>ðr§4ìý¨}Ê?˳¬¹}ÃüÀKš/õ9P·r¦Iüª‡Åú˯ðþêùîh©݈+),¢i1H@­MXášbLtiË)%·"¢ÉE§è*ð BM-ÀÉ¡‰±¦* "Ó!uC”›ÐÁ\Ë,‰If,´±L ¨¢daE$`2¨#,„Šô‰µ?Ëõ³øŠ°†þ33Ì8"BºÙ’Wˆ)j1ð/ñÄ@Ö´°+@Óö¬Eý¿ïn“…mÆDdòstNûítLß#,°LÆs8ÜåbvÙ6q,š%¡v 4ˆC$b9KZ Cjnb5ˆÿ€ÌCŒGöV{`i}”HÛ1¤Ú|P#,Xã¼*ªðMþöýo]™°ÓÈD2ÂBÃbô[õ§ëÔHÞµ;O×±˜d¸³™ ©þéÿ…‡m}jÄÈW›¨#ÏùÒwŠýÍK™œÏ¥¿­á6æ>>ÙýŒj fué׳¦L¤‡ð?©PhRZ,P´–ÁR c#×±xAùˆÀó5­=N)ÏûI¨¹Â#*-BÓÄ¿Ïì7ô ôí®w¦Þ󈟥K³²æ»LpÖÕ¶Mˆ-}ým†p«µ™Í@¢dEïP÷3Ùˆb+Ü/pÂ6civ”àJ¯{ƒh#Kìv\rÆZ"-$,-E‚‡’C‘ýø ‰B‚;ƒ#½ÞÐkZ÷•jŸ3ágî ¤FñÊiŒ Æ $”‡o¬~ŠI–l„%¥«`§ìàáÁÀ#*Ae^a#*¯Ï&Å™ÁAåèi‡¨¯©C!,·“ðñj§ÈŪ—>‰üv+»¯a_ãŒZåƒX=1DxÛ#*XÑôoå""6ØÂ’:3‹Ð¾&…àÞ?ËøRó|傳åA«e®ú¾4ÞŒÄß ü¯“¢é9öñð3i¯½À$ŒtŠQžžÖIlQ Ô-=Ànå#/øÜ“˜šâaIAò7Æ,ã´3Û?Ó¦N ëàmŠìêºúežYÓ^.#/aD¢k{©ˆ¦c†s©ß4X'â(#éÒqºm}âkCeû0å:Ö‘àóáK›²Y’x½ötÕ,»=Z¸w¬h?ÊPñ+™àEعìÿi舩ãcdCÝËWóIì3‹³ˆï@¯èk¹;ì} ÆU Ö‹@ŸÑ;ùv¼ÐJú‰Âˆ#*ðÁîf’£|¾ixÍýNõl%@!0!òåªÿòÿñå³Ôößèï†xìü”¡£=¤?99ÀCõú[o£r2—ñâª;C†Â5UF`„‡¹fw_7áƒâò‹à#,èðýJ½¾íE8döŸÑ¯ç¼€3D\&V¢`SœÙ°bÎßÍÖu â÷k‰@¢mµÊ¡U—´6ôHGåÀne!ë×ú¿Ô”ÈÚ¡^G•ÚÄÞô?Û«òÊÁA;ìc€Ò&&÷Ù µCÈO9—ࡲp¶ ò–oT#/@HÏ`T ¯ªŒyÛLtÂcãpv#/Š;:d÷ÁGýVŽqÕô?3KDmÊÍø÷\:_¤Š>`õ@À£*§Í˜ê6]b àÎ÷¢1Ìû €äuÍäò} j‡üë;à$ËÑØYgô\±ª(O±â{ß?­¿„‚ÑÑÊõ½DÝú#/r¾ïؾÎQlÍ•Á¬:—bä!Çoh¼QÛÓ¦ÞÇjø¹hËÕ;/ wó{¼Ø"øNZ²XêþË×7Vçým;å-5}ùLjºZXu@#íQ ØdUë…Ûv™ÀVÉ~§Ž±îe´Zˆv*b`Bn¬ÙŽSÒÅÊ3QÚmr‹MGȽKŹSDÅ&$Û¥÷*ãCŽ™ÄÏRNº¿Æv¾† ú¾Y/)ãI¿°›²Ý„a ˜t ÙÛ8~¦"ð«à£vpȶO. Rå½óMÐì:¦Âøðú^üãcŽ.z@šÙ±Øºm`†âÿE°+”¥ñzÚo8”¾04¶ÁU.Šƒ‚ŒíT$bù–M¡²¶6Å%¦KŸ—Šxâ#,{`‚G!Å:?#,cóȺ¾3à å/¨îtËôÎS,Óf^Z(Û¾S™Oe;·ÅÔyÓJJ”bh©š47 ¡’0IʵžIË^Z轕²k‰( UaVDp'•BÕP[í[hXÏ'¿öªж‘ÏÏÞS÷ ò^Ý´×Ó>¾Þ©w?õXr#*˜…x‡í³Íïi韬Ùz: ŒEƒMÍžþâCB<Û½z ‹Yø¼šbçå_Šž;—ýú¨¿.÷Yáw­úkÄÜm_³j²áÔøKm­G ä¥m³—‡u_–øRR/û»f2þ4>çϤÞn19×PëhTg´Ñ–Wœ‹LW*ú¡vÒéÚ³RU#,…I#*.#, ßaSnï+Ó(Ì›òHÂÈìaÙû ³˜En ™»®¨¾½qó˜ÞVø5Ú¨ÁÀ R˜„ìc— c¢ð¾Éð£g8/•ÒC)¾õË€ñ¸<;£È £)×½˜t*‡æÁ¿vðÇÝððÒÀ})ö}éÙá mñTwçè—|Eâ\Ýw^#,8Íw£¢ëƒ»Ä4&æÛЧzìb#*NšUü‘æ}T†»&‹ô–ÒÜ­¡rÈ;!~íAs@q©üz>#*?ýâ2™ ÊÍÖŒ­ô¾)NIøêQêLö¡Á#/BÙÍw°Œ¿}äèÂ_-@° ¿"³ì+ªA‘8 qp;] ‰VìÜS˹òãÊ=÷_×´´kMÅkþ\ð¾;ððìÅÒ?HÔ/98j‰Ÿ3Îï!¶#*°&÷¿‡ožo}† ¾MëÚb¦M4ÐXɲ+Þ…ª~i'uôÀôF6c¸÷KÛáíìïÂ[¤ÑNg¦p—pöᤆî€Óæ&ôÙèG:ÞïíÊÌJ4þÿâ‡=¼n#žb÷2î-+‘Õ ú@Á†´XÂ’U"ë fbj«§å8Cdn¬™^&4‡ÞŠâJ„åpâ=,+!»ž#´Ð‘b©µ¹Y.«$yyÄb…ëÑÑ0È›õ¬FZ’è€ê{®`Ó°»œ¨Ñ® L…«ör£õÏn2£‘b‹0î<ˆ„ŒŠ}?Ëçÿ\{ßñü|tz¿¯ûëWÄ#È€g[8ÿ§z‡ø¬[Þ?!ôåYB) à#,Žw²n%„|Š(¼Óù£?gqÕmF£Yý¶Y#*j#ù‹ÆOËò®ç@$PÉ”‘<åŠ?f¼»»_óø þÿëþGÄn!ü‡‚j#,-èIoÏýf[ÑUUaÿ9èb7Sý€û4¬à“o¶€rÜð2 HpäLÃgIüÀuìÚ=òovMž¹Ã`~У6ã|‰G5#M!%"F(Dcþ4þ»/ Ý®jt7*}¦YØ’Kàí‰)u¹´ƒ#*ðÌ 7Û«µ»pUâ0xCÒB|’Á:è !7-àn‘ŽÂ‚A¤kès;éDzÐ}¬pàè,v$kp÷o€á#,aáƒàð¼Éì7€ÜÎç¯Ip'HN{#,!‰è¨oTÈ”ÔÌó 3!©•³?¸Øï8ýM€½"%JÆJ¥j©TjŠl;3`:¨5#,äg&€N#*=ðuòdj¨ònaÄ*Â|žgì>ßáJû«·ø§#*³bRˆhß9ñ燗3Êd(èê5ÙE¾ 㦄ó-'B„ à\Ë»èq¾vᆸ ГßÓ7äÃ’Ï.g=ÄõT«”TeƦj›MÞÝžPk"ÔL!ÍA†°Ä B1ˆp¥ƒ4´X8!±†ü#*Ê;Fކkš7aHgƒ1(̰®*ó¸¼Atx8 ±b‹Q!Ï”± ;x$<y£!’Ý{–$€„©0µ©D &·f"Éö¤Þ7"x‚ŸzýeΟr7³‡§ÍÍɲÂBÚ»¹ÚÉØº/]î—"~øFÎ]±7ÕîîõÔYž‹;7¨T8§¡Å (¨~¡=L&ž§!l'*¨†jlŲAƒ®ÆãBÍ«Lm“V‰T‚¨d)C´—`Q‹Ã¨I¹eïO–UÛ[¹n$­Jÿ)·&D—•þGôÿ«íoi­-™£F±¬oáÞ÷X^kÙÈi»£uÕýλ§•–ýŸÅq‡Ô*IòÚŒø"1®í»<ä¼ï ïïŒ#*∂ôÞPjlyéÃ×4#*Ái¤™Àœ¿¯©­¿ÒX|z^¦ª±Xˆ<¦Œÿ#Ç‘cÄ8ÞH-ÍzÂË¡sPýÄ688:šÆÚ ‚+VBGŠpŒ=«Ý[W'#*½´d<ÇÆlÿ¨»ü^$Ñìg†–#,å ©c|¨e{B†ç 'AÄaÄÓ-¡ÉÇR0ÞpŒIÂÐ,; Àr'ÚþÂ) µW©ìëˆÃðF†˜ÀÙ"Tþ’›r"hÈ<HÆf,@ϱå#/#Aïê²1­»òðñÀÍÈš—‚A -Æ96·vÛ°\ü¤(ß íå*`ïWâb W`œð±€dÛ3ô^%·kfûdÈkK&÷ïãúoK#/«_–:·‘pèã!ÌßYa63>EÀÞMHé7ÀÄÖdòKò'KÁÊD¨®ÿ$]c°ÎÇ_F«›:2«ßV®1ûáƒYÒsž%ç¬XóÅä’:zß“¶O|²O=2Ý¿ yvJ8r‹T˜¤Ñìnµ¼›»ïºqÅ(tèç¦i髹…8gk0›wŒé˜I±Ää®»5mÝ#ìôu†NxG@]¶—ÖwÐcôVñ×6»_3…õ“Š;Š80¢8«Œ6ñzw~Þ‚ª÷räi¿qê3G·/5§³Ýž§¯PÄNƒ´7œižA0CYàÝ^.fæ@¬šæÃ'P ðþš¦ŠÛÝêö\ÔNÍî´ä\%™ÜYšXÐ:|° ’ºôÉ#,}<wgßÝÏÓÇ_"BíB÷)G­c;hhÃUÔèã»#/.GG²:ÖÃ{@#ÜåÓ¹[9¾Ø§{Ç™ŽŠ#,eA*&”Ìì§Z±a­õ!ÁÖÞ‘ŽÃg a’›‚0¢¼Ög@˜i^a–Ô-ƒwníŒ>z›$ÈÉ-x¢@,8ÐCH\œ{YÀc‘<}½‘ïH ¢ã£è,ó s…&»ÂøÑ µ–)Ǹò´©Ê=| PuhžgAf.šHN±Ì¢uQ/e\ÍAëö¯GˆX“A5š8%€€=†À7B8x£Â99Ö-~Ú¼¾3Œç*‘p…*hÒS·U‚ˆ08úÃ%ï–¶ÃJT‘ƒ“w:Mz[®Ñ2¹r¯/σ’ööÛ’÷aˆö÷÷uÐ;Ù£ñNz1Cžá·“ð4º@ø`À¨ðvä\‹tlLˆæ;l ¬è[–ê…0í(*º]cÃ#2´6¢¦É¨:¿‚ª#±ä#/Oa¶)DÚoß™6–,rS¥²YÚ&ð¤vŒ»„SrÄ›ú¾;·“Q9I,3‹Ç…©´2Pe›{ 1M Úrâ,`z{L™æXì#E¥<½|«”Ù‚Î]ýЇ©fó³L6cÔÖ.rJ‚É#*`ŠJdVoå® ÅïXHcxUš¦–Þ©»K¦–TqI„…ˆÉ¨wNþ„`ú™9+[Õø5rÔm“ABòùºî‚;a0jCkޱ ¨$ˆqÔèÔMzIÅœŽrާöQMìëƒâ#,‡Ä‚ù4ÎËߢÍ ·Ü|µÍ\îDÊÆJh5¤æÂ­T IÔ£¡é4£³”9a-:¹À€Lpçïš™‚Qí#/fbTÎdË™™™clƲ¬Ë3$•c¶gšç½[rüñÅ$PÙ«…äÖÖ©ÈdÁú¥Leq¼*èf&_>ºvÖn­Mœ#,À퀽Ä6O8­<òËrLðié÷ˆ•»Û®ôxÒŒhlÔ„]{@mx¨>Ù>9z§geº8ÄT³:ð¸:O"Œf°&Áœ•ÅØÊ4ë«jI…"fB´ˆ miÇÎ N¶W¨6Èé›°Ãü–p4ÉÓ”eÞD)vz‚öß®dÕÙÂX>P:|û%ÜbÁ@J¢„—T²Å¢¢" ^%œ´˜]ûo1h+wn™|¶é{PÖ£ ‘´¸…›5;$·%ôæ“c[6û¾v˺Î!Ô9kOæZ¡TCQÔ˳¯§¬5“NIã1¦ŠPQ­¸—¸Ýn“ý  Ž“~ôTU£~…y‰ËR#*pª¦,Û#£öû(ÿyàÐzè#*òؤœo#,cS#,΂ÝüЍb2 Ó‡`jž)d#,HDrßÐ\!2h±O 쨖‚¯‚H4må,dAváiO©ºÓS˜·|‹orbÌ<rúQÐݵG(tÕ˜wà:`s‰ÀMé,˜d!üV(Õ¶ËzÔ5Öw­Ø:”„€Ž_‘“´¹ÔbΪ:5©5·KÜ#,ÚâÄ$%Áȉ¯]ªVØòË—"ËuÕÎØØjå§ð "è^O´¦0Z;69ê‰Þ¸â¼#, ®†lÚѺ̪µBZ&žP“!Ø*Æ¶ÍÆÚ0m#,fiìÑŠP…œÿ³ùaž#*çÚÜD.…áÓM‡b\Ô uà™ IÍ“ïrØ1–/+ï(“©ÕT™B=Yì–c¤ÍAãÀânWˆ÷¢H‹BŒ2xœDœbGÁ.ÉsÉ0wO€ÍtJ (oäÝÆþQ¸HÈâqkkªL;$†6öEíF¸#,Y‚3EÒ"¿§¡C~DÒ‘ƒ¥’BgÂYÖ1F0¦Æ³ˆ¼<#*LYV õ7Õ3Þ¢ÝÈz` E*Od5lÃv±£Ñæ¸7]ÜM¹»É»Ñ„ ƒÐìc¡Ø5ÇH(Ô#,°a!S© ,nRP÷ÙÛE Lu©¶ŒdS3 #*c$†' ÐTÕnS³àÂw2šT#*ÂkQÔ¸$Ic"9aMVÉŒÄdÅÙœæøfÐÑÙE׫݉iˆfš‚›…·;ýÈÁXC¬ÎˆÔ¼ÛŽÐ5Ñ ûWJwxÒ’½À´!ñ|‚Ügäp‰S²@‡û²`vˆ ‘,‚ŠEˆŒäÌ¢jÞ%ÐóœÇC!ÑŠÍî 3@<!±6â±:o̦ø}ïqë†[˜¬ƒmêvVö0ç¯È $Ödk)ll^¢#@“©÷x]¹Öñ#/x=R=H #KpaÏ9ؾò[q\ ¤Sç¹'¥ûîkƒ²ògÓQa²§ªž\ûyn¼7R¾\=û/(´x°HA$aç—€w‡ÇÒèlÍÍ0‚¡Ò7ÜÞ7ÒÄDš¢%:øÏÜÛ3ÊWí|:æñyË3d$yêh21à÷#,·bþQ@o $Ý,«$’À%¸n¨ G¬±¦¶0 °~îÓƒ ¼€rgýý†vºÈÌ/N(¦‡×rý§¬ 4|™„Ý D´§oû(Êæ¬®é5â‡\\Ç;úiª,‰„pjnO× ?•¹ëÏák¾Ð}ü;l—ZÄÏ0ý^†d`Pô®ûÓœ{䮿M5XßÔèPPKBnI;C³í|×5îßìü?í_äÒ‘ÓléÝö]†ÿ†YÎÇ€Þûü;󨡬 ô‹`¢ÄFÉEòû»¤´qþ8ßÒ3y™™gçGÙB°ƒÄÐ\`»¦ éRä`vèy¨õíO8 #/QÈóãýÏ`ˆ{¢†¡OtAb¤,Ph§Þ|~/wDõópV:⟧ߋ/‡þ¸~o÷³þ_§TµùâÕ‘—el6i[ý_aÖ…Q‚Á'ÌTETBO#Ûê>Â#/ø#*è.¤J-™²J4í«ü¶Û:û;½xõP2}xuÙüì\Ž„öP³kþû—áÕüšRbÙVdªiGA!ŸÕ¡Œ`@9#,<6lŒKÉmÀilmA&+ß P}*ˆû>p€,‘B8¥Wd¡EQT°”]{0c¿·‘Ì’º \î„„”^±~iŠJ<¬©ûÌùä‹v©E2$HZÔ€¶@ÀÛH Zƒ­èOûÜì¾4tÙS.«ÄÑòÁYMtC[UDßÔx¡L)¤Q#/a3B·ùr¯ÌU-#,.S›sH81T”JB Õ È­tWé‘é! „;çóD‰,:©X}S×.SA¤(±‚…ÁSZ;Tˆ(qPäf@>H‰ì¤9ŒA$‚ª@:‡а>|/À5’}h,Ó¿lm¦½wª+x’QkB1JvºÜfwV.ŠL>‡#,/o~õ½o40T H¢ÄH^Ó’T¬š¤Í’7( ÀÿƒtE²û;Îò•“•9|l~Ès6DFÛ#,¼$$êæn&Ú¡æN«R܉éŒ%ûXÑUÙæ £h„/H¤=F‡XK"?e>¸I›*|HTp€›ÉA ¸àjÞšï{Ä€„bùÁ¯ñ²Ê}»W€KhÀvçÖ#n|¹l{Z+ç €¯˜Ç©ã(Ä #*46ôÌž`ŒU}JÆÕËERÒY´©(£é!ÜG#/Ù#*þXŠ,Šˆ%EID#*„‘ElG"âP Ý YV*p2âüCž~I'ªÜí¾ÉSXDáõ=šÙK÷ÄQnA´£>àVVÚÐ<R±:Ô#,a¬TÒ0r"d&&"HG¨ƧÒ4Í¿¦ÉW¦/è·.¤’-êîÞ=*¹^¦åêoìM£ˆ´ÆRFX+üö¥YƒÈÈ7 £Q€Æ „ˆo,”rJÀ­´R„‚º”ÏéÏŒ 0jfÛM¦þŽúflƒ@› ×i~ ÙØªÀ ì‹’#,?¦RØ2Źž'ˆŠ¨+Àö>AÌžÌ/Çå?£'oÞW&ÚV’ç}TH÷²2ÈQÇÓñÎG±Ó§±_;Ñäg·õU±bÆ„cŠ0Y„o™ã˜b9_xغJŽ;Ÿ§¢ŸO]yxó^‚ûï‰àð[òCä•$…ó¹Y›cÿåÚZøO–ù«oúiì87Š™°MQ#*i*2€ Y]y#eµê°ÈÀ‰ȉŸ¿½6}7Ù$CGõ¯N»»ê‰Ò=Ÿ jÝê ëùÊ ÙTòjíiy鯰·¯f#,Ý“ÑBæKÚî .Ø"Êp!Ly×H’fC&ºn´p2AVb†4¶†›¨G{¡‚šRÉq¸L.¥ˆ‚D2ì°vŽþ-ÁëÃÇ+U‡å1rÝ‚œ«²hþÿ¦n㿇¼¥Ên#,"BiÇ£Îm·R{ÃÆ'¼,6ìãrG˜ï«UX.qÅï’â‹À.u“¯}¤„³Ëµµ‡èÝ>DXD‘DT>!ëÐ÷ÉßáL‘`¿×D˜aüžž`„óåÕTÓ&Ìíÿ‰'D’³t},ÃÏ#,GŸšç¦K%Y!·ñƒQš6ÎË÷nø›c–P[3ÐçwLU:> ÒÌ?™$Ÿ§çÞ EÕ5MWgÐ:÷§QâÑE£¬ØžšMT½|ç™ÈQê€H‚4#,j¯ºB#¸Ùš…#H‘ôóG™#”’¾%'Dl\ªV©i…E™\juód'mcÅS؉Çî’¢6ÄØ3ï¿gà³’¦ºbYϸÕs â#Ãdžœ+@ðÓãî;c%U:º¯ËGNeç»Îi;v5¡û*÷¡B@K𠪀yv-)Q_Ë ‡»ˆFšÆÚ¶ÉZ²A³V4“eTdÚ+--«J¤´ÚÅiš¬Œ@„c#*K#*ZEª1€ ÒqI8ÏœåoªTœáÃh‰ä‡ ŠDóĨ"Œ‚½6· l#*À Žaïl‰J‡ÍþÔ×ÄÜö­xÙ»hƒ\ØhŸÃ.d(`<46:â¨æ¢#,Bí80bÉ‹ e<AàU–E.mˆ …`æÁIN™&™×+ò„ ¼«ž»Ñ`‰DC7 l“C%hâ¡+-–š?®ævÈÈ¥m 6¡‘0°@WЬnÃ#*LH¹-*òè{Öê ÁU:â¨#$Š2#*Š©³j¥*– $€»Q^^|Ô3ÚÃ| ¹JŨ¢!líiÄÝqL™–7@€Éˆ”ŒÊ„#,ˆ’ M¾7‡·¤SÙä=™DÙ*F#*¡UJoU6oãL@T HÏ€…xãZDá #*‘‰$Y G~jæ±mŠÕ͹­Í®i•#/h¦h¶f#,EI(ÓH °Y÷æ~Sɬvl©xtÌÔ¡¹xÂ@#*!‘rNõ6 s¾¾/Ÿpý÷¾ïQøü1nTj°†p´no–ÐÍÅÂ&ïš+™õÈ<#/óâv©Ýv¥PÔ÷ÄÖà2¤8Z|d=§åîü¿—íþ/¿Çüݰ٫YdPò‰#å8eD «æb#*YÝê³Á/#/ „bª*¤0ÀÝém¼ß›áÚÙeüÑl¨WL×#*Ù*,a=UTšŸS•áÇ3Ìððî³I7@ÔèÒ…à&ÉÿT]yÒåô“á¼ }Ùk̨#/Ÿ[?®´:«C®™Ñ_¤#,³–m|[l½ZÈe1Fø¤:ˆ[û)9ôNÝçó¯*?U»`B&Œ@„ÃM(…E÷úÎC#/AéãŽíÙ‚xÉÒÛ¨…:Aû% J©ÀÛàÿFOiھ͡±Q›Áÿ<Ü.W x)™#,ýæÚGlØ(,ƒp±Àj!E10šÒíŒ&þ—¡:YÓõÑÚWfìÉ,.ÈôÌÐ!Ò3šƒWAÏnvÙwì΃(h¹A ìÂ5«ÅÔõL»Û½ü°9!Ðéõºµ88¾ºÅ ¶–QW(•;%ç\×®¸ë|>YL’ª„šÒlŸ¥²‚dJ-ŸššÄCòuV¡ç¢:Í!¦~¿KK§Òq Ó™ÕpÖmÔ û6ù‹ÑŒ¹ÿUÍ£ zÔ_ð «³¯¨ yr6ê]˜-Ëí¶ôƒ‹³§T)D Ý«™i\2™õAÄ¥Ä9¼xQ†_Âñd¶pcú¦!öó·ŠÐÉÜ&ή ðÛ˜²¨q«œ9k%–0ªq¯ö3{ÙÇ<oZ\ˆ(Ñ`È#/¶žHê Êâ㙈Åh]ïv“°CÌ@ ÁU=m&«R¡ë0y¨ñPM†ãÓàü8nØ0Æ”´8iÄåYŠíþæ¢Ò$!gùÏèïÄ ¨A«)¢¨¨4£QX>Ô³ïèyßÌI±ömÝÚîR‹ÖéQBôzSDp"¦jQXž¬Ð'WRyºûúöw&ji­ŒÅëy¿|ƒŽ°$*pGäÑLXÜ’“ÕÒÀ€FR#²AÐÏÐñâUWMeèáUÔXXXiœèèrø|Wû&œ(˯@¹F1¬ýzÎÆòäjzÜ#,(éZNÅM#™5ì}‡G[ï×^Ëà¸bæ 0á±Î·8Ä@m‹xh¿å½Cí‹Ã2†!ÄX‡’Øð¸.¬±_A`eíÇ+î€#%KMà‚å.L4ü7ÇG"cB’}E®‘hP¡Ú_¥×æ,4°tLM‘“Bœ«®r YÅcWhmbðI@#/ÔFùx$ã­“äqÑ0ÜÁâµÑäôuå[qÓµv\ôòæ#¶¹åpçqF;jÌt,ß 0ëf¡·U˜U)°.iœíÃí®:G!;í<ÖU6ø3CÑÑr£Ãaºt¾¢ëÛž>ʉl7<Ï2AËE’r –ô¨FNL^ç[:òk;PhÕÃg#,óØ+ÙÜìØÁ»ôű©·|ûE©ÚŒLÐ(+«vP鱆<{¯ÊßÚà•^«š Gƈ£p9#/äæfÓ 3‹èN·QälÊÄ0(õ4|¾XœØué¼ûqÀb쇈6âõ`»XAÏ+†ÞêÚn×ÝÑs>ÜÄßÞÓœÝãEwo z‰åê}0ý§Èúy%Oçtêp#*„¾”F}"(ReÕõÞ/´?BYžP;K².…‘áR±ÒW~;Ô»'˜=…ùxÍZ¸ ZÖLê>¸té“#%ƒØº<#fH<HE^ŒwqžpÁ‹lýpCó‚§-•ólÿ™ffÓn„ߨ”ZÏÔ#Höág3×-ªƒP‚€‘Ýˈæ5ãt=¡ªætì>šÌª#*Û¯CY½³ÆâöŽéÃN6±Þ÷í0˜7Är¹¬…Ð6m ¯©“µ­ ¹5ÊèqÙÆ½<#,®ò›\í¡Ñ&Ìyø Ü”&7sžÊ[÷9 èy”*²ƒ&ç%:ò"ÕT©b‚DÀqÞqè}›õä0ÅÜ73¢¡!ëµuH°ˆŒvi¢²YTÝPžêÆ'¿ß¹Q芔zøorg" †&=ÆA@šž9Ð#,Ÿuõ¬ BìS"cŒ`«Ã‡¼–€G)”qÛ·û8+fºÁçêÇ©·ÁÅœȢY#/8<»Uä•Ѥ! ”GuÜ0]ÍÖ7Rv‰=ŸöÉ$‹âÎìR,÷¢¥„:¤:ÔѼÔÔ¹ù÷ùÄ¿~¦¡´Ç4ä®k©}9büš\‹yÅsã¯FU`ÂâÀ›#,‡@þOVÍ¢·«§ZóÛP ¾!ÓNŸfMumP9èMiÈ;dí¥j Ð:Òs”D/$Ž»%‹U-4­+UÕ\Æ–F†l•®—6@wWRénä\–5 ƒ"øÚëÖ©!PdaÚ#/á`¨ÈX«$ˆ!¡J"(!¥ÜïÝbØÐ´–ÅA*;>=¶V4Q#*HA"°À:7Q×Áµ$hjkÌ3j”¤Ö´TáÃptçÇó¯VÂÃçÎÐÖgÑ‹Óæ#/_Ÿ”ùó÷“Z6§f={“î<”JTAðõZ©€m%Êé`dÚévKê!êa '¾ÇD3ÛB#/ "$…àêP:aUï·d^3ó•GÆŸkÖ™»•ÖŒ’?‰s7ÂA…öQ2"ftÀLO'P¸ÓYF?ФƒÃÂR»@s[)ŒpT5›B°+)#/gvàbXk#/ e3,5Ñó­W©)³n7^ÑVšÛ±<t€Íû#,a2@ût¬°* ¤6•#Q-Ƴ{@ªÇK´öi¦®[O-¢w¡æ„ú`é­òü;ô-ïq"·§†xnëFµÍpœ‚ˆ€¢"T¥°…T)vÖí‚¢ˆYb%,@ #R"–K>fí'5mŠf©à,Ãé@6xÌC𧻂&y#/6 â ‹ ))¡$B#/C\Cè&QBN¿&ô#,Q]Ÿ§G_„æ¼pÉ!1ßÄ:ó®Õ…­´ ³æÓûþ†ÄE56Æç]7€dÁå†àtŒö>ËѰ Ò§‘_ƒ™¯%¹2ÒÓ-5ŒmµÌÚªªPcÔLÂLÉ“#*ÕÔ¦„ã›<¿èÖG5âÐÏ)ÖîNÉØËióổµ[Q˜Ò¡æÃK@¦€PH;˜Ó|Ú킞#,I™].½Õ!„–²r6I¡¬@D PE=í¨Z3䄪£EýÜܽ‰âü¢OU¹›!¶¨õ>ÞÇ£.eW˜#,ý&ù*M§÷¹²ƒàÏííáöã¡ÁÑ7±b,(mÛEŒuÆ™òפg/ÎXíñU’5äÍ•N›ôàN}EQ(æQ8dã· ‡¿ŒÔæ“ä4&š;!d2¨êF¼»s€ <ÕÌŒ'¯™À|lêœÃ<}—½¯ ´݅$¨R3¬mFõØëyêúM¶ðŠáÌåܹÂ8)ʦÜ$fœÆá¤RX‚àœ´ßš¨Ç÷ó«aÛI0cüºç °Å¬e'_“ƒ)&ÛÜ[®l#/̉k—dZÜ4›¨lñÆ…$$ Í#,†¼jU#,$ CëÒ2¤a2u!ó  ŽPàˆ<‡³P5¡B^jÓ¡.rð¨#/,2<²Dâÿ'7»+Ø|8ÃãDAfx!¨ ]gr¼‡2Ê=@+ E×ÒVb ë‚¶òÕ×Õºï1Ù•œ6×_µè#/#©€V¡äàliƒ"a¡BÒ¹èE­ÜK».BqÂn]ÙPÜ0ª„¾¤ƒÆÒòi±"›Ð`”  6Æ1°"wœµ¥s…X#,, [©MD2–çVß+«¶Þz¢‹(ÜaK©K ;î·dy'9s_f/ËåÔ‰÷{jóÕ’6‹lJS>,’î1YÒq°§tµR}à¶;Ã^Þ,õ[èh"‡³l)(‘›oJ…A-¥9>“H®–0›€ý–üðdG‹'‚cw>SêÅ>óÕ 4&IƒV|wu@#ÜÜýD—Ð’ÉZhAòæ¦W7qÙ™¸ù9&ð${`î±®Ì-"K\d6s>7rÉ.0åYB¹Sá#/Ý EÆ‘ÒêÒÛ<8"Ÿw¿M>ßd'Ì“I=Þ‰¹Ë¼ýÉ 0Ó¤\öוýÝ„`Š4åÔØ•!ËrÇôu³Ò'Y;x‡#/0ZMŠ("•TŠ0dÛìð?ˆÈ¬‹"1€š—¤‰¡R#[§»c¾þÝÉ›¿Qöb_´Î­.Þs}íý\Lmç»ætì¾gžªŠI>J‰žo#eBdˆ3àŠN³}^דÑfÊc˜>½MÿÜ~Ö¥SB˜N¶Pˆªim¾¶ôx×_¼¯ÎØÕLþ6D¢R6Ú,dEº”Ɔaßæ³8-šèL¤VbÄQE0’”£!B2]ƒÂÕÒffN~–x”+%$Š$ÿ:%è¾3ì¶00\ bšäˆÅ‰<ƒ¥Ï¤äd@„Ë¥«RVuk@ô¦ëô4÷+a¤¬»›Ð&jƒ¼Y~Î Áõ¤¨ŒU¤gBB6Æ‹ðúhÃ#*ˆžV˜ÿD{ˆi‰o&¢‡d<4T#–V‡†RŽñ#/MP“ÄÌÀ R½<¥UMÅCch,#Ô£dëÎN3k(­lÔ•ÇZ¦€ò1ï”Æ¯éˆQ‡#F#ì…8m&ë•öGka¶²Ž=xÉ#X°3ç‚Ë“Æ<Ù´Sr$ª£¡QìsFƒ…Œ_&ýŸÉ<ØÖ„FÏ|Hšì›ÅåÖ´|þv%ŒÎ ê˜kSZ­Ï8›h ±“]-0-f“K bŠhÓ‘Ü05‰‘ŠJÖ?f“Ó4`KXR*B4Ô±ÐüÞ4l}5ÅQœ0°>×é êÖØxfk#/QÁ5éÔ´ Ôj‡±y2·BFN´'H mcæÈÔ„ôçyÚõ4© ¬±²ÀÆ 7#,¹Èg:üÓE=‘F,憬ÂSGK*Ó¡gQ‰#€ÛìѹÃÞPFÊuªF¥þgˆæ«z«Bw;9)Ùlœ—X½áä•^®Uwn…1áÔÄÓª—§×Š#/.0°Ñ¯ùùŽkðn7Ôºö¸¥J‰.<¹9t‚¢âN×Ñ«Û&5¾×£Œ.ðÎÈçq!*w~ŒÄXÚ£cü°t á‚;ïÏPËY»YÈ¥¢› ½ÕõM«åkz·Kî¹.jke$ !‡R¹ÃWÊÒ˜7Ñ—%tnŽKQ^#/(4”¾ ÃFÎ…øüBh±F…¶ŽЭ¼èÅMõ§ &‰–SBRkFæƒ)&¢S#,ØhÁ‚\#,#–#,.]ËÞ,Äû0‡wI àãm.[¼Rs:èÎ å­™+IÁ‘ ’)Pv0ËC"É,Í%T´7CGƒD&Œˆ*ÃCv­ØttˆGO­ÚoósË|C;Ÿ(¾qºº•&g•(uÓX‚’Ë‘{ê,Ôc R1»˜½Þ®#/‰ÓB—´|‘¶z‘¸Ã¯~|6¶3§d^µÏèB©Á<#/ÀˆsEÉ$¥ÖN8r(‰TÁ($6Ca79 @Õz6—þŒ`]Žvlç#,zS­ÂÊR“H,)¾8óå’ƒ‘Ü[€`±ÎÒ8%B¢4D:b޲!"ï26ø xî6…Ù”KÆñ9³ÓYè&Ókhca7™–Îowc•!ÕÀoõ_‚Çch™ÖÖ–jÖnk æã]›ÖvQv%#§=°k|9ñiËÃ0PQDÑ6ò¶@”Hû›kåTm˜A+⪬ÁDÛôÙ±>¢#/B-Ìkó–Ü\°[>}ñ—9¸ck‡Œ½IÍh×7füß}©aÍ-ë„Ø–û‚!†™m‘€ëñlÎww(1T£G7¶LTañ%˜ B8_ˆS¼;ÍÙnÈþê&/¦D¿y¿N“,ìvt#, 6 €)ÅŽÓg»Ë¨zÂ{w8œ0Âây¢,EFÌìzD´ ¨¹[%ð°IŒû½Ô±X[ØÜ@ ŽmÍm¬Ü•¦ ¹1£¦I#˜„jšЄP¡SÏ¥FŸBüuJšD€c<sM†Îœ(#,b Û1T‚4ÙÄ2 BôK6>5¥Ã4L#/¹Å#,ûøk #*8J/pŒà¡¿^€!ƒð°ÛðouDƒkÐ~ÿÁªf¯!wJ¾ß«_6gæ÷Dü”Œ耚3jÙžÚ×ßj¥ï›Œk‡d?Š76MÚ—ÂheñkµXÑ€,Ãuøª‡9#sÙQ¼_Àäe¢™™zv™ t‘~)s@ÊSƒ¤ÉfeÅebÛÎnüÝÏÝg‹#* H¢-ÎÙ×` ¾™ç§©ùÀ„!(Tկ̹âÛ¢ j5j6×E·+m±µkF«úëm¼kolkUg]iu»[龟#,xy­ÜOE¨ˆ†^-bˆÛ»*1#/‡šàì¾Ð[YvPø ?aóï<ƒsÂÂ÷¿dûñºm«~XÌD#ˆ%)2S1š¥,Ì•”¦˜¤Ú¤ËIúÝIL6´„ Љ¥L ›4DÀ¢Úh×ÓÛ˜d©1d”JR¶hS&&i™)Ti‰¥Kèî #bÈР¦4’’Ë#,PLš*©QE"˜EcÉZQ²ØÙ L’ Ó)°e*3Y ¦VLÙ‘½ïwÕ_ZsÕÊžD9^YSzó)eB 29˜Ù¦a7åciŠê]¢^Mßfcú÷_gôë+Hqåg ž¬›f*\ˆÇÀä¶&°²ÀKJŽÝÖMN³† MàºÏ¿pS(hÆô–à3µ.ÁGVg>£XvoFïCEF£?-–LOSŽ!ð…ËŠH8#*>M‚™—m3³F}‰e»­Z™ïŸàN™Áž¶’§§ësdRÄáÇ7“ úDäcÓæö¤œ¨°ZÝK^î;$Òm°ÆR·#U²8†¹#/u.\€ƒ‘¥ƒ®,„$dFÚ#,#R²kˆÙ•™F(ªŠ"$Og{:×|Áà&&fh¿eRã&DW)¾SOÁ¦²4í-ÔM&/–™_<Ò³ä;Z>ÓZG¬©‹S%™”IÈá¿§-M?Uu;rö;W¡éù‰íi•#]9ì( #/FXL Evì<ÝIóÚ¿ZCªxçmG")’êAÉ#/—ØÆ‹Á>!µC—Áx_âýPÑ7&š'LpKrÅ%Œˆ»r>-õ¢÷rºÁŒøI*U‡Y¤Hb Ø#*›#<äÒ3äÇêñýx=™‡ÔþßµÖúýÖ>k§¬ÙÖ!Œ¼~ª«Ï‚"b8(ܶâ°hÜž$°™húz댜yÞϯ^®%;ýoüÁ¦ƒ³M›1i¥¥ð‹MašƒÆaG–e´Ûµ8ØÌ{ÙÙ¬j ߬÷Å<OºvÉ‹îmNÊ ½Ie©ídÚ›»®Xã;o°‡V9CV’@¶ö’,7ÕÆé‡m ‹ “ic³4X¸=·œëo·æüàÚ÷l9Á‹PK¢ÊÒwO/¨íã²ùÌiË~ÄOÊ'zt‡ÖΔÅCØ·6iàOy¥o¯4º´#,²max5É5„Ûa? ¡,;b“—O¹ìóªrÞR,½¸ì{ <óá&‘Z)í õ`¯nu="ès|nÚ<Í0!@Œ‹õ#,3О d]“XšÎNÜUE*7•ûîŒå8#/Þ.ô&%óØÔ½á–ÚH›Qð|Äü°*~÷®j²û:5êž»ü»<y#*r6RE·|IÔU¾­N¡=µÛÚo®»W¨°Z>!8}Ÿ]q½ÿQÑi:R$àô ¨Ö{|³ Ðéva±µ°}”g²_1°]w¢^Uh‡KQÉæª€Ä”ñDö€"©rPoÛ¥9ï;ÐÕøž3rÕçMkgœ¨à<¼½Øù0܉:„§ðÒ¡lÂS¤x†!¸ãuì.£u#,áÏ—LU5Tn)ýü±ÚKBð$EMnÜP–tÓZfDÔi𓬓”:2z߇Ä}´›s%×i^ý:"ºŸ¸H@" œ 8•ÁRµi¥#mÿ¥/Ñßc¿®ÆC×éúÏ5Q‡ÛU¿ÁîJºŒÜ+)@<ŸcDtj1GjF8ÞV\ÌÙ­1¶dÕD¡•ÂŒk:7¹¬Àm?^31o+ŸllÃnj7Nf>f˜óP×ì„©wwH´úyU.B4"b^Ó o,¶c'–R<8s1Ú²io5¬Dâ­dZ.Œ7™3#9Öý™&ð¦ÕÕ“Pçkoœv»²pòweÌ"Ò–ñ?ƒ5£ rq† ]50Îlcªtî)º\,@øuCTI¬3>š÷ºD䂉™¨ÔÓ‹IíTbæe –•Df]¨²”& M) ¹$\]Åqˆ”h\^'jk["§acqó§Gìt!åî^ÔšˆÂÑ’ï5½çkÚÍrvìb€èù0BŒâAm‰'bŽ´‘çS ?ƒGjÉž¹¹®œ'—#vØFŽ®ì$!qvaIËÌ&*_3Z8†%_WhmŸ\Ø8©!píµøó€AÇHz7hFág^®±§7Q$i‘Ýé‚ uŒ.†ìÀPQú³£Wt«Xd-%ðø440i­Õ⩤vFæÆöщ“¶61d>ˆu¡õ#,9*>xï¼Ý¬.eó¿Yáñ¸!9Îvånª¹Œm¨€x¥Õ3Ú~™ŠLi34'ÃMFÅ,îåã „Ë¥®Nx̵â¥ÿ7nb`c@¢~Žù‚“"¢¥àÄ;P›e“e)Ô£38j¥Š ÉQ„&ÂMþ+ϺƒÓþQ¿dbõÆ x‹@ìIÑEç*4˦öaè‰Z»ÆøÖ+y3­cs7ÕõSÆûÙØzJHÚœD«±‘vÎÑñ¨]Ýw¿pûôà<ssížç[Ä‹§C}n&9=Û‚ˆOßé'Iñ¡)0±Ã™­ãU9ßÈ>q¶pI";ôÚõ[ß5ÉÙ¶´o Jf…ľ÷U-|'—Šß/sKtyƽޡ*³’tûÛss9ØlíŒÞÕ(O˜‰åTîžöj‰+#/J….¢“‚\<…ƙՑÖóa#/Áæ7#,w2f£å6“H„#©ÕH3 ðÖÑ·Ù¦l4Aô$ÎÍ3¬Ì09¤1Mª† DÐÈ%­q’d‚=ùhˆÎZ]0Áqˆ(2§ì,H¬ º5 јXûé¨"#/—0õII:mÕËø¬ªr`iYݾq![jâ*És-ŽbbT>Îåí#,©‰4€HB,ÊÁsY#c`¨Q¿&NëCÄòaDEº‘òí¦—«¹ª`˜Z¨R¦\Á­`NÁÔ¶˜Ø`8CA“wÙ­I®èy¢JMÄÁ[=`ëD„U2dÜñ+}UlòXéÉ4Iª+Fž 7…³¸ŒrûFËtÅ.#,ºÁkKGMéÉcrS^¸Ñ½ÙÓ,™©ÀÄ$lj¦7v„4hIt:h@„4Þ”§ë áš#,æíD•¢-‘f™­uÙ­DÚݯÉÁ-ë!ã*}mßÝ3žÐïf›;Vï8"ógX=é&2ô™á‡&YZ몸Ò+=>UˆVÑy"žv᧬9Y|¸mºbL U±AÐÔz\];æY¡š‰rï)²¦EW<&zár99‹T-JO­5Ì,Ì΀ᅫg+m‡lm±xåÄ+æV0êè¶ "¸ $3‡ÕÝÞþø¢ñ…t(‚1qM&]9ûÙ.2Ýó™tjFÛ­pó Ü#5&©_èãFäÙò¾'cdÌ}Ã|GÃXܳK#,c×)Î-tû7+­ºÍ7׃{ÈÍãngWZÌ8°¸Mäë&Èûa0êÞ¤ÄÕ2†LÉLïOKTøÃÂB ‡j×OS¢¤…k¤‰O.a0æ7¦²‹‡µ2RTócºÖ n1¾vvGC7­Û3Nl̬Õo#/Þ­˜Ìeô´¬ÜÕ#ϯ5X)xùçŠÍãJaCœËõ&‹s¥DÍEÕU<„Ò¨x“QâËñÃÖÀ¨®"6H<Ö凌ÁP_wã‘o„kŒy+m¹ Új8Êàmù<k$#,&¨3 9¶jÉ«ˆÉYÄ#ÆàܺÔÏašÐcÁÌLšÜ£G57V䇧‡á&¨6«zešÌÌÔèi$ÞknmÖfMÛ53—N½Fcelvj˜1<“’‰ÓD¹§MuÖrÈÛ2rÄW^ßU4öÐØ°×¾ÊY7la;5ÛFr³«U>ú¥á°ÙmdëÞ gÃ’5l÷(³² “äRš¹ÃR˜©D¦ÈmÁíñ®Ú9ZãE2ò@ÓŽN7#/ÆÂ1Ã8²˜pr9àâÕÄ#,ªÁû‰Ç8Q£˜!9…Itw‹Rö06"K@J#/hØ”R«’–4ùi#/d†E tÀlV(yaW›I’âIÂolfjWÞÔ±ªÑIÑT3|óÅ$ºhÉ*БåpV1ЇM‹-UM0ö憆IjË£ODÓj8*ÖÓÙŒ*ížüB£o]s)ÊHìø#/ƒÀ–—¾¨ÕJ’-ž-­GTlM»Lõò¹–Ó[¬P¥FÒR•)%kcezÎ,³ m¾­Î˜BmÎf7-aa–629'È!¢ÆÙ3-àðàlë#*G†4aäÅRí»èÒ45´=‘t¦ç¡Asɲ‘QŒbõ0„æ(àÑÇàPCvwꎛWg­1ÕDžíÊH¢$P8 ïuCÁ’ën…i+åØŽ#:1oqGÓ™–d±3š†ÉXñÎ!i4`[d#,zU;0ʡɅ<i«Hî Ñ›³€#h¹CBh˜ƒÆŠ\‰Q†”¢ÔxU)DÏehÌàIB…ˆæ‚Ýà z4‘´0!l&î®™©²Jd0±Pxë{³’KH¶­ 8iStÕâÍdI«'6mƧÂI«-‹–M2ÀÑÍÂ?²m&©&÷ÌtG;ùt£[;Ö#¿N$Ò›v¥)G4)yY£’‘¹— &mÐ$#8¡¾E×|`]ê¢YZ—*HnbÁ4ÔgG§!é™rðõÀWH ö0ƒÒÙ‰¶P”½8yÆÙÏ#,Ý.œ<nÕ“´:œ¡á÷]çn…¶‡Ö#hå 6Ü-#LÜmWœlÌkJ7sÎËt9¹Á96R³dg4C#8µJ.ô£cèrtÅÕk“™1^%ë§Á”ɵFq[I³‘Æ5“#,—áq×k“L1c€D‚ª/)¡#,³µ °"Ü1±ˆÞÕÎk/)‰Ã¡Þ¶xœwÆ4Êý™0ÄÎ\b‚fwvq5¢ÁT<§µw¾cÖ‡&ù8MÜ®7æ2áÊ¡Õà 7:´Á’ÌÈMN¢iŽ^F!7xÀ[Ù6B˜&ÃLŒÁV€Á ,¸`£Œb±#[x¼£‹b óh Mw;ÃŒj>º³©Ð§tª6vˆð2e‘Œmµ$`1³„»÷¼~Zæ ¹luã¬kÖmד‰þ•HÆwu»PÐ1ìu ¬`³ÞB8±œ|>[­À #**vBú†ŽLðÚƒò1Tm À‡Cu.)lÀrš÷¥YK 0q3$1¹2I¨¦{œÉ `Ê-Ó|¬'°ÕÀ*”DAÎQ`jÄHÌÊÊÑc7nܘ€ßvä†0˜Ê4:b8Bc‚8A ª£¢#~§$(AÝ4 f@M¦óc¥ßVqAE&HÁs2ÒFîæ“.S8Éq›Ã\¡#,ÆDLºÅ1Ñ‹ FÃ9²4SlÁdÏ”¨*S»Ž$¶4@5eöJ‡ee°;8nÒ`m«‚èkCfBdê`ÉÉ…ÓRR:#*k¶R9kcŒ%Á†,Õäw€·jI0–ÔV¶pv6L©ii$t4ð¡RU`s †ÕàØÖ“¤¸àM*‚#*d!ÆK-¦fÖ¯â›Iº«;ê»_âI„TMDÔgxîÖPŽQCÉ)D`"5þ³/ÕÀ=¼Ü!Æ-¨ß*ü¿—l»\#,cws;¹$ òª7Ÿ1þ Ì`“šŠ±AÄÞÌtn‘OáGœm„Ò•]B‰p*,Uc"!œd#*È#*Ê»“#/<à´÷e¼Áø×¼ÒÀi°Qc‘ÚÄŸ:9§m[«L>YÍ” }â[#Ÿ/<àý3²ÛI:Bv^æ^[LæàÖe)šÑÆ2ný…´‚È´¥Xs5§×Kn)V«¾ÑÏ-áG9´àÙ³X`ø:Õo× Hø¼ÌÃÉ&âm›ÔÆû@äŵÂQ[Ès´74á„d`ež6œBûÎAÃ6NYe¬ðÆB°ì.Ý>):z`Ñâr*;Ÿãl .ŠKBˆ“´èŽ'aŠDB$‚PGp<öñ¸m“nKDU3n“§7‰åÎëŽï<®]–·ØÅ™m¬šõW­.®›^*Õtª\ÐP(l¬‹!œ<`›,7TAø¯žhP;„ÎË«“ãÁ"f&A¹éÔÆÆ>µ¥QØNÇ´ÍÁ hÃfÝog³W€)šâÑ×1ÓïÉzÕ~A#*6ûöƒHz`Tí¨PUWwmÙn»³.nºn¨5sdõÂÈBÇÞÕ0‘Hí5]ôè/±æK*¥ì:ûHî”Çj¨ð#*w¨p‰ú0 !ÍgÌâ‡>•ö^p9î ‡2V¤LŒàŠ{Om~µwi ú¬j? ¤È»øŸæ3  ír~¦Â‡³Ïöûý§¨áÇp]¤/»ÝÃna®Z¯@Ú´E²Ò¤©W“r©/;u»ÓÏ(ͤˆÞ'Ð72à\ß(cÜ6Í”‰§4˜ìF#/i‰@ŽGÁ W#,‚F«QeFŒ'1D%Á‚Ö¶ÄDaåû‡Ÿ‡8°ë#/DJ†±¥{ÈÄ3#*þ$à~ÿ¼,¢ÞD„,{ «’ö Äù>?«µøÕjm )5±llZ-hµ“ˆ”6ŒÓ2Ѩ*5±c^5ñ«\ÕÕñ­@ xTOzïõðÕZ€{@ï" –ëSnÛõw­&A’ð.޳¶›#,]¢…EFšX?‹wB"k\" ÄnŠ˜I$ªºj5Êçekã¦íî¶Ü²öZÙÓYnIâë2;’T9'yAŒ^øb»ŸÙNC£ô?L"[sŽK»¬6®ŠSѺàð{h´™ÍõÚÀv G²hÐm°½X¨Ñ쵈˅†òOb‚ug¨i/B`ÙÜòç•Y…µÖG‘¸A¬˜­+¸Hó¤}L=§#/°ÒÇb¥ªšƒ1HÉP¼*DT[ƃcb˜*ÒWdÆÌ¥,€ØAŒ…°¤–ɪc%4ªAI”G=Æe"fÆ83ŠîPEbæ÷Â$x,»)áU$‘VµRYFÚLWí¥½ûæ4oQó Ç’vîɘznøÕ`µxãZ_VhÜ$Í11T1¶4>;të­‹‘Hdƒ’#‡­R—#ÖˆVºR6‘Ôf2†™Ö¡CÛµu@ɽaÊCdœ5*NŒ–$þ„Üa¢ã6tqPƵ5Ô1˜qÈ"Â#*°&r‚ì‰dÈdŒÕ•çF-—ãæäÉ<aÚ1žžâ¦#/1I"ˆ–À«(—AAt¦àÜl}ªK® ¡J~$BÖTK6hBðøYvÄ#*ÍU  ž”2kþI˜2†>®ðž±^¤™_:1zgU#,j–a²ïòÆX¬e?-*²˜ƒ[èêäaæöpVÑL‹»#/3‡®¹3ð)M9 LRâá:ΧGÚr.C¯8ØŽùðĦ°)wQhÔFŠ¡Ý©7¨6#,a§-»"øZZVÖj(-„Wù7 't9`vhU#/‰¶i!KábÇgØÌ>&ƒS2B¬Hb‰P¬IClor˜ÃÄÖH8 ¤áÈÌæCÃà\D:}÷Á„[øA”Ѥáš`ý]lŒå$Ç#·c¥ìç1¹ÃäÆe²g3Œ,$B>•‰®´ÒðA»Ò²œ-¹x[IH¦SR.†B6¡ÑÍeÁeÚ¸Mæ›%¨è׊.1#J ÏGx¸‡kÈDÔëy¤YÆYÚ·¦4!ìÄ1›#/#/ ÄÃõa0Š0Ù Yc¦Œ£vêìa˜h$0Žˆ¥–‘â7B…0ªHC"€…У*#, Ì#*»qY5oX…ˆAVT¹uÈv foàä³6掱MmLÔH¹Küa#*#/ #¸#,›‚ÀcÐuá¨|/z¿æW)§Š,OeðVéDÁ¯Ì0õU€³sÈŸ³:𣥰†k†;úmk­C§ótP,LBˆ”z¨ ¯W†5k±v*Ò^ŽIÁñSA…J%UTj¥1#¼µã_Ò[AmFÆÔZÉ´jÖ-¶ T–ÛWíZ–š"ô=êf‡ÑC3ͪòT¬yë°XÓÆ/O®i+]Ãî'}‰ÅÓ£JïDVÎñöóU祔¡¾ýⲿ¼¤Ö#/Ü[AÙ[Äu 9V’W"†É½õÓ†³¼J6S=£K#/æaÈ}'Râ–[jS®V›i80Ù&èfVø»–½”£UÒ–1›6m.tìÃI€¶‹¶Uxšpȸx©Š‚6ð’Âæo$Ã8Áá‘å2=Idæn!ÕøšïQŠÊÆÛÞ¯’7•Šiȉ3ÌðÍ™ ÛœTÉ•«-&ºÄc¼ç›h4MÊ4m®b˜ßSœn© óǬÓGŒ¬MW>:Íœ;ŽÆ¸DAÇqIÜàOy!ÈO ζñV›”äcP^åP…ª¤Æ&êÙ¦#*ë[t–ÖÅD6Îkj‡©§ÞæTîí©BÉ- 2u‡B·Ã¡Ú2ÌìúŒÊÍbp§k’LßVw½xf;œNÕo‹L’jV 2ºT¡6ŽE¤"K´6¬’l±äw$ùT=ÐûS##,“bË#,C˜`¿c?›9L“¢g…n±Q„dMJm/°BùV’Ô]XÖ5µÙTª[›vS-©¤¤hÔ>{}·–•e-0±‘V£#Ga6#,oª&‡d˜X%‚aÀ`@’‹¡Aa‹ÒH,²$BH’@‹"¶5œÆá@J!0`É&J6FÙ-éUÕT¿¹­2Øø(=H@‰Œb µcRAmMwh»-Ò£bîêô“žR²·d­Œ‘¸AvAÑÙUmN]zÏ:ínóM5ãn†®Ö[­˜ÜÝ“zeÝëºÅwk™›NÓÍ×y•y‘¹¹![©[“Ï+26LBE$HÀ#fSýÚd¤HáÂ4ShÙ¨@ÂÔŸ8‚Ü‚HÀ€“6Ì¥(›+bÖl™JYy]k¥¬RÓ&´°Í›mO»¯§oŸ¯FZ-P`±©‰E­&ÕEj„¨¶ÀHŠÂ-ìôyÊÑÉ:u(üãs^ F¸—öëb¨ÖÎA2=AT–ƒÀâÙ`E$ nÄ¢%ŠpTjw#,#*p‚ùâ;Ò!é;ÏeƒÕž'œ„aq×§ï0 aÛòã!u4#,#,}Æß¯4OŠ&(w#/ÁvÙÜHHQ#/áTÙ„Òfg/!Ň~zfa@ÎV±nЉFßÒžƒ’‹‚&Ze³$:ÞxÔíÁÔ=z“aŠTâŸkøYP:˜·½*UPI*#,”ˆUýè€+M‚*Ì #/Œ¬H#Iuêw„íØš˜éÜ‚á¤ÚkICú¹9ñÒ—öð¹S•O͆úZ·Ù&é†ï†øýNc#Å›aR•lZÔÊf>0;Ñ Q5z:É $@¹´†îý_¹åm{ùìM¯¸¬pÎÇ0ŽÄ:@0#/Á‘+f‰%ƒÜ… Ìx“Þôsªð¥QAã"ä@EX¹qÆðxRµü~2¥œÜ¡0¦3p0…¤ÚÂH„ˆÙËb%(v-LŸ¹–Cd%}±ƒ]Ù÷(KƉÜâ4@Ý×$årC9œ‰r¸(…ŒHjÅWü>¬@¼'5Bxú¾äÔ–¼x4´ñ¥­CV‡ Š]j“Î^pù$@"#*Å#*" }›Õõ®³Ü}Ý&Æðч›bVO³0BÏ×€S#,pC¯Ëù˜WðÍÚ§}~­­½2ôì•£ZCýNꊲI¼ë¦š3i=º×DHJMãs[L‹0š’k$ŶyM­rY¬¶2–Òl1´šIã”Ó4;t²™4ÚŠb–V„R"_•®°¤j²™†Ëf‘¦%›Eµ5¶hžœQ´T¥Ë¦Ô%õms]q¬Õí×cELBPLÍU˜•^§R­&¶"-,ceWð6Û¶¾NÈ›½wl“dQkDÖM[m‘$Ò©«[›­-LÖöWI©m½zï#/h›M¦Ê)…MX¨ª[-&ôëZ¥j1ŠtVlÛή¼îL¦Ö™#, \×m5I¼Û5xÚëJ%V5^\˜‹SVÓkÆÃ^?[ÉT\xå“ì×ì[MyøôtýDéD.ZõÙ?OéøO·ÝÓÇV'Ìé&Æ4èG츥É&C§Ù4ŨŒ†~>½ÞÄÄ/î ö6ša«bæ€{a”]“¬´#,.î´bŠ#„Õhï΀@›³m¾6Úƒ¦jZm*f›a#*A#*… ìã¾f y $ˆ(ŠÙ¥lÓm{ªÕÒÖÅJb1!f’ E*²¨KD¢4m·lªîíŠ-%‹cm‚ pŠb*·$R(_0êQM)Ú`G^â€GE ©°H­E#*$XAÛ-›1,Å c#&%µõ«¢„£R“T¦Õ´Û6e´›l4¦ŠT¦ßJÜ¡†ËQY¶%£’”i¥$(°Úm”¥‘6’21°ÌÆXØ*##/Q)­šŠRbM&D´ &´¢š,¥”ØÕ)l)¤Ê”¦DÙ±‹E2Y4•$¦)*Å’-J&ÔmfÓJ¡%&,™I„Ó$Ó%K-SlcTEY+E,LÚ“$‹5Z–k&MS%¥6Ùf¶¤­µ|kZî6Õ&Ò³VšÉe²K|&ÐÚ*Ø‹ T#*#/€0Š"T* ”Bë#C"Ê0ÁF@M|ÚÜÕ)lÔjÚDÖ©"ÀST¢&D(Ó_i<ƒ6ámxVJd:è¬ìÉI>%ß9çTuäºÎ]1“:Šøé€fÿ+81AMÝ.¾ÛŒ¿Ö¨›Yô|lè?Ô9#*Òݹï#,-N8eÓ¥ƒäÛ_Ì-ödjƆ£§xüI‘¡±Ÿ¿°ßן1™n#*CÙïòÆÊ#²=PÅžÐÈ9,ŒWåá»±®­uÝ‹f€Íµ”1é.ŽÍÑT߃’”nÒPîäR•Úb]WÑ-|—BÏõj0÷fû1Áìë”:ýæÂŒ„P’ãM¡„†ò@¼À§3™¬$4Æ äãÙ›l`Á¢K>`©&z€zRWê(-ç#*©nt%ÁïT|š®n£¢k#,N\‚•¨AR¿Owl°¢wç°M±3‡ÜhTɵÁ±ü«mÓÍNßa?œ#/$S\P{4Ì"„$]ú|ë¸f_y{è„ßsšU#,†Ó±±Oh;#JaÁr0™È6&"ÇØeÀD3P¶¼ù¶Á¥c¡Ã,€°JKâÃJ®§O‹=Ý©Í49¨ÏÕð£úô×v¦s3Þ&™TZ‡ÑRä`ðªtJZ~éÂðä+g~½NC|À‹$Œì«X§ jzpßy"á†Ùòu6Ú >4H6õÓG"Å3­Ì>|FÆÞí”q„s³PÕµ"ˆË€µ©ƒDê~ÆAfaÇF >‡JÙ]Ä@ÂöŒ$@ï¨n™]\RN,T˜]À#*±¶ÆÕF#,·ÎUÝt”Šài\´˜Bd:nɉö(TP"¤Š%dN»E—H1(œhšï}„mÕÒZÂýÖ#/,ë÷ãÈëBȬ$Y:îp–ˆô… VŠ*MîÆŽ €Ø‡#£6U¦«¾;1´mΟA¯ÐÉÑ#,¡Š~<ömǵPdbA<ú ¿Åî{YëÌóŸ­±å][{éLcØ:ÃRô‘P ••¦`}~¾w¾è3¶›ñžÛ¢ÙÿOð²X#/³V¦¾óÍ0bŽhÜÅüw¯;'ó{;9ÔWªXÙLjñ®¥â+tŸÌÓ«-†3V—u)‚Z]TÈÞ±Q4#,5¦ˆd™l#/Û´C2Iš¨µÃ˜#,¡±¡rÔ±ªÄ(‰b,jF”ËñëF#3†¥° Ü‘MœUV6pãPbmÊíRœÙÅA@Ä@¤––ãXâ–*2ÝÆ…UH¤T®Û¤“KV‡šEÑteS8¨¥!®)ž•&ˆ#»#* "ýîÕ'”¹¤çÌf&ý5¦š0ðB)Á5Ú5H'rm‚÷U„J Ó¸¤hÕ%c˜àùèú˜#»„ZÕÛ¦IR»=[Œô18žˆu79…bÏ1ÔÑ;PmäåGÓc]\O)ç9â; QŸpÖ!V/Ð,²+h µculA;rß >µmë)Ýmu^‹ÉðvýSæB(ëEhع¿³vçáÑóúH}Z‡Án„1¤Çîš_ —ò†¤5!±‚•®“5…y+n->.µV-œ›ä„3y‚¯†ÈÔñ–’æWÀæÝ(Ö@|ÑËRiHRhg¡3n˜ W¾¤³dT%eL¨Œ¿_  |rŒÂÛÞ¯±a¹ei#*‚9.ê/ ‚8I×äúÉÁz|ò üžºÎ 'åR:4W`Ðä>»´Å¾¿¶¤pÀyÅ #/Â9ÇQ;÷o>ha¤i#8æ€z°l#\aÍ:Š_øµ#,º?Ky&'u÷Ô÷g$:<k8¨7 kF˜\2É 4Ð#,ƒMJJO6Ž¢+!¡¸M@(Xä#/4É”Ññ™Àngcƒêç§ÊuIp'Ä].¸˜ý•( dшU †R&y'€õ‹]÷Œy†EA¦ìqJ™ Ï_l0sZ¤d£º_:.Œ)$#á—\BãP9Lg%ãÎl¸ž·#/{Û;ë÷ÁT;ON!‡fT*©z2‚8¼Z˜•:(Óž7tvÂæ>É„@` ’#¯'%™F;Šb›J&‡Š»I0` ÙÃ#*³D%¬²Ýü̽ÜùÀó§j¤}‡,ãxê.UDy£ÁcÍ;y¥L“¤! ”"ø¢ µ" IÙ§¡Êä~Þ"ÄÌ~ï(NqvÚšŒ-úVj#Q…74Lo¦‰¢:8#*B#gË.$I£°w^?‹äCÉt1áÀXlìb™9]ÚÜÕ« æ1.…÷ç˜ÈµØf=^hFÃnUfɰ ‚š·(Ø%ÔCDÔO‹‘À::©]›ä‹WÒŠUäIë/Q`G§yÃ;ºÍålÎåBãNó©&}Î'¥;N¡Ô@QHÀ±J$)T#,(²@l¢ˆUñ;}§Q¬_<©SCì;˜—-؇¬`ª8#*3ÞÌã£pYAÂþyŒ£ÔïÜÈ$ˆDॡÁ#*ØôJDBÄRF„†*¯ ˆ”]û @"ÄV,ÉA‚K+¼h" bl]e¥³—­;µÜË×v3œ{×s1¬„z³Hj¶‡¬Q§u#ùôèp,è¹1€‚ðc²û=ï/ùbU'#/§mIºcg#/*]£³5¹w§;®î¼ó°¥x×9¸Ì1×w.)­Éf—<ó­‰áçgí–&XFÓpI6 ”’#,‘œ5¬†"Eƽ$o™#,HØÆ¤‹FÑд5ˆ$¶ Øö÷s3þD%B¼ƒ©vúö^äµ'@HEHvëU×wî°GÞ8G>˜ñÓ¯—«ë€mœ/«@œàfØtÛ¦¾%Ô*ðÂÜ/å‹TÅ5ZÃc²ÁQ ×ÁÒ´.mØHHëw s÷¶gbe:}!èå`Æ:'O.>]¢U@‘½ò]çW«,OPv%x½¢›DDíàÓ¦RåÚ~8;qœt¥üì½Ù0džîÚEËQéSghÌ¢áúQH–ÀÞÅ“pˆÈªKª`«##/©Ú·³'?·Î‘ ±@`SÙU(ÌLÊ#,Àêã’DEÚD’l-´—µîåå˼]^;9·ÖÞR&S$0ç•ç«SWI+ÊDÕI$7#*8 …‰€#,€ÁÙEÞÝÕã®uÛˆ™.Y²1Â&á¦0°hPÔEb´±E26kè­…Ü$C˜£¾+Þ]Mݺ`bãf)añû6ñˆˆ0.“¸CÃû<g^Öwª\i®0;NÆE;Zí¢1¤Ïw5~™z^0kñ.³™1’zšÒ“m0P¿V±Õ£VMª²3ùÒ‚ ëGK¦M`l Â+{¶ibeovÛUâÀfÙ¦“MY]t\ßB¼—ŠbK"ÆÑª-¯ÎÚ¹ŒTF¬k_*Qµ^—¥êV׊欘¿ÍýfŠ)Šª^ÑÑù/b`Z£Ë†®ÍHa<V*9¡fYüYº‘§Ç4ÖÓZI´*ÀŒ‰„[ÐÆtÁ¶µ2‚¤#/šÏ,ÈIc;zZB$a}VðÄUa˜ØÁ Y#/LDÅ„n‰‚j+¿?Nf¾0ÒqÔk„áÒ-‚ÃØs6:N8®È}ŠMàCþ$RrÖJPÞq†®TÑdÆ¢;ê¿Ð©1óøÂþGpY½~~)*Õ"®©Ä0S.LX1<ȆݮOE6šóCõí¨Tj!QH#/ª„IdTi6Š£hím³j×ξ¯Ë¢°nv,dnìºqQp‘üa˜!y#[ì\Ã# 2ý0ÛzÚØÑÉ®h'ÑÓÌI|Z@€€DR‰™(Qýø_׌ú¹¾ÀÞð'ÑzÔYãI@A„Y#*hì fên/w¨3OfîH™ÁÓ?6>ïøa‹¹ÒÙ°0…¡…'G»ämÆ2#*´˜–Tçª%Çe³WC¯ÏmúÛ“`ñ<#ƪ‘–x§#*ïE’mM¤@êèìØ¨ðÛ*{õ\b" #/’. *_”H>4-+öz¿ƒÔŸ'ƒ:ˆÅö#/)À3Ý–M¿Ð~Nva&£ÞCѾEÿžEdF«gQQþϟ燰 ¦“v[«l±^;˹hV9îèåŒQ=‹Ýۺ̳SWO¶-Ù¿òüC—^Ö»«°<a#,„F~`ø"Û8ÁÏŒ)ª)±Äò¤üP>ž€ô„_æ;×¾„O9S…‰B©i"2#*Ä#*æ×6ÛWJª‹[%sZæÐ ‚$4€¶,À»¨ "bLI±.#*"Œ×,>wØDîÆ³2ãþD0m¿dÝŽ°f¥t`¬P[i,X)Á [#ÌchÙÌ"dv Ð|,x=j~ÃhòØ Ò}cÍ ÄÚždõ¥!Åàh/8+ ý@ïæîr’H#*È#Kªh•A!ÖüK"üªw#îdµH¡l)Ðiy”æÀÏoÇwÈùi ¼R¨ÄÅgìÝß;4׺ °õà(.ëO¥ÆóVƒ3qBc› t#,!È -œm@Ѓ}—x”hЭÔâÞBüÔö#,†œ²íËÓßG¥?"v‘P0vI ¡‚ ¬6ì>;X0¯Æ‹#/©M°‚æªWõÑ–Öe&šï=˜Õ¯w¶iÝ´awW6½¿¡ëÇ®uÚÊPcL… ^J¤ÃÙk#*Ibn„Åül´!he–…AH(ëFÿë©ÿÃrÝ•#/@))Œ€)½Ôœ²#*6³ ‹Ø"޹gFr$´ÆÛM¡ñz`cºÄ´ı3FÐÙ2i²aÍ-I„H„]Øa¨ i¥â“ ØÐ[Ue‰`ô½#D—¯x­Ê»›®÷ïHÞ,ZwUsmŠönj¾ wö¹ *Å s› i«%8ÅÄ`º¥™© íA¢L¤%0¦RJTe²"’ZE“F@«£”ÊM±m]:! `MYi4r¢M0––°[)e²©½—’³WK—#/dU¢°Æ´V‹z¨zʰ&î²u{µóõׯ~Õx"1¯'wNèå±smJîŒn[–æ$ÅyÝâãCË®ªø 6æcyÄKlÒo…»N’ †cV`ÌbŽ0Æ‘ZNŒêEÛþfe„7ÉpÁÍŒ9b…˜yA®4(lê‹FªËbn@ 8PÚÏñä0aáªig\["ÅM¨„¤ˆ„5f3J×Ó^6Oë#,;O@Œ'R@è#  dåø›h|€ùÒÛdžj“4Miú<¡ÅØCÚG”Z"þJ»je2Õ%f7Žª»Î»E„–)bD¡0K£ã¦?¦’˜@Ž”†AÛ4ONVàqãìz>#,áÝ£ §-Âø¼B¨˜uèa?7ö$¡.# …> <íðµflke,šÛKJÔ›MmóÿM^¥µ§q¨Ü¼Ûx¶ìÔ´Ù˜±¥«ËTcu\œì—-Ò[lVwSºéV×R±­F‹UË6mË*¤´ÔR.ˆ)ÁZÂ#®7AXŒµ*H#/H#/ˆŸ‰dÞý`d9 š‚#/BɈƒ@Ù¼à}Ï_2Àj×Xör«±ËÃìñí÷xåiëm0orû|æ‹’}B!ˆB’Ê*¤%-?ÛRÂØ€’‚6Ä‘D”X2àÑ8ÎÍÍ™44ztéÇòã¶uÛgî~^ŽóÍç4ñ‹®×71>¸çð/UQ C ø6ÙD©02 %$¤Ý–Ê2ZÉInt¦TŠZ¹·6Þ+}ֵ嗧DQlšÖFÒQÓX±·UÝQkÓWµØ,Q1D¨À¦@à€Kd.UÁaf%$›j5ªI¦Ò^Þü€6ÆÀ44õ¨ l"2<ã }[¸Çy±£Hu4Cýâ-mî#*f ;tŸš!"‘€ÔV\jÉRˆ†)>.  ÂȦHÂe0l`eaFŽÍ´V·PD’Iö¤íÉ#/&¤¶E™¨äÔÈ*A.BC ˆ¶ö»ƒºÄ²'À{U@d(<.e$7ÈObûd‚;Ãj¥Çfß--Ûòñ:”…|9xqÛõ¯„@¬ÅäÕRqFó‡O>~±v}°}u“åÜG%õ‰(Zw B&êuéž]ˆ\°æX4ËžuÖŸT^È)QPÒ¾!‹¢8"";-”œÃä}œ¢op5s!êPL¤µ†î];vØyЇxÙë+ÂZòs«¶]†4ÖE¥)j5Ñ&Ù¯y]TiZÍ6ËíÒïi]FÐF&h†!!¦ý—8fó#*n;y÷Ù1.WlØÞÛ´|š¥Š •g2!{§Ü¼>Ê®kQíû‹ïɘŸ‰çfq©Z Ñ´÷•»úp5NÉ™n]ÝéË e‘‡ È‚©‹„ÿ¾!¹yŒç–0 H'·gÂçMæËdÃ9I11¡”¢Ja GkŠ Åc`Óy(È#«¦vV©Øi6`p´‘”¶ŽÏR6ÈåD´±„ÌG!ðô°xx¢'ŠyÞï0’y#/ª°EÞÁ’?¥–`ÒhTr#,ᛸʧOêPÐ$*=â–dQà‰jHïå‘Õ¤$ ©Q /ó{¶ˆ‡8I6tt9ý+ÔÏ#*gQÒUɳšb?}Ž HìÄ›GÏÓFŠëV×#‘#/ÒtÄb5)¢CyÓ‚94µÑ¶»›aPJ»>1¥t(Ò&2!#04ˆ ƒ#/6ÄHJK•5Ó|£*¥:ª¼”PÏ옹Z¸X÷É$÷s5ÏFƒ„59ÑœlIz ô‹ó:xêÔ‡_õ²ƒàÛÆð†¸ª£ý=¿ÇsEv›Êm,0xÇêvï®ÇÚQŒêO¤52uõ ôO@ z_bjÑyW#,a’‡Ëà£À#Qà¶2áä"²$‰É‘¶1¬ V˜bÌ©¦b¨Ú¥U-M6$Ö#/3¥5üi]ˆH,fm!´³õ6·*Œ•‹feSEH´P²š¤–Ô¢©‘‹Sm²¬´VÍL¶Ê•SD›X©DU5¦Q6j³DÓT´UZ5 #-!#,6{Öú/ænª¿e"~çèüË',ù´Hí«ç©!® ÕN¸‡/Ú”B#*ÔU‘Dh%E6Ñ[ck©Z×-»3Î*ó#/Œ¿¶ÔצÚ/«yib'Þ¶[°zŽþ®:"q@¶"5#*©PF¢È20”ðå…C®@‚~$dWò— z"¾­´›Æ1(¨¹’¡ ÅÇ0ú0Œe>õ†›0ûV‡ùl| µ¨ E!=þ~'MÁÝÈ£³yvÐÄ…:PñÀ¦¿þàÓ’ECŒ#*‘Bˆ#,@Ùò åQìNjíÚÄ ix}¤zm"UÓ‰oÄßÙ‹Iâ¶ÔXÛoh†ÞK¦¯Wt^eW-"íKdãJž´&Obí¯bØÎ<ÇyôöñÕ¦ý{ÊÝsfYºeEÔÿ\díu#*›óE/J aŵ!³Ž#*¾Atch1Ú\×4½ff`ò8G/ÃôVSHæ…°°4.¡k‘#/à|ïoYñ€‰À‰ÞS#6sy¯ÓÎÞŽ‹•éÜÉÔŽjí€kNñ¢mfËU­kHEÕ-éñ8˜N:C·qܬ4xxE“ôÃP»Î5XMp5#|µU…ÎÞìMætFÑɵ‘ƒŽJsòGF þVXO8ŠÖ0†¢+&†) ákbãüEç£485EY‚D8˜4º÷οÑí;–ù0,öÀý¿ÀÄš2"M6­~èg!I{J¾î>ȧß'Ýк(}æ[Q°š{p‚w:Gú1%z¶Œ‚$ˆ`é‹cÿD!&a""¡" {ÿ#,xqÏ·õ>Kͧ!=ÀG”ÖVüŽÝù:>Yžµʳ‹i·í9z0:°'ɾ42jªhLd,ŠÊJ””%¡EB¤P0|‰¦:íµ»É+võád¯b3)eb¨Å›G¹ÌqÅöñ™ƒåÍ8‡g¡zUˆ–ßÿ‚èifÍbË‹AÂ0rRHLÀ`ÄÓKß#,ˆâ†å²B4Ó  ªeR±Ƽ½Ÿ[‚Ì.1ã€ÀÄ_FN9ali7’)#qéãH¬­ @cax}L„ i]ÅØ&µi︷“©í¹Ä0ѳ&?DªÐ™lGo“d± —è Z…™Šå%áÔ:íLýÅ :㈠ֱ£œh‘"b‡ÕtÁB5צ0ÕKU7W†:xœýô6q—@ðìdÃÁ§RɹÞ46§&` 6¨ÑFaйˆ@{Ù#*œ;7SªqĨ‘(ÏB \i¸¹¶ª#/Œ-¼h½aÛ½ #*äE2cÀ.P¥•cDV0…B’‚Ä#*„RÈD!a#/b#*H4ñlpR#Ô)âªÙ¡óù¼)yK‚uìTuÀ “Ä¥>¾}îß'}UˆIL‹5BA¢Š‹E£Âj¬T;ìž´üéŽå\öYR#,{u¼#,£&Zi‚ÏK-Ô§0ú•ä᣻¦¾ÓR)Ñ¡¬½Ù»!JÈr]íâÞ‘­p©1ï×EdÙ*ôÂ’Ê ŒBÚ¸”ƒHm‘õ7öé<±>$7ñJˆTIj¨öƈ­Š»d$FƱµø¼¯3Ö÷¡Kž:Jòå2Ryç˜m÷Ý$Yë»â‡£85CíãeEƒ\Hˆañ*…  2!ÖtË»MD#,¦tÑi€Ç’rô´pÀ‰«¹AÕd…ý=SE#,ºBFا4œët“)Çep¾Ÿ#*îiŒ´Ä÷ ‘cwrŠû§ƒXf#/Ç/º#/*ãÐ.Û#f#*Á¥š¹RÊ8@€KaËÖ“æï7r´äH‘ñ7Cm´ìeøi5ª#/ m|Ê؟²ßEšZO¿…ûóÊë Š¹Ta®+Ó0$- Lœpˆ˜¡HRZ˜ÑT:,®‹v=AäjYGí’±•…òdÔ׈F~R|ôRºáº©pJ蹯-¥Ðw„DßÚªÍ4³ƒ¡#,S¥Cæu/ '›ˆ£EÍ–ñ·O‘õ—©Ùõ¨t=I½%,fÛ<r΀biZåSEѵÁÅ?YWtPi«º¸h\=5Z>•m®ÎKƒ8',6,£q‚[(;<3³šÄ’ú¦t›ý_Á”Ú0ù{ýzàÒΉS®#/*±‘‰UO#–·wZ¥"UzÍ̺š]¯"Ù`‰½.Y,Š@"©'QŒa[ãÞPuê¦AOY#*/w.ˆÜXˆnãÛ:þ±#,½Â#/dq7ñ('‘—ók4»¿4(Žýe8Ò+_V¯^zLÝÜ΃îl29p5özLƒ¢#*,ˆ,Œ rNZ4u øù¡!œ´-ûO—À€Ü²Ž‡E–í \(rH= aCcñ‚jëëóìW=›Ží3&­ õa÷ça}³Ðê×70(ÜXßËÝ·by+Õ1‡Œ¢'‘L#/J%ã¯FXD­3&*ñ^yÓuç›x¼çmu‰YTª“mµ&ÛKHîuÓ­¶òíuäÑt”…¨‚ÁOÃå¸Üo( ¶d+?Šý!Z½X–ÒR¸A@~ I#!¿Ø#,ýÒ_ö>+¶4 +4©… ωV†[Ha¤”Ì2‘dD™ªŸFL“âœoêë#/nK½·f²#,å.™p¸±‡ÄVŒ}ZÐÆ2¦V†Á°Ò¥q¹fˆÚdebÀ™rÈ5­ÂØf¨Ê²S„4ÛÞ‘³·%™ð´Ž¥ÕÕ뮽KzéEÓ±¦&#,t›T›Ý1`VtIœPhˆäYLg6t|:Óiµ¶Gnña§ˆmãÆ,xͲ6²„$lÔ¼pÖ!vm:‰¨<4…¼8d°ØzÌXF"ꀨÆ4ƒKª y˜†m–ÌS#*K7(Õ¹}q#*þN&Ú¤NÀâ®~wRÈLl²–#´ªF@\s ¦1à§7™a¶UAoóÊ'Ý襥‹¬Qêôˆ"åþEåãÓ/@n"lŸåÞïðÙ¾  Í8:œM¥ÜIÓÖ>ª”ê€bH ˆh ×y•šK*5’¶&Z6-&¶£T¥­ö®Uù—+])_`²#*û°Ø[ ¤´L”…+, A}fCÞ‘]8îOËÀc­£¦5Ë)EÍýMª`åô{€P#*!èíµš²tÐv˜ïêoã·CÁçul#*Xáó@ÿx¿L;ú²§ù$ƒ#,îI±¦êT2'ΦÚ×[½ëݾ+÷mñÿ×]k„¸hÔáUü¯Éd[JËÍîŸ 9m›°ö­ñÔÍn6˜I6ö5cpß«2™B$îôM™ó&WÛæ7¹öhúÉ…dDñØJ¢ØLR"j$n@äudñÅ&/m¥Ç÷S}ZÆBa™$&L›|æ}zìcŠ3ÕY¾ÞFZj¤‰TÅ ,8ç¤Ü÷\°ºD¹–ÖK\ö¦þ/=€bÚ)–ä°å~…/¤»–úé†ËÓâyÐ$/áç¯ÛmØÎÔpCÝì1k{O+½Ì ¶¿ÉˆƒI3×î”äñ£óGuô¤éݬ}.xý+4OÇ]‹>ØÛ ¼á컈TQ•©­7þ^ÇÄSfÀÌx¢‹íÁF˜è±w¿oGÙ„÷EçQñPT6Ô2ˆgÓ˜©¡¥„1^Š7O~Æ£Þ f8ù×ÝìMG牦¾©9²6‰¾Y›ÛbšË«£…JÎDÑÐ;>©O#/ÌjjíÓØc ïì¢Ñˆúb9d}Üeõïxù\–7NˆÝbg[yÂ}ƒ öà XÔ#îÐÑ`8#ö¡˜ÜFN[þ–ÙØeðX –çiÏVú».¥”™ùÝ]„cL>·0‰pÓªAk €nÛµ„X#/UL J`¢2Ë%Ã5CÛz$‘,„‹ ¼ˆ& ­¼å-hi#,þ:^ýE·VýJo ¨ÞÕ͘Ãþ£&ר_³ ]T,Dˆ·x±ʈ´˜ˆI¡•å”eˆ¨°H$7[a;‘ÁHá€TF"€£LDo#*J"#/|H+‹‚ B#b7DÔRŽ6šÏë™sÄëëäsË ô§!ðâêÑè w~Ÿæº^wU3±kmVº%ÓŠ#/ø1÷qL¼ÀêùðÝÓÓ€2æi->q<O]¾‘#,~áõ´4èÓwR`†ÚÔXXÎB<¤ËSDé]=x4°Á×Qkˆhè: Ó„nâäy -VÄ[Ëô@áQš|Ð 5ç—<Á4zÑǵã´§3`,_Ö#,¡"ŠKת%Gh‘ÌÐÙÐMï®qiˆQMCTlÙFUs(V‚ &Ú#q „h‘Fˆ šI¦´¦Ö»UÔ›5ª™­WU±¢¹™x¹ywi[Ík|¦È‘a"@ #*E@Då침ç#,`÷Õ<¼ŠË0>¾¯‚R´×°¥1´ÍÒen¦GBØÑ+F¾ú$ßÛâ02“qãO£Iôfâ#,®¿K²œ#/—T¶ùÜ% Ñ“”œƒcPÖ)Ž'-ªMù´E¨+j“ê8–Ã<?ªálxÐl6%²˳# È—#, tÅCà;ä87;¢å÷3!eÕVX"1Ü3·<‡ŸñèOOb%â†q-vÞM¹”dmЯIÞ†± lëàø›2ed^àiÎo÷×a·Xø"ŒTñ?e½GÓz¾Ç¯j33ÛŬZfáæ:ï@ܶ•»^£Ìñ#*É€C¹¶šŠµj·¯h××ø·]ÍUb$Ve r§#,ꟲ³®ŒØ²A#/_ht˜¶L 1üX¤6F#,£|ie‘C#*ñ'Û#,Ÿ?çû¿Ïý?“ @¸y¥-NuF½Í­1}·IÞšöøæðMñµ¬6=‡¥BéJz޼öÕÕ»¬¡¤”$55@^òAyÈ*CõÊÁa¸Uƒ¯«31ë_•ÁëP¸B¼‘¶ôÛIE`¡I±>ïo"â‘Ó#,ê.ˆ.þ¼8‹ÐÎðÑÂâ”áÔm)Øô^F–ÆÓ­`úÀnh¡’¿ê|Ž:ÐÊiÓlpÙîÉŠ¶@ê ?.éÿ Ì5;ï |øœm@×R¨¨ãòý¹Ï3•Uð¶x<fƒLËm÷¨Êq ¯-úKDÄZ\&¶dfê‡@:ñ†J _#*ÃÔ)š§‚#*ØFBçRÄ:x¼lã´ؽ¶†ñ?6#Œ;þ î^-¶û:c(˜ÒÉC̺ëd¤À£>A›*²é$ ¼v‡@üuqÈ·~òj|çðÙ4³ÓfMèQ@#, }™¡ª'Õ‘ÿ<„vS3Îz<•f,+¡©ß Mµ#,,â\4æ)#,R(ý?¯˜fÉ#dB¦œVÅhóÞ¿ªŸ©†þ÷áΛÂ8 èÌdén槤DUNçĶÝ#†Ð´"¼V£GÙ#*h(Ñé)‹x£ÛL1íf&g#/ëÃNœ•c¡Ðžk‰žÔ2 r@²þ;Î.wèúl|¸éèÄ4ô# Š"i;!“ÙÖC@×dž#*É!ÚÈ ‚·Vêkc[§ßT^6ŠÖe¢µklZ±ª6¢¶ÔhŲ́µ’ÛdÔVƶ׋PR@RB’@”'š6 ànQ;Oâ¾ËŒž ÑƒIÚªdb 0dH?˜4& •W¢ÊBÁ#/’ \¼:vÎÆÛ®íÃ8!¸€rÎ;e©¿¤Á`ºvU½†`†0¶a—×@‡ñ;•ÁL1­°küTqv…c¯îž¿mµL|@:é«¡ä#,ÛËl›l`¹fØÖjMP9LÆËó•’vå ¢¢žà÷A#,žG£+åý# AAEH±8emæÁ³0ô(&Õ6R¢P»J œ=9—#*¤«ò©ã¦iÔº?›A7aOæ!7[ÔìØD ÜÀí¾÷9‰Ál€vH?iÀ8åߦŠ_BCÐDêšÇ+qQ#*ïˆf-æo;cD·7|PP´&©«[4«ŽÑŒ\Œâ$Êl·@>§'ɘ)…†À¨”>ˆTMqJÀÕ~¹*ªJ<\¡Ý${»jõÞÎs/H™çBQªš‰¤@´yA~¨Z)YÂY‰R7‡Ü#*îH®§2FÊTý‘F‚…l5¥Ãòç¨Þ¾ù™À´„Ì‚Cd'Tà23ˆo HÉ6eT‚hªÕ#/€×Š}}ž#,÷§¯åêàmÒ5žf A˜ˆJ#/'Üî»·«|h)Œ›[à¶Å/›>Sé¬Â÷ËG’µ^ˆ~Ãå³^I·É ønWÐÕ°¬5nç*"a,“22©rå93ɳC;P¡[r!{n˯Å4ž6²Lbø?Uع`±#*˜ ª£‹.êLóéÛ@tÏôiè]Tü½(ËØP›@ oÈÙ~Aä(>“Ö7g§au9ùΧLFeþ¥«¶6‹j¢IY­YªC\V®‰jÈS!I#/ªF ¹6#,sai³ƒÒ˜̸ÐG2—rLo#/@©¦ÁÆÄ"d ^¦íåºëgsI–·uÚRM©Fm#,qwQ¯f©æÒþ#ã2Ø x…”3x``6qÁƒ2K-c"ŒF‰hÀqCRB7ƒhdq¸4e´N<…8:5£*hU0‚$A‘1§¨‘+kñ„Æ!°k´#Œ†ýû‰ 'é-jöì½f°¦©Œ!uÎÍx¢®oœ®™l›jM®t“æîÒnR£iU‹±¸¸¥¶#/!*†##/Œl¢3A,,¬æ¡i#b£i™1‚˜Õ,qÑkDHb†ša`†Á©ª”Ô43(ØÆ©$4¦ÓbK6ÌÄÈ­”Ô½uvòí\–îw8mÉ“}-ÛË®[sGeï75æó¼‰£B¥¨dn[çë½ÞÌØf`c[0¥”kSIy’â‹ Á¬<b3A±´ƒU­Òâ"T„XÁá6jÕ† ŠÀ Á€Üv;ŠjÆ3Œšcy‘SC[y&j*ÓcϘg1#,0ØqöÕZÆ,äËa# ¶E’‰>xÇ Ûa3áQÆM¦ÅÍÀ—t¾è-´°È1œå6†ûiFÚ—¦9Ó>¸¼½xÓvÚh$#,«Ö×KF‰ø73®ÕÞäÁ«-0ŽaËNlÌ,–«ÛÎÊ»s¤ÍÈöëµ¼QW³$ÌŽöþKŽ“]“8¦ƒ+‚ÁQK-+L#i¶œ–¶DíJØf:¬ «#/6“Ç‘¸Ò-¥Œ„I˜Ùhí‘•¡F‚h‰*ÐRGŒ‰ÍmŒcbMÙƆ32KkLa›ë—8á„iäx±#,[2’XÙpÃ1xâ¼@âæ–î¸ò•©a ‰ ­#s&#,ç¾Ñ±µ© >ÆG¦~#L“aB ]/s‰iÖn„m7dÜÒ–P9åLÖêjÆßçs[s{žJˆ€wŸ#,­%c/9ŒY<èA vâ|¬K$¤ÜÚÚ0qÃ3zÂ4¸i#v#,0W#,¤ÌbÛ1½½Pƒ©°óòÒÈ#/û †|ÊÕÈÌÅ,Î6êþ¦ÆR\10ìK #,ÄpdÇܾ‰†нÏáÜÙ°DðîcI%.dûÏK ñbç™=ïnž^ìt´›ÑÎ$ÞH¨Ìm»9a]ÈWÑŠ¸Ì{]dÃó[JdÀá0Æ2#*³6É*mVoŒº]GºqÅÈLJo‹Æõ!±&s€®hÙµ†•ZÌdUG-‰Ò„<#,êQ‹Ð$#-‹ÃqéïäùE5û¬0Іb¨l†û]?v<¬ dðª u ošÀÑà‘‰±6“ÜÅA²Ü,eeU»mƒz@Ú›‹å(ü´ß:á†Ð¦Á¢* œÄf"1EF’{éçsµsh«¥l«Ë«‡”Õ¢¦PÐô "â#,±Ð`ÇHQBbÄ1Œ a#/6¢Ú1"¶B¦ÏùeÞ#*oÜyyŸ)çðâ‚r<Yø~Ý,Ë8¤èèyŸÛ"[÷ÁD..ÿ9·¸PÞ?¯ñŠ¡ýS¶ðgðAQ ¤s ù¿w­f½õáºÅÖº´£6OäK ¥ˆœÅ](«ô~+´ñºÂçx«ËÎÍ"ƒéç6õŠ=Ò½»#,XÚo¼Öæ¥%+Ý‘½ÝËåÇç̸ùãŽfŽsCão8Ñ‹O’¼«Y­¶fºÈ4K*Ì—scÞhD#0¯FtvŸÐ¾gÄe Ráe÷ˆ«_ç\!€%-—¤ˆI!ÉÌQÍè­SóÔWª¿Þz›çæS‹Þwiä"‰£#`DF$ž’v›£éÐmUPÅ„0òzH³:–Ï 'L8é·Œá¸N›a$b²ž§kÏsào“zÖÄÅ»ks}þf‡ [óà],o~÷‚B5S»á[†²o%þÒŒ^Æ(¸Ãð8†–r<eaîAÓëé|êañg>\–íÛ..áš„,n\·èä›&=ýP?ÃP<9 ‰¢”¶X8kºL ‡À­i×-ûjGŒq‘޶‹ü—±õÀ踱³˜(z­-ÃF’V%¤àŒ§GôB0øƒ"(Â)ñýn~ß} ðÔŸ#*8 H"#*©¦¯~÷²±[šµÒÅkKrŒ(…¡.d,ò‰ #/l "AùÒ#/ÈŒ²™\3K5bUEÛ¸Úiç›Éæµã¥FñUÙkpªºkWŽ–¯wE¬jó®]5vªé·vé¹v¯QO ÒX´¤b¥KsŽí»»m¤Õ-M|[UãkÆKZMÍ­Ûuç›Æ+Z«ÆÔZ`‡½Ã†ÇÖ˪(Cש¥ù ¶’ÄsJˆäˆ’ü1N“ã„ÖE´%Ä CB²ëVm­”¶®i’íjìÕ¢ bÈŠó°HB”n…!#*Wƒy²øÚë]{Ú¼B]"µÚöµ‘D‘ 0ŒD>=ôöká…nUÒê³]kÙmDTV¥$”k(¿©Ý-ƒE6h­EH&iJűª*5™¢Ø­‰5Ñ£f´›$S43&Vš4Ei¦Ó@lÃV¨…©‰U ”°„øÐ†óáÛ ¦gWìøä&DÞk¾u[^¼ƒIµR)$ ’$ˆ–_yѲþé÷y¯Ýäô<Võæüô§ùòýxCÃúŠƒJæŽÇ,w½–Þí8[çG U ȧŒE$B$u¤¦Q£hß‘Íôï]~i¸³FµtªüŠÛpÕbÉöñ]€Ú7¬®ÅcI§w[¥®í×kXE­£Y#/MQ­ãy庛JSmi«ezíÙ¬­H’#/”¥RƪÍGüd7ìS‘“,À>E’y($Âd@ÞC(a"ÆIF1ß!¡d!RíÝ’ˆÃ*¨ $ &ñŠJ²¨‘™åݰ|&8ÂÈM(9•àå7#*9+ˆCRëÙÈë ÆCZØ„ÒyÓÒóY÷a©ïŸšŸÓÃ,}º)սޓýSå˜U,Û•B}3M„!ø"06l=UQý,á­cG7µLÌf7?~Ëlc]Ì“MB`ƒ#/a!`Í©¦èà“L3$È>—µ¥æ*ˆQ‰1S<¼OîÅçÏÇjÈ„$Ûiá1°<¦ˆt2b²tÙóJßÕ<˜ã §wXTžD6C™?"ºK±•ö;Þ7B˜²^l3&$¼‰æG;䶤œù qòÖôž3Z6×_B•×W¶Q´ž¢ÓEá;Œ8`Ë,˜iîö{ž  °Uþ2r¢HÆ ƒÖ;â&ô¹Çùj+ïš2Õåa;v©³ÆËgòãiü8øØÿάø`¨Ø«ô Ë)Õ+j¥b†ž¸%úöÑG¾Ø¡Òâ Éë#,adPO”Ea$Ö¶+F©-¾X_ZÚºVL?ØÇûH†W #*Ê ¶&p± wQ¶JÖÆ­òm¹Zñ­¯«ÐX¾ï+c#*JÛÛz¹Z¿ÙÈ8廦‹Œú©A#*0Ä@µùٿĨ¼üa{zåïÎ#/`ªò[%Y®ºÏ~,ZØÌ¨(@ûÐ 0À’8ž÷ºL‚l%”\gZ›†Ô‘h04OÏ6i„6"æáÄ\Q’AXÁ1’­kÍd¼öÉUçu]°R­ˆŠ","S ,©LžX§ V0°ÆB pg8ÒðZ84U¦Ù2 ™ƒlíjÔ¥"PÐKd*n¥Ì¥KR ˜ˆP (€ª!B¡B±XňG÷ORMP,0³%›Ÿ@RZ°*$#/#,#‘q@ÔaÚa1æºöºŽP$EcŒ=äÞQ æÿ?_d¨^sx–‡²’ëò?<õ¦’Í]Læ´øµÆYÍ:–.ÈÙƒ·n³lô]Á(Æ3Éj6íÓá¿=Ú s:Î`YPAäE@ ü—„À-oV¯ÅW­ZÞÌ­Ewéë<4Ïì>d`tW¤#/3µG›Oñýaá d^ž5@ûc)£ìeì#,#,(žÃûTF/#œÉûY#,7¢©J¦•EÒV¶výšq>’ô±¨üd7Ï‘á:ÕÖ³æìß©A‹9/·Í6ÙÛÓl7@p?½—p¶\¼d 1QfÚÑÊRt^àî6HhnûTí5g¬Ü}ÎϪQ³DHk¤!Q$´>Ó©­ÅÔofNF§TPHmð#,ƒœÃÙHØÙy’æ¨Ún¤+XÛBbÕ[Ã’ƒk8(#,H†ð²‹Ø‹Ú!“) ˆER@#/X+Æ©jJS$Âêl,ˆ‚b¸0àr€–t+Íѳ¶wöû{KÁ(LGí|žÑ=\#Vß}TøFÆrÞív=ÊñEÊ“zž]¢Þàcì?ÈÀ|s†`cÛͦü9A¹µ]©DZ§5–àªdb CJl%Ÿî»ßIB †GÌ2ÇõÙð¸›Á#,’ð•!#*ª–¤$Tb¨„*"ü‚åág|X²,‚t•w`ÕÕ,A)•q4£®ïØ”£/+’Å›,‰Iš„ÙKQä«›-*“h¤¤ØÁãpÐa.mÊå·3‡tÞo.Üu×jc •ÝÛ¤WvÛ¯ç“lr–[Éä·W.æ³,huÑæÛM­<æZ¦¥nnmtÛ¥¶ºm²–6ºÅ6îÛ´›%oѺsS™-ɩݺjë.vËE£G6«®ëTù„R¶" óÒÚÅ#/.ö€RÀ zSÑ#*¸mÂk" önôp•ÄOXvˆ…ˆy@pÜôw|/V F¡( B"v±ÂØ‚¢ðûQ<AÞz(?ºqžÅTìAßp}p¨wÀ‘H,Uå£éw„'¨5†¿[<²CáÔÓHz¶ˆyö÷ŠOº„#/Ñî⟧¼év‡_r]⤈Æ2HHff›é×·5W´µmµÌ´A3RÖ ¿âSi:½œl(¦%%F¶MX­Z´3VùDC"'êõ”²Z‚A4¨RHÈÉ\ÚíίKWxuÎR͢ƔÂX´–#<n\XÆRJ‚x„7rBXq"#/ПàD’G#1‰(ÖéO:Ûà1 ]Ò’’fÊ(#/(hÈI” q²QC X˜!¯UÞnv×¶zQ¤ˆ£^7¨ˆ–#"ÑHÒ±f¸¶`…#/Š´ÆV*#/K†£¦åÀ™)ðJμ·Ñ`„?¾Ç¨2Ǧ0Ò# F#*@hÅ™î?‡øf£×X#,KºEÎØšEà ‘`ÙSC)UYµJªSA!À·cäf#¨ë  Ž‚9ŠÁa)6m‘¦Ó&Vµ°Õ«ùu@uy&Å#,j ÇË–N•B‰CRZf&oé5iZŒÖ†ÌEbÀË-â#*é#*CýP¨E«hpÅGÒŽÞ4 çâ’#/PlÚå‚€#,ÕÐôöÄò ]¢ª¥Un#,…¾î7ÖǤéôÜ6ßôÅO_É##ä ÂO"Ï/>VÿãŸ1x¤3±¤Ì`˜s(¢¸C2ÖäÀIÚÎ8 Õ!>wrpa2ÂnìŠ,’ª‚ª–ªµ4¨Ñ×]ÍŒï¹5:ÉŠDH¿º®k?ž£šÄ2Û¥Ò@é'Y×#,]ŠÚK×rÖÛ*S÷°®ÁÀ#i!™ ‘,aY$¬QŒN< D)j #,ÈB£ŠDd ¹ª3€¶\ #ý¥Â„%0(D`R #/G:X*7ZÔ„¨„ Ð*Â3ŒªïD°F#/ã#,…ËBÉ-„¶Jiïj¼bôÛ•%¹{Ù«kÅko&‘ĄÙüŽÎUx]—YÅÖÐδU|œIíö¼PîÎÊ«!ýmb@$K0 †€M¶—Qáwˆ"zfI^¿X­&Y‚`Éš]÷°™Ä‹rŔ¬œÕ¦ î`´#*–$•(@XHÈ(Ш 9Íù4Õu͹¦™t€#/Mû÷†À¸A&ÃË#*O’tð)‚ƒvJï+Úœ$þYŽ¡ ÐgïD+DÂ@ à††´)F mØrfå÷C±daó`§ðCFÝeAâHÆ@ÚNj{ ÑQYT#*@ ăD¨UÍNAOÆ(9@ Q"F$#/.$¥Š•lÁ²5ø6°HE:eÝŒHÄV†šçPñŸ$X{áá2d ±O™Oú6¼yÀ>ŸßgLhZ‡6AÊR±1m€Ö ºYq8Ïã‡#,ýpÅöµÀAü=LÆé÷fbþÿ‚Y#,jÒ4bA ÜÓ4ƉÁ"ÐñÖ›Ó"m¼„²d$ÉEI#P#j¸Ìx2<jŒ¹[nÉ©] ð3Ucú²pͳk`EZÕxñ‘¨ùeàÙÀj¡V^[m…{´Â?Úx=©{W¤M4Â=a¢HÁížD<úÛÃi¡ÜdðTõèÙˆÝ)PCfÚ?D£¨‚¬7…&ãžb#/o‘üñ@‘QL@T¨X ˆ“×CLT#*…Ùì–D,`Qè #*¦<)Ì¡òw™sAÕfá¹ü !•¾óN‘€è¬‡ºwývþ‰Ë#c«jèàþP&GsØŸ€@„"HÁ¤,3FŸ¯Zýj“éÞoÅÁEÔ0SõD##*ÖýŽÎ={úôñnË1ê+èÝ9]*PWð*"¨Øß-4d×î¢ MvãÃĹ6 ŠGÚóTPšœ¡lýÕz0ÁÀ2Ò%AŶ#/del Üßó4j\¥ò£VÞÖ³ L1¶Ð墡8¬6e¢Ã“õe7ËFâÅÝÌtðŽìÊ· 07ɄŊÑLäåuÌŽ+Uâéq(3‚¸7Ò#,EW…“4dD´…¾Y©ùûD{Ó½D7–#*òˆð8þNNe#*ÕÕ說ß“EÅŒ´RÐùQ¢92J Pn£DØ¥ïÀ¸yyxšík'\m$~oOx£à¯Úñ"GßwÇ¥ÞeóÞk/çŽ-9nahª¥ƒï».Qo»‚8USv9”‰{)ÐÓ§¥h”#ú• ·¯ë”;7æ"É;VÜ%mKtZ9Èö4=Kþ ¡gv„Æœº©±M¦–1M+¾‹Òºf÷j]QTÕæìRœ1T¤ êâ#*‰´ƒÞšÁ5¥…«DÞ#Lz„4š1SAØü'w ‹'4ƒ²çãs×%ÞïÇtéÎÓ|@Å[t¼S­çž:[Êá4–Ù¥1¬òÓµ)æ—±ý/ZO6o'Nqô!¯YæÀxc¾ÌV=Œž-¨ž4søË5åÛaòdíBÞî¸ñÓ^Ý,)ÊŽ išÎñ¿~Ò»<ðmâ°# »KÊŒ|>Ѫ «°S³¦Z]Zĺ$žêC{¶‡§²SXÐU:W[Šb_«élÅå!³Í\¿Y~÷#/›ÇõY¥ã½ru÷O µptï½;":7#,0¬D1"ñ%‚Àf“ie¹w ín\ˆKƒ²œÔÌ€”nÏ·™à=g°ð%p†']¨•^ì`Ï×®ÿæUÞ/OßÉ™¸â©‡4;¸wcãåççÎp~%ŠëBåœ<Ç•¹z´q™~^4í0ké¹änL!ºT”6ß¾ÚE*‡LuÓH†“¼"QŠ)ƒ¸7uÿ]KùT’Ð!6\Ö|›¦4óÕ<¨Ý˜S )R@Úh‡#©G_.•9Þ4%0P>®¡Ð© Ì[s÷㘎²ƒI©¡ušÕù ~Öoå[Œª«Rª«6»{kI%Ôß©µÊ¿qã•«†¢Ûy,’H‰L#/kx ­ÒK¥Š¢[V4GsWokWxŒ¯ßêByÏ…dÛ­ºD³0îÕìr¼žtøÃÓVï¨#/¢ÃÉRfIç©C3ݯ/F©;i5¯ä\5ÔØ “ÅT(;À¾W§oKdžp&PƒÚgzÇÛâŽÃÎy#,„Î+`(0Ic@[š•¬ÃBÐUŠbBÒŒåoãêÒúòs&uRÓ=1U‚áP#‡3âXÙ‡tRï&{7z:rJGÁö÷¼îg&¢äПÛÅHÙ$53hžŽBd»“8’ì¶G?#,Ò2wë–›ºy[5½!`T/È#,ì߆XTã’I¢lºC~da…€‚™ùÁ#*M*—k9BL¥÷#N‚÷eЈ?Ja@5ôbÀ^3ˆtþ=ߟ@¬M•=²€†ðàü»#*‰‘KÁFFA¿¼„B$>(Jtãß“jÿÛ-í¿<µ[D[°$E”;÷—«‚íTƒñáÏHöVãòWœó¦C37PNq ÛG1æý£´ë£Zrå=>VllúÏjwK¢¿C›#,Án€ñ‰‘nÜËt(èzNÞ±qÏhðøp:£Ý7Ÿ¸Ú5ë¥øxu^áiÜÜÆß0àVÝ#*1¼34r³`\F¹2îæŽØàÉ£sMDY´ ‘8+´6§˜¡j‚gö"¢‰ L~z÷p!UÇŸ3Æ<•Põs#/9m9=Ôz,¼Š™šßWEáÊÖh£âvñ–9“Ó¤ÄÁ–U§Ô,è€ìUÆùñò˼QL@Q‡"€¢'„#*"„B‘‚j.ƒ]š›žøÀO†ëŽâMGp€ìß¹gÔ9(ù U®Ä™ï;K²-í¢%4¬$3Š#,­”ák¿¿ö?¿èñ¸+$GÕOÚ:cD°"@L#`!üÙZ¯›g¼_£¿oÛÞìfÚµ¹5fƵñM5mYCPóEß#/o=ô†#,”>]±!‰ËöÌl;ÝP£¤Ž g¹·úo×MÌÏ£«2špãAéšóWiI‘OJ!R‰þé¶45ƒP’Gú˜kÄ׬=ñnÜ/Ç’}w‰wžo‹É•w`?È©ŒOw?5¿ÌÿÛ:ýÈJGþ>‹kê7-g{PJèKõtÞ;$&ñì}wn˜½°ì¬$⪆~)´xÐxÀNQ¡‚±‹‡«®ùa+Òcà‚… yò¿ò}{«rÇ_Ë^ÁÊ­¾íxm ¬;õŽ£ßú³ò¿»ÐÂôUASöÓc;Õ‰ztI#Rù²ë˜îO=ùŽé½c*©Ç#/îýúàº2ækÖæy½QMVf÷ãÆÂàÑ0'ëò0ÍüÎÖuó;v(I ìî0üžg¹VÌjxÑHäîÈX ÓB²d„‹@D LèC§/ †ÝÔd¨)JmE%‘0CgFaîÊ#*›?‹Ö:Wu§š²üž4•ùÑQ®"KÜ|¾“PÚ~¡"ØP#*P¬bÒ]?‡]µI‹cUKfÛ4µ-@ ŠE$#;wí°»Þu©$ŠŒÐè\Ö.]¶4ø};ZŠ!@|B3–ÅEŠ×ûÿ=ëÑúÿkÃÌ„#/ŒÈÍ’#fM›DÄÔY1 1FQˆ)²2lM#/L›6MDXÅH~rqàüOwC^awŸIÅ’ÅYñfOš{èãñÓ<ÂòàÁÂq›a'p¸Tèf¦Ã„B6˜ÔFp±¬\Þ9äK‰pDÄ#*Û@yáªíí=•fû}§Ð¾é¼¢ hT©´ù….¼³lÇ8™@¨#//mH¤jUg¹zÒ·Ÿ)Éû}™{hóg ¦Q:ÞÒb ¡‰¶ñœLÆô¸_¦mtÒjªrùº¢“ÓY¸ô‚ñ ÈGºãêZ†Ž»´:º­bÄÓв;çG8l–ÚVévO<î¨üþ=¡Ê¥ äp" ~uúÃO¹Æ´eÎ ÙB1uè±ñªIüŒ“/û<ÿ—]ôv¼>d*$zœ´Ÿ±$#,²Ø*˜ÉJ«m6Ç6çUz³tØ[Ã5k¯^w®÷öÛW¥g³\º¾nj¼lî¹)\Õ]®é¹º¤º®‘Þ÷ä+f$¥4´›æÃ¼ÂƒªaH¬0”˜I#*š™C#,±"øh€!•C#/ˆ{ª6è‘Æ©d½RµßJ¼E’DRAdB-¼mÀ«—K–w[—²ÖÛy¯o‚_£ØŸ&/#,eFZb8σÀÑ"´¹d#/‘ÔÐÄ2"†Z¸ÓÝMkUЉ©ªË†) ¢æi©aý,0¯Üýåêp³¼B2ãcbâÓX3• QFÐÃ;‡†?+÷œg8†ÑÒ·‘m Ôm¢VÞHFB#ÈìÖÍ&ÁäJ´«[6h¨¶qˆD„II,"‘HJ`,€RŒ«€³5A”«§s"D<]æÛ¹i:[Å/FÞ8ÔD€¥=66 ah’iB0OiŒ.¢œÑPLlÚqN9 È@F2ËmM6¦œM3xˆ 5 ­Œc pÑ-#/ÕbÈʆńc`éTª+rªÐéIrŽÌ#l®·€&m„UÅ¡4A(ê‘Fä¨W#/ËhÆ:#,‰²¸È™J*7˜JQ£QÊ%#,@Á°id:Yf½Xæî<M·c»Ý7°†¢®nªä‰†´¤¡3ˆiR #/âeJæE¶²¼‹k7¨þ c#Ì$æÑ½lc4sFöjJèèÝì\å)ZEiÙ¬FYB²Hì2"ReXÔcp$¼ôà kOK ·ÛéjgFuªÁóðµ¬YädÓ×V+bOƒ¬-p‘¡è½CTÓ­ºY‹"’@‘¤c#,ªµ<® ÛAš6<­2XVƒ¼™©(79#/TiñÄ´‚xQ§údUâiy(ÁH#/ЀwêŒ+(ß)Á‹JÖ“Œ(ÀÐȆ•è\4E‘]–45¡C4+5I)23¤LëFPÒ: F©(C ÇgÐ{l9äXÌ» AtcR1¨Ö•hHXÅ‚Óz£8«@¤¦X”®u¨LÆL+"†##,3›‚¬PÃFˆÄÓFX„QÆ#/"8¬U‚ Ð9AŠ#,#7¸ ¨çÝ4ôÅ_)›x`›|ɧ‚9&1TÐD˜• ˆ›CŽY¼R®RQ7£ÚÃf¤Qn·HÃvT](»gm2tš ·iE/(%ª›$©"ÔbɈšfŠECWæQYžVàÖé†È(ø“ÒF¶Ðµx#/Jùž¦YÊŒM’ï‹ìu¦÷Â…}0'ƒ:fI[}™2”º#*ÆÐÚUDU޵)v°K<+†#,!iT[³šÇYŒhbði)µ–Ä."&˜ãójc€6/'NûˆÁ£`Š¢H€ˆFÄÓ:˜SDD4–ƒb„#/ Ĺ€Æe#, óoÆÙ(ŒšË/[oVë^¥&#,i2·RÅ@Chd‚ái£íJÔ”©d'#*èä®74k¼w8nî¼û;˦5FM®õÕÒßËë‰êäwiÜ–Žú/…¾Zü;IAV¶Å SfÑ‹„AÖTý¬«Bê!øj§ëCý9/!è2ÌPÍ#/v#ª<§éáF:Å*(µ• ÷ç#*ò \îÉAÔx·ÝzJŠ>üP8ޏOEXÙõIU¡]£öŠÔ–ªJÆÖšf²´[%€pDK–Ù¥ìœä‰í©IQ'…yÁ„МÝtûìã#,* $¨E“éøqÏg>ò`Çã;“}™«0WQF r†·æÅ=ÄIÂÙY áGü¬Y’7EÝÛ×WW6¶ö×]4;º¬ œ¥Qc(PŘR7Åj•BCZ©Sf,¦ òaÚ¥—‰Ss]Ù£– F7‚š€k†m¨’†ÏEüþ­a°°ØY›(1‰vw’ƸKÊœåöÙ®¼íá­÷f‡Ó;È$±ݪ”¾h^^Ô©zÈÞbÐOxjTª/ª; ÝÄÖKÞ¤vé‹éŽŸ6ÜÎ/»W†‰^”D­£éP5}º ‰:¶’$ÉÚý3Ø`¤âaÁx(aª(Cȉ‰¤ØZשè#*txi¨}_ß÷â;¯«•ób±Ÿ2…2A4<"ÂLméh]v›fúk¬åSéÕû»#,°Oâ>£ê,ÇêÍ^îÜ<ƒôŒ$‰GÏzwéâ#/=“äè·œH¯·u_tå‡×a1´É¥ŠoŸ?¾Ébóbvš)Õ^Îþß^‘nï†3¼3#,-_•„#,º§·ª³¼>'¤‰„";®gЮ:dƒQ*$+‡ØŠdç£SZxH\ÛŠa;*‡ªP½à©$C…ÀÃ/Íñ›¶.¾Ò—¢*ÌulÚk¬¶ØàR;ù}EíĪuçmr1Bô´X<I´äX3h½»[ì—}—±ŠQ¬}_º°b8Už±²FÆȵÏäÊ´ˆ¾Žu7§#*ĉ¸†Ÿ\L ³)#,\ÕR@—mE„ýg‘¾#,Α9`8™¹±jIÁ#*¤‚;Œá€ÛÏ‘†¢DVeh.‘wmŤ¢‹^9[%¬[Æ*݉ncZ¹¬UÑ£›šÝ-mÓVCX¨µÒÚåd×75«•;½›‘£jJ×ïw­âô³º±Zþt·Lm‡eìvÆAÚQ¢᤺†´Ð»Øùëžµl°0æÌFE.Çm}XÆsö‡ÈÐ߸o"¸5R9 ‘S#*Wë"«š€qH>—ãF$\È@Š))ˆmá¿W»”CñÑñuÐóxPTúàìhøŠ¹þE#*úˆ)©ˆÈÌË’Xø)…M+“º Â#*I0t}¾’î4F4…C#i(I‰D"2Šª»À¸WΑKKªAHÅÁÀdkPL1  «m&¶‹ºÕ«t›#*XDèØ­äK·#*”™ v÷y5}M›kmøµ¥š£I¬„‰ €‚"üG‰óA°h¨:‚ÿàPOR‚jü"nŠ›s(Ū¬Ð/¸o"FÒ¾FñÇ÷VG–ýR‡Wˆ„ƒGÅTÖÛ›<s~Ëì¶ßÊmlfm&¡M„¶5¤ïó›Ò²#,ädp'QÕ‘_J:¨z^°ÍР==m(TYdÒ>d…á•L¦ÒHK40XÅ¥’ ´i6,ÐÚ™¢Ôl¥&II6#/m­Ô[XÖÔmjm+LªQ£S*m¬[IµšÞ~‹×Ùá[’1ºÃ2"‘hmÉ+‘"q….M¶Â<«)ÈÜaˆP—òpعIQ¼ÐÉ,#/m†ˆ†G”BA´ˆ ’™c!0T-"Á‚R"T4ÅÓ†ÄLUÊÂL``bƒ`èÁmˆ6M]Y©ºmn³šÚíZå­µ"(U®ÓB‹ä#*’"@¡ŒúÿVv ¨Ž<)KH-H4F›»§vbáÚŸ¥]¦õÖêõݚŰ#/#*I#I,f[dZz€åqPÛ]ÚxÜ£8D#'ÊÏÞ:wIÒŸŒ¿Ùëϲ´¹å¢ŠU¯`BB#/ɆùgoîÉ”!h³è×ä8¸Pš8í½õ9;;'Ój—,1Z%ë–¶2iU""†QÑîQ,C4Á¿bU!›5?>œ³‹ÒÓƒ!äÈaAC%[cΘBˆÒ.c‚ŒTKÏü:#/~„z#êEöZÝ}gHQ;šêgvó˼ë·tv–ò˲¦Ò™ú:áé–ÕÍFÚÅ¢ÑmmmrÖË ¶º;«©z­ÛVòZ¿ºfx‰6jz²K1SÓLðmÔC)XRWÑý:mYÄg ëŠGg)öb­#,-h#/1"¯›tý‚ á'̇MQ%° Þéô3î—]Ô„¾Ä\Ì X†tÝv{ŸîãÏÚöƺ!žt’¡ÖÏÛÒ­¥ÚWWß2ZÏgŒ;mX·ß­Ï­û©–]9!¨EŽY,ëUa7_ŸI[ìkÓ•Îþ}üÞ&úôDNÝŒ:×\•&6RÚÔ›ã¡\ùPVÝï·:uÊÃDΜ¶S’z÷Y#/™ÏëΞÊcC¨Â}ì ’aŽ(%‰3Œ'‚^JRñÕJ‡'Ó¬ô·+>ÎÔ‰Û»¶s!Êî±oãOͳÚ.åâ¡Ä€u_#,öæ3†´d#*ÍzëŌְÁÓ6Û{ÇY*ÌOR͘—Ä.:ã[nÌͧ#,åÜíš3Õñ¬ûj­ñŠ\Âé ès1柮Fgîó†~Nnp K(INÇGm"xÓØ N¶ÙùŽ~‚¶ÅÁ⩳J·r°ñÅ Ë4й¥a½5ˆHôW¶5)…dí*#,ªz¿¬\5®YòÔ! ÒñçŠ÷V uÈo1ìÈ2ÝZ dC3¾æø™Ö çñ<*Ö®Â$<¾}#t\Ø£ ÙH„‘öXFF‘àaœ#*tŠE¹#,±]Ð Á Ñ8§õÿLzÉÈR9AŵáÉ]Ogmp™éçã¹µÝ|#,®RÀÑór<of }˜lMhŸ”œ<J«ºjÀ…6ò+·EÕx:±`è4zo•…7;$º”‰Æ¬Ö–”ƒ bã4¼qkº”!r®èÉ å%IPC®ˆqê=Ãt äBY¿L<-Mš‘ùÖd÷¨Îu,ÙLòçAœxR/ŒV-øÓ†]¢áG0gåÛ¶÷ÓYã´:FÏ3å3¥€ EËTÕÏé%±ÔZ­¬á©1¬µŽ#,çKC)%˜½—×¾ÙàòYÞ\Û[ND#/n+š•Åý›í¶-šÆL$ƒ¢fb6߈¸á¯Mo¤NGöwvvnVÓ]‘éXxæâ6¥¥9ŨBzxBI$;¸‹àæyʪͼè±>7µ7@"È#,èð0î ¿ɵSú,·7¡³fWÑh‰ÓÌ„ášU¹{âlC"´s9•—.ö<W£;/o(Gnk#*û;8‡êãÖ¼k›#˜³.ÒûakÊC;±‡u´'vÚxáÌó¿Ëj=¶ÂÞxëÁÞS”SÉ$ôx34ÑÄsDœiñ/I^Ù¯,bäC‰uòqHrÈg[ZNqEïº+X̘¶È„ŠÌçseSÍ{å9jÜÅj»ÅkB“Õ{‰º£¶ÇhÊcj[KN_ösJ+×å׿–õÑ÷ö`²íÍâàŘæCÎ8-hù*1º}M CÌt9Î#/ª#/ì\[<uFpê¤^Tªc ûÏ ÝÐÄÀ¼àn³àÛãxÉá>—ˆàDz®™×j8:eŸl“Zxô‚%Ýåü¦[gʘwwBÚº¼ª®øºó|m7Të+žz=˜¤ÇvæW lˆ~N×0³ÃÜ»íþphGdÛ®é¤ËƃÛf¼½~§•óäìê½Ö²—^³ñëío\­ñà+ÊØD³ŒûÁ5Ñóð'®Æƒ"–1±ÖœQØÎ#±ÄÒÊ.&ý‰é\aïX#,³¦ # Úr6¥š. @ƒÕßFãv%½…”Ývx—}ØzñП6»hd'(O(im¶æn¼F×ÐŽ4&d¶êK§z¦IáâqÓ}¶5=}tTnœâO‰e3ç½(W;2Å´ƒ|è0¨P;Q®Áài%œa†…Mؤ"Ðt4Ãm®€ÙÁ»‘ºÉîAq<b¥CžÑ—òÄ#,hU6.F­>½c¨ŽsJhR:„åqÙ†E°³KeØÏv b»°×(–Nо㸠H:´ã¦{fŠN@í°S#/Ÿõúõ(6+€caP¦ ã¿žú7Jç[%^¶‡g M³=¼ªCf×.h¼01º±Ô`vÞÀj~¶ zv­ë4§Ïüç—Ù:*gw$¶ D;¨©¹‚f¼¦ºgaAKÕ¢X,ЊS7#*"‚‘‚Â*böW£qÂòv*æéÝ]›ôË-ÚXÎÈîè …¥›¤…hÚŽœ ³7q•(®ýfµ44z2¸Èl»e‰1¶yL°jÙŽµ9YF£¥Ä ™áUíLRg»#Ys¹÷«Ë¾ ?šëoÈruª‡Ž´’Ž!ˆJRÀ-ÛTÚ5 [û‰»mÃ+Q$•7n|I˜sÐí¨%eØÚ{âØ²øOb ƒ„TûM0"Uò¥Lá7Åh×§Çl‹l!#,Âí<Ki}—ѪåÉo(©¥ÚÝlÂFsbC VÛqkÍÓì¨ø=; …Ú:TPŠ*¦Òˆªššr8㟸vœ‹L…‡×âW\7®œ¡rº.gÄy/,¹Ò_«æ9òÅoC<o> œçÜl&ÒóòàP a‰›ªÆÉåesC\tû0Ùw1¤Ý3ˆjT¥ã º&%°ÄA™§ò8r!E˜ây™ÇP<¯¥ôñMŽ‹¶Åí5Yž(²Óí ¦[E7{û¨}u#ÇAÛŒ>ÆøåÎ#,Æ0YVAK_-JR6W;N¸õÇn'¼™6:)!vï@¹#Oé°FëJ®µLŽo‡Þ]±n`C‰ÐDZV# ‰X×ÚídSÑcâ+²—:e£¦µ½h1®ýq#/»7,í!Ço^§®g¡²ÅsÆÔûø9šË©ëÉújk/\ÁÛ ¡Ð»®ºË|Pr‚ŸsmuërÒÜzùøÁã¡ÔΆ¦­²=o³v2`=w+sÒ_âcU07«¹®+Î]-àË,S^•Ó¼úáõŽÈ[ù(ê§ÍÃD.!/)ëlxÄ–ä§0‡> p™áoÑÒ?NøŒ×Œùr_èõ¼ˆòîûIc TEdg°È•4hø}>M‰MA Ñ¥«ÓCï3¦“Ð9ÅÛ#,h«»›³¨þ-#/a2x÷ù…ĬàÁñÁ…@lîœ*"Ú䈀ÅCBk VÀ½MË2*-Ý7­=}›ÇSGÉÎOÔwÃ3 yQÌu4éxïl2=Ù©#/‘•WŽïú"[Y!¬*ÃѬ橱òÐ(Cµ{ˆiÀ€˜Î0ª˜aô;¼†&–ÓךÅñUv˜GÍZ j(±Í‰µ¶ðëËr·ëK‹0c8MëESÐcÝܶU#Uu#/†¦ÜTzÓ·0äi¬/#r§ºÕi,ÛsÈ+¼jM‚S&n(3pR;@©z’p€rž"3IÊ£Ù"ºá‰Þ‡†@è8š×bœÂ#*À+ZçE+³+ä`ƒ»ÎÒü#”Ún­¬$È%ˆ€>¦ SΞWñ)רnôVf,Š\Så[ˆ„#¬ »~ñ…#/E³î#/ã³%½†?S…ÖÇ"u à‚O7à¼#/ïcg®Ö[mƿհÆ1fýºú¹É­ D¼:ïöR&°Ï Ðy€r2¥¬¬¤’¦º¯Ñ˜X ç¡]@k´z såé—Zt#/y¢o±ÝÊ\Ù£ë+ãÙ˜ØT×öŠ«ô’í¡(ÐIøL=—y­ÖÒ§³&‡¦ÝÒpC’A1­0%M–Ä¢ƒT!!aDÚ2HÚ@•dÈ(ÒÇ[š6II´[›^7’w\’JÌÕׯ6»zÍsš½^’©h­#*阈¥ˆ ƒ x‰ «PE¨£‚‚Ħíì^Õ#‘@éX,m5€ÔPXPU ЉCd±#/,´ FÅ/j‡Fëé~Ó/í5WŽÄ}§bÖL2€t9êׯíñ˜7K\eàd‚¢#Òl(©è4°ÂЖ·#’Æ´ÚÕ¯Û[Em¢ÚÁL„ #*a”’r³DÓ9}kT™Çƃ® ¡¤Õ,mð~ƒÙöÝãÔÕ™e©ÐRßãôбŒc`ÒÅ#/ÝD2†º>œ(ÖŠ«wmkƒPg&ÄËø#,Å1h‘]…2¸™øMO‹7“lTé­¸ÃVbã+«†#/RñÚ×ÐK£!#/HR UÐe!Ã)TE|¸ÓâopÇ­jê›Æ³‘, ,ÊŤÍÐÔq͉¨Òm6–5$RÂ]ÔV6&šcD0€J墣ܔYÈdÛ{‘§„M¶=po™×•Á8ÐhÍàŽB‚Ù7T€²bC š‚Ôxb2Çw. S5—¬2&àiC¡%#/ÄF©Ñ!Óc3aR÷.¢sSFíуMÜU­=6µ­S Ü!µ—IÖÃZº¼âÙη–Vñ“m¤†6X*‘£fäEÓJ#,©¥Ãv¦ÓÑš#&›j#,YÁ¶Ød™ÒZü÷Ƶ:s“³v´ÀXVC3”ﳯ$ÃÁ&´žþonÛÈó»Ét«¬œäÈŒ{±â®±‹W"ˆs#m2‰l4²©½\Êøf•“%+XIw­Ü&]J&0gHnÀot†Ú4ë;bµÍ¥"NÁ8Â7N8ë¨ã×gÇ *Lá‘9lw“£4< þlÀ{é1658‚/*N·T!­#CLäè†JÇB-£pÊR#/”*à Ѹ)¡ÃHi4ØÄÔ ^5hÛÍÅ·“%ŽºíéÎÃ6¶réñ †@u¨lŠ•®¯4†®®ÖÒj0Ã(ÕYÍ–mÝF?'r%ÆcAÔæ NiàÛ}zñ Žã Ó”¿J„FÓDu5OéÊËÜ‘ùÉyTlæWz:DÀšY¦ÆÎ³ŒÇv~ i€¤WµßlPË`”¬iªª½–†BŒ„#/Ój²°<#,#hÆi-hœŒÆ¹0ôLÎmª"fæ`éÞÐhÆ>TºwÅFñ†FóHtë4ÛmºÒ æ(­¬ÿRV£â¼ÃpÊ(øD#/14”{‘hÂ(ëvSNÐ4Ò1êÀÜ€ù$¯´Ðñ¤‹š$‰ÃÓoÌ¥08âd€ÓZ±™Ù6ôÁ—}X¥ d#3»¸HÈmÝ&47,ÍÜhZ#,2j“#*Š…”l› „•5$ÈÄDÚ*‡6‘ð©5Œ;.©PÄ`Íjs¥#,4´ñ˜“C#Q©ùÖbË8 ÈÇX3§aÈù…Š,^\Õ²¾LÖìê@^Ç´2ózåÏœªj,DAHŒ£´²î¡ÀÀbm¯™áèõëþü×~×k¢Êd“Y²nŸm«õÙI¾óÄvºÎ±&îM_··Ç÷ï’¡å8#*œ'}ª0O´¾ìÜ,äŸ[ɾÊxÌe¹¼yE€e¾ŸX>ã²@—Í3:ì^އïá¹½½SvFµ4C·#/1²³mlºqáôÄÈ«õ=A_RCÍü@’ïêõ‡èéO¶Š §*×% ¤03‡ÏÃõyÁש‡/0<üSÍc5A8÷wùUc—dî‘€¥8MeøÚÁ#,‚âg¥þùQüú´5 ›fª¥pyr˜gÓy½ÏM¸Þ1µ7tÝÉ„D@täîÝ™ULm =ñ„–;£×è®Ï.CÐ>‰G¤Gh t 6aÎèÙY‹h¦¨Ú @Ÿ¯‡Øtøuäc::‡§tò¦ T$hEÍ⢆HvÀC#/ÊE´L—-‰u×[¥^j™M¶ñ¶LmQu×W+NíWuÖ£mNud«DE±A@U"¾"êÀ?¶†³OÓhT'ôqò}<ªúŸÊ+‚‹#*"2aIZØlcHFHÄL”i¢i(Z¦VÂkɰ[V)(ª$¬‘†3eE¢‘–…4Ù&”›%(¦Q *#CZ#/‰H–ŒÅ3E)¤R©FÉ0Û 6a”$˜ÖÚH5­ypé<åy¦£°ätPÈ_dN0=¼çc9n?$Ü/³eÍöï~g'Q¯ó"HH3‡p‡¡<~~—Æ^Ó—Ç%A÷8$´ R8 ¸ÌP¨PÃè0/Z£†Y.#/²ÄLl^ì&>bm¿0C”m{Y² M+N${fkC"`Íq>:Ÿ…é¶í°AÚ—~Gy A$H¬&½»—ÀÈ8Ší:¶ö+‡I F"ÆÀå…U1w.üO¯£Ë0÷jêÏGl`^ª5MHm)ÞT¯¯…мÑI“7¨ôÑdÆ+00#/Ú?¨¨Á¿j5Q&Ûb©DmIkEuª×+/ÕÝnUÔ)51­c>»ªæ2¼–š…ÊPJ¤}ibÒEŠ Ã€À¸dË#/E…J!ì–~ݳAKQŸ¦å.¸ßÐÍ¡­‹>mŒÄG©m@Û1q?º5[cJ¸º<j*(àÉZSR•[(ñ@Ùƒ’#,‚*!wNRš›¡`€(dX±Þ'’#*± ¬X ëàÕhÇMî¼™gg+ÛÎ×—;F2•Ñšö•å%ãrÉ6ºíÚ Ópó/ÙËTÜ’ÑpyŒ ¼£ížq¦V‘®Q*Ú”¨'QÕFÌ„Îg›Òyè4%CÕ/3kš¾¦ýM£G½y«¾=À×:í¶û—­®¼‡­;”Ú6ù5»cM60ŒDlcŒHàÑ…Ÿ×yÀ‘xjpØŒòu·u#ªDèã‹i4Øóôê#˜Þ(È¢'DÍ! xCÂc  êG˜Æô’ŒRÉÖØYU&Bà&&€X‚A‘ ™Xš–È,C“1—’D’I"s¸*‡KPõr¾ù0§B‚i¢`#JWÛ¢ZkXHª×§µ²ž‡òcn;ò;HVìûàNîîCÑV?ÙP÷´LGÃO‚1L~ÜãõdS!»HÏ(0¯x–gq7˂۲“ÓÚ@AÉùœÂu' ›Ð²JªAƒ¿  ››°d=…,’–’áŒ3Ê‚t‚&ž!ž~b!ï>3'†ý…Y5‘X»¾ª-xýšéû7¹ŠÑéwŒdÅgãá匪(ßoàÑ$#lç„÷÷`Gæ¿#*¢:ïÄi1#/šCKè.󅶤‰èý€­ ›Oó4D}ô~‘EAI(>E²P™åBÝ´¢R¹ºC6Ó&T6#,š"J‹Av">èn} ®¸#ÎÓ˜eªÐ‹êôž»¨›FuÕ~Ú¿î—Ôú³0NÐãcÔ)¥®l«¼ç¾ª2(B°]êË>TT·ÀdfêAiH2ˆH-H£ÈèÔXwiÇi<eº»äÐú½I7®Ð6¢j̨æïõ)‘’øB‘E¤÷T¶›–Qï8vþ‰›õž†9Aƒqb¥¤L½#/,ƒäÖö°[#,ÒÙ£@¨ï÷üü@“/q¥‰8#/±çˆÐqÂw´-7Òb»eRj93>þ©§º Q<: ÇàôÅ"2@Db`ÓíB÷ømEä̾×ðû7ÁDƒƒh>'ÂÃßc¦ϧãûlá ò×9¦%Éõºgá÷FÍqØéÍAªé¢Ä`C$Smn¬Éë#*;NÔèÖ{Òw‚dd5î`\ÀðdåÞ¸"#*ƒS›±ñ Þ#,ÌåT˜H%ó¿h¯—>ÚÝM;½í/—QD9äÊðìk#/¼ûáÜãXëÆòFtd,kRÇ£œ”ˆm²YÜõ†ÞÆÙÞD^ñeyz>âª4"RØÃ“u´*é™ákYÔÏ hg6UWXu…°ÓAI  …")#,—[Þ˜–„©#_C+6‚Üdÿš TTZ'L‰0ß#å4w.äÖhßL 8Æc7)•%0æ™âV*TÌ€2N$oJ f(n’ÐQÖBâ¢öˆZãfùÍ#, G:‰æm €.jhÎÎgõ,ÌÙõ³r#,£Å°ÆÈ ”ãi8€ÔdÚ,K·Ÿ•<ÎÊ ô˜NØFzcf¶a¹êµëeœ“’Ct<’Á5åB`°’&”ÒÂ#*k#/#,ãð0¨J@bf¨F›ìR42´*ò‘>œ^#,­“a†p#*Q#/°Ü†Ú¼Œ´*=i{µ…Š˜ˆT)"©¸PÁž¶¿mSð€˜Àcb°wïÒg®»rqBë­J¶˜hbæ^X@z‡H²™©˜W¡ÆtÊb@ô§(zO/kÙÃ9÷Pí¸éƒFŒrv¡ŸZ¸v“-€¥+x¸0‹d&F955:fbZH¨™@œ“ ²Îؼ~>_î—²Þù‰mmS×L¦g:uqÑ€vXpI—Û²“,™¯Ná¿$ŒrÊo µH•ìÖÄ¥eÀ–xðžÞüp"± Ž Ñ#,Ê‘ZCCbDVÜ4%b­ Y1Še¤/BV²`’æAZ"ª”q'y˜å•°^ÀW¥™”­ŒöÝaš•˜ó#º·KAv÷†=ëy£ÓŠËÁtá0%ÌoF1ÙÒP創ªŽÒ<Ê–27×1çKeh#,bì¢Ç-Nã¯w¥ƒ*#,^kß,<Ê0há‡~Y´ï\Æ`ÚÙêÀGsjs&´… !ßH’Út˜m*XeaLà>‡ªKK{;¤ÌI©0¶Ûm,ÅÉR=s§“™iIeó»K'Ðôå±ç¶#,Œ’úŒ‰Í.IˆfáÛpÞQ{HhM)ï‡ €ïjºlCl‚oO‚ݶةhw%„^Ì Õ-²šu8‚Çd;KÙ.žõeÖψ[m0Zu-eÄ¡ÑJV ‹—Mýš’-º»c¼Ägg…8!9Àû#/UóÚ$T°CóÃÆÖçšaU»ÆD<DC$–Ê0ëN“ŠŽ,9ï4`>ƒ’γ ܶhÄ\2y”ÖgÛ2F\BÅ>þ´xXX½q-BÕuS(yÄ×^ŒNí¼'×Xªñs&âiÒtîJ¥k޵#/µ‘eP#(k—„+r¹Ã•U[^0V$#/˜k­é&õ`I ’¥G@8…ºŸL½(‡"ß‘kg Ì•šfÚj2­n#/)öZZXRZ:.îåÀ÷Œ=õŒ¢÷è"2pk“*Ð"ª}*eÇ ÄÂfÁÐ7§mÌtàÏÀpûõÇ~3·9B.ñ!ÁÉxuÏ8[sdÝ8|°P8o¡nI\DøéøË¸Dp8o¬#/®½4i²5çRŠu#*Å8¤Ú¤<Ì@­# c,²Ä ´lÀV"„*0aª:³M±@9ÒÆµ¥Ëˆ{ Ý-$]ÒA!'>wÂŽ¶³¬×a^ pÛÞÌÚÖc4/_L |œ ÊvÔ`óñãó\ó†4æÏ:äa4µ‘ÏY¢ºÙÞPìÓR3Cj¦:ØÖ+.™&.×Û®¼uÞ…ÒÜ )UÁ9M(è=JdÝ9$Ÿ§_çøÊ4øm9§M¡KÙÃùæ­¤ý=4sÚ·ÝÐ>ÁPb@P“sexÑÝÝGÀuóXxë§‘65;ŽSã? TÔÚ‡ÓŸ,Ì‹ž“ Sz_.B=±É5Sœ<’GÁ,-&jeJÁ³†pѼ˜,LŽˆHd–°å Š–›lìþw¦”úmDÓÀª²¥È,PÐö.&Çã_—MÑ l:0‰Ñ¡V‘A ßJ,y#,Žš¡BPtžlÆ\bäù1)’ø½›¹mÒú5eaFUYK·Wiêö¡˜K#/œò±ÍSõÂv"roÏ6Ož ç4e;Ñ@L4ÀÓH§ˆªÓ˜6ã‹ÑŽÂhÙ9’‡h ôZbmÙ4ÐÖPå½1¼¶çu ^& w0¶YÆ¢/LÜÌÕ„Rï;&m¦ž ®íxnòfœ‰]-Êåë#,Ì#*ük4Ò&§n½§«¨&³[T¶¥‡O]nN2AË«& Ý«&šoÆBÃGå ÐË®‘M 3w†ÙqX‚ùaÒ7ˆâD²žwd,á´K D#,U)[ÛŽû‘Ö$„ƒ@tG¶.M"]Ĺ5vmM"ÐjvÓI13?~HâÓáÛ#,µ"GÁ†žjWF/#/#,K4m Šæ©CU &Æ;À÷nÀ’øY‡^I­F#*¬áÍ0Qds°0bšøP›Ã| 1‹šÆá®–ÄA `Œ‚ ÜЕa¨»5IBkØfM7L¡ ŽAŒCN‚-.N³03'ÓðòäÇ—vk¡¼gt;Ï{’Œ¬•&ᣙbª%#*˜8é’°¡qŶfj61AHP¥)K‚ÀIŽ4o‰ÝÌÌèÙØ« Ý Ä°Ñµ ŠÛXMd9”°ÚD¸q43‰1‹¡P,pĨo¿…Xä$#V’2®[läÀM£”‚1`ºSFΦ‘ÝBFÖêJ€l#/.hE€Æ®•Õ)1 ⡘”4Eß#/psÏ{¸ãàÄF l4Ð ä3tÃD²Å°œ V°†v6ª0*ÂÛ1¤T°ÎÐÑQdn 1*‚†ýy>^w²Äsìp èŠƒ(¢¢"€É]¹Ï»^Šš×vZ¯çë“Ô7#,?w5Š ÂÑv","B@#/‹ kP´UC (#*¶ß€ãVz 9‘—:郸¨\€q#,¯ŠÎ+H t_¯æ¦ê–Òü¸ßL…*ŽH†v_¨²˜Ò‘6Qš¶ATA³/°Ú»ÀœÏ–fqÏyy,37êi1ÔyMŽ)ôX#,&A¸Ñ)õWVª”©±—fM†g;» k—d \¨C9È×óK5òíé]yë«’ªŸU¨‹ú ›£ g.e+ÙH¬ˆ¼‰¾¤9_®°—ªd ¢‘†’œ)7‡vpÒÆˆ?–Ýé¦NÁ¡o\I}×,±Þ\©‡+,YÄL"«U? ,“LwA™)å+H¾’&™2wäívÇÜÄsVš<º;ÛGìsuÔˆpœa€Í#*µ+öÄC”¸Ù}5S±n‰^Fãs¯mÍkÞç¬Örâ(².nôÎ7ßVeŸ9•s> (A=´`ˇà|Ôè9e¾Dʳ9ß^Ø¢{¢#*ÙöÁ¾ë¡¿78ÃVH'Ö@H3‚5RE<Rå­j4S‰Á‘!&}Ç…}çlÜÌc¶êà;IZ0i(Úc HQ;d‹^“!2Jf¼KNñ¹5æîÑš‘]ço^p•éÓÕÒ¹q&8å ÔrK0Ä$(,ƒM4¬´[Êšõ<õºæIK³[n·¶àÛPÒI=ðÏ®,ੲ¥=+K8Ö\†¸í„òàifní5aÅÑŠÌÌÑÔ«3I8…`È2!ñ)†Ç èìíÏ·¿ÌøÃ'†­{‘#/Gè€ôÁQìG´6›Œàþf¡$Y9)“çµ¶ŠªŒ@ˆ4:HñÜÂÛ ‚­#,¡]’&!’˜W‡Ä:o‡(nB¥šë"h¶#/:x‰A¼ ==6 ÌåÄ’ÞÇb<YiÞöÇqœð±Ûñ‡ ù¬!êÛÏÊ+uw}•.=~¤žŒÎ‡D‹ú²ní:˜uŸ¬Ù4(PøNk±ƒ·e†Dâ¼äÔã#,T#NþìLɦ•—`píݨÕrd.0)2å“-ö&§æÊ™“n±“w,7¸ù ( ›XMÔ " íŠ2Š>õ¶õÑÖ¢šº±«ŠðIAtÀ¹¡´æQ4pÌ|l¤µE—-" 1ÓËÍŒ6‚ò@61ý;}¿K4Úb©¬DõÐR?i¬ã†tÈkÔÒŒ™Ò²iw#,öž ?6PŠ ¿T%R+­~¥mÛf[M$¢±l­­)FM¶Mi•÷f²[^š×,0•*(¸ ¬  04ˆ‰r#iQRö0YV¢È‹d‚·HŽˆD€°B&h¯LPw($öeèÊŠ•!tËþŒ#*ìTCg†U·¸ÔÀêûlÎ,"`ÈŒŠÀ#/B#*ê½ü|9|_ §Ø¦¥ AR†ü.ã0Ô,¢²2Œ‚¯;~{ƒVúÃñצvž¨ãžÏ,kŽ[·Xé#,âèшÍÁ±CÖ<yÖ•ÄêÉ©î$高µÌbΚˆJ)c€p 0dX„F‰šB­J#,…j\¤j±D€(ÈÙ\Mp¨‘2YM1:ŒJ±ªÀ²Ó.[jå/[dÚ®ÎÊéWVܼݮ´U<ÜFÛªMkh¢é\@ë9·œ¸oÓdVm6ð¶À8` •ÍU⥅ 72,Às4µ§Ü€=ÁÔñ=<^Ia 1V=¼ý¾êfnNf0šƒ*Ì‚BšÃzÖL‰_\lÜ3ÄžHLë¡ÓÌ;ç›.ƒ¹Ü@ä%‰#* Åó@V‹ºrÙ˜oôÔ%ß2ɢϊ¢Íô0€öP$Yu©%!((ŽY!C4ãRØ/¶ÔQ†ÿ17w´ð›,@#*-„n¨äBŠIóüš¨ù’c–ÁÆ÷€ü ÇÇNƒ|0V!<ÇAD¹ã;04U×;‚‹RIA@ ZlTj"¥xŠíêÌJL°XéùoÄ,%Øþ¾XÀÖÕ—Žvq1úÌÎ DßZ#,Šó÷Õ›žGêù@ý ö¢€àpŠÒXb’ ÒS*œ9ÙO߸An‚¹ë9BPR:¤Iû›OR|0§{Áà{ %àåãròI¦³m¢™´š’•K*™1¶%(eªØÕ˜k ¡6Vb«IWð4V®3˜¢2$€ÅŠWž „tó'¦8±UÑ‘ <¶#aà¢N¾™¿Ï59¡¢Þt!¨Ý—GVƒÔ íX!°M¼°îÈ#*‘ #* 0}ÑÑŸ28O¯5Kxléön¤œùÚ*‡Á´OYﺂb ª#*¨íbü3×Ó $:N~;øÅ½õøv–õ×­¹7Àk>½f9”¸^Œ2j•h«Íø½>nÏí©Èk ‰ÛDÕ3£vwwHƒraÛ… joJ ÜPmÈ‘«%—rX>tDÙA«”á ðÑÇH³¤1D’WÎÂ#«ãzÖÄ&‡¤%ÃÐÖ`A•XQ[ÔíÇ1ÂI›`@éi“BJZ·ÅXâÜ ˆÁ¨kÊÄYK’hHM…í£¶RÀÓm©Õ“‚p6¡ÈAH#* ®#…¹CyBUË(nCMdÍ5¡ lˆ˜.éÚîôENzé ! ;BÖ‹Fˆƒè2²¹J5 ßä­h`}OF´·ZÓ„¿9`3ù­“d]S“æX¸@5$×Ûèz”²Yî+¡gwB0T¡W¾ÝÿE êcDR1‚M:î?h*{;!â‚øxxi&;ˆ!¸ Š# CG4U&ç„z.–7ü#Z|<å#*^þó³Öw†#/¶*y25Päx(Î+4S(•ñêöù‚ß{aˆP” • ¤TÄ–÷ê}{~yõO·õô2tª“;@-œk4©#/S°ÛBáÞ—g?œœû5fÆÛj±¸”1ŒSfµË<gï?“‡¿wÓÃÛ¹TD*b!p"7søäмÀ¤÷€Ovî»ú.óRtjû;[u\#,›DÔ<€ÀP¸öÒY³^óüô5Ôícš÷y‚çOÞHX´.…>Q´þ;Xˆ«¨vÅ•x(ôÓk, N½ÚÓk5ý”Þ¯«`Hd£3=uÔFÄhÒnuÝrF$Š"ÁJ.*(KHS>bSv\—Š¥ÛNRQ´¥”a¤6ŒQònÚ,äl–5 µ&Ò!.n’K&Æ”A#¿ …G´ýiÚ$ Z†âÛ¶}^ãÃÆQAEWȯ¶Ç‘‚ög¬< +5L'œÓé} §¤çÔ__áb,–Òj•f6”²Ú È‚#,Á|#,ÃÔ‚tÈ„„,HTjR66!K2U6üý¯Ñù‘Q¾ö«é¿‘†‘hÄØØj™¶*Åe)RªyÀ>^®üf DEØ4aú#*ˆšþÈJZá¾{‰™…"ò!’žLâ™Á5$`äNPd2Ò5EEŒScXZÊØ¢ØÙ‘‹c+M(¶h1=7ÚMµ "@ˆg —€„^§ù å~‘TØ»ü:ÝAçú~ùw_q$ð#*ñ½aÅ£'¼}›êÙS^eMW!aWÛ²’b|á ˜7‡`á"F=¡«Á®´-ÌQÓI޽¨¾'¥Ï¢}´ÕxÛô^ö T©mŠ6ûÎWö3û¿:$Š›ò]ì­ö)0ï €PÞÈPŒXD#,ÃùPÞ›:5ñö`-1¶ ØõªlúrAÎÈ™ )îZ€B„‚ô#/&» ‹çÑ·›Ö¸¦µ&®nª‰kIe¦u6W¾íå1­¯V1!s[}6yNÍAþ$6PF…`65‘/*4øÐ #4ˆÈf÷Ø¿M¼¿4~iÑ󬌘eë„ÝáË^ *I¯Ni`MÄÆhvø([;3‰iHÚy—ËíÈ+«`šŸ”"MÎ%«YkfJ8Ô™§óÑñEËz¯‹{SßÎãÿm$sÒÄ}²fh‡ä#,At±Ì~oÀE#/A(óóm¾Y}¼nÉAªY¦•$%"£-ŒTPj#j“j…-û[oµ«ÆV©1‚¬Š 0ˆÏó§³¶ÎÙf„‘¸’)THÂmB®¯À.mˆ±„^q°ˆš6™²AòvîC¨T#,úÀ=ŒúãžõÛ²ô;®:‘Hÿ`‘ W–ѪŒmAjPª4&Úl±±V£)k6¿n¿!Ã=:›üݽ´ªË%$å5öãùYõB†@ÇEõ9ÆÚûÚk‹ox„‘µ%)”p‹,*²Ä¿H ð7;ç‘V"´¥·÷žIdní™bJ8,,ŒN(&xݬlÁÉÑUÿ³² ¨ØØÀ;!…^X¯:×Mã­ò[¬Òjh¥KzÍ…vÓ»6»»+ƼÞVº¦Ñd¶ôÖ䨷›ºÊnÌÊ®¹»j*çjl™e«Ë»i“k»«»µ²l©*dJlÚCE„ˆ#/1rR,$0uyvºr¯"o%¶a¦õåÄUJilš“*UéZê×AEÝ@…°‹$AÆ ‰#/$R×®î[µÝºË[.šé+‚"g\6<Õ0 (ѯhFÑöÕÊ6'î%øI7øƒqd8о4d-‘QŠ ™’1À*ˆ’þ:"9‡ôokÌÜ1Ãp¯àbÛM$CFÔI7œb€ÃP8ÀÝã³ÄÞÜíuêÓªæ‹r1îEÛün_¶à†Ô‹˜Ñ|JžÏ—|óo ŠvpáŒ#/fo‰¬7 ƒ•)·uF±±êÜn%Ä…»­ñãÁöþ¢Ó#cÔ‰¡ª©S‹¥ñ:3¬[À¦³M4ÀeÂßg‘™‡®B†vÇœA$QGÊ)‰Ä¼.#,õêLqá)Ñ®b~ l"‹±$H; Ø`ȵR] @ÝÒbz}7˜º²"îü‹ïÊIy#*ˆ;r¿Õô:}ÒV]×J“×[Ø7ëM#/ØvòÜÄÜï´G#†˜G¼‰4û}áÄÏY5y7jÀùE’ hŠTp7ÃmuS©ï5ps.1û§¬–[!P?s°ì\ø0†”2|З~¥~ÈfÒHý´V0Ô䎦蔤OTê>Ä¢qfª›”ÈÙAJÒu2Ø*Ø„Ïq!¥µQ{†´Ìö'X›GS„½ºÙ€Bˆé†G%±Žß!®ÔÙ´“¦¬RòÒ4S*M¢¯┦h"QQ‹V!¥pýÓ‰«Îùçž_æJÉv˜ÑÑÉ#±U¬mœáÖA.îqµÿ/£˜m‘^hΙ-S¬ÔgÌÑÐB»{œ'9­—[ýô!D¹kšgÏ2Žë-“=Vmá6[dS)„Õ#C“÷$ ¶""³=ÕvÎÖ߯[$“­…ŒGX ÒÿXÕûê«À0 ÚˆŒ‹G¡[eopŠ®¾)ã¾”(‡ÜØç#*p0a9QõdìJgÜO*Óc4ÃŽ˜v+iã#,nlA‚rËCzY”Ê-4\Ž!!Òx£–»ò“pú™²À’˜ccò4s·ŠÛYø€…cïIÊÁ##Üj/´yÒq^’ E0{ag3´òöèd@Þæe­¼­§²Q½Vü½ä;¾ÿmµ`4Ö%k¤ûlî<b”º(‰>Üà„Ð?#,_Àx€ÈA6Ídméˆ,¤Aê#*kßÀ|ÖY…<ò^õ”€„qqÝ3æÏ·[ù¤üw¿NÝ€|‘ eyô5 lT&¯×aVÑgöÿèÿåÿwýÿüÚ¿øÿÏÿý¿Ãþ¯ùÿøÿŸþ#,–]ÿòéÿ·þ?ñÿÏþûðúýßFñú>Oÿ??ÓÙùÿãü¼ŸþïòÿÿÏû¿·ü¿û¿þ_ôù9Oý=/‡ýßóéÿ§ÿîíþ­ÿŸþ}ý?WÝöSæPû~dÀüCðˆóð?*&J^!d$Ì«‡ötФ#¼…AÜD¢#*áÁª`ñ”ÄJÕ‘q?èdÐ'÷$‚¨¨CCtºŒþ£þ@ž©îëHfgÕ­óÚ›kð*ºÄ¢9g\„‚=Zí.Í6ˆk3’BšÌAÄFÙ`þ‹<8ÞÊàY:Çü7ïÚ™›J š¡ý‚Û¡â­ÄG«ûÉî‹þ´c¢FG¸Å.f;k·½î?Ñ[›°TŸóNXs‘Œ÷rûm1¬öæS¬€½ z®#,E˜£ëý¸ÏV¸ÿ|úŽÙÔŸéð Žg¹gõ_Ï1x·¸QCâUË*À†˜ ÁþëJ’”X.–H‰&RHCD$­wû1ýPÜ'ƒCŽ o÷µ‹ž=ÿKáaN–&„Ìs+j²3Á[3?Úâí,{R¦¤ˆo½)žz\L¢ŒÒë!TøÞÕn(ÎJ‡—šW#,ÂŽO݃FÈ8žõ‹½¹˜ø¢3Á´¥RreºpÐÒðe–%²ØÁ ª%ƒ”>m=³z*(íZ¦Ãn­:.k,°F™ Õʉš–6‚XŒb‰bµÒa!&aÅåGÊY°²]É`Ë«vL„“‘•MŰ×Â!bàÞŠFîîÝ4A#,hÆó)¥&%aËÞÖKF5n¡ðCA§×\ÆQê™°›=NŽîì6P®"”Å’#.H²F#¹yÛÈÌ1—CŸ®ù Û‰™ùåžN~‚¶­y”ë³y.‚u§HØÑ®Á’À¡ w!†<±DÎ-sÐõŸëVvú¨ áç‹À@ºõ›5NØ–ºµš©ŠïIdÁ:1b‘q#‚êðÂ]ÂŽ3d0UÊñóöû¡¿ªp» kÈÁUE¤™åt#,ãû}<¾ïÖGñ#,/•íNÃ4DTdôÅ#*ŒP¤ÆÜ»ºàÔÛu—Àˆ9™BFA5íwK†Ç54ÿxÒ­–#/€ø H!.wwz<ǯ°LÍ]Ölk’„‰D†½C)—˜Pߟ N¥.$ 壯åÄfgßÿœM&†a~«FN½Æ|®îÛ"ˆ°"aŸ=¶t5hl-ßÓZÄé`Ôj$ ª@”Lh¡xÜME(mA¶6Ô²fÛE²V2F’aF2#/šúnÚ»m¶ø|:Õº"xióù#/‹œüHýqURÔU¼à Š#/[N‡´ 2âS@FHÀØ)ÑÒ5áõ~“Ig·¶‹Á~¹|-p~™Æ¸˜§B¶?ðãS9>#óò­_ª’"ŒøˆuÁ0W^ÎŽßðÉËå’´]Lô¢aͲ6r]ÔCã#/¿÷OòÂ>‚'Ëû}à ÝÇZBwn.7ÅPJâ„›‚t€;35v礀uÙÅ+,mD2€HÎΕ=ÛCéÓËmO˜ÏFœè‰óÔnñó˜Ú”6aƒ(idÇj¾V&è#,³QÄVa~Ú-€Ÿu›w…,øÍÁ [¢²ZûºWØf %¤ßÝršÑ¢ß·Í»,kx´[ëkš’±ô5]5£ŶôÑ«ÙjÞ¦µ&Å Ö¯|Ö¹h4Â’ O?fóL4ë'elÖæôP8LÉá¡5EiMŒþZéÖÜÿÎPÇõ‚s’) ÝD#,Ç{£V.xŽ ¿$&Z ÷øð7‰gÔ=ñ1^׿^í©륣€P\‚wÚt‡¢ýÑPh5É@$gY¼ti¡oøý“¿Ãì”têzUÞ¡©ö‡1|¡u?±€Qn*u>SR?ûb«¬#*P ˆ"A‘gMr=8m»¶¹²Ú²[i™®ݵ]–¯’Å6jM{^Õ­~‰mH¡(9#Þ{;>¿–šÈ¶|ÄÕ„éÝïOz/§­£îùºiÚf_-?{Öq 2c®k$Šz¢|eˆ2Ýø‡åÿ¹Cóm½ÿÞçû·…JÐx^'Å$‚ÀYÿŸd#/B#/ÿÚ%MdÃßû©ÿqÿã#*H*ž°C.¾¿ü'g/ýí£ÿ˜\‡ùòeÐpØ,òÅh?ññ‡þ_îm~…ú|Þÿ±ØiæÐìŽ\Ä<éwtzñã‡mø½N0ØzK ½þž#;â3Þ8×ÿ-§×æ:ÿî2ð¤ý1ûˆ—ŽQH@ü¿ò¥ßï—ùX2)Á†É“øÙïóÚkÿ޶wmá‹p¡]DÝ«þ^Á¿#*Ê =þfb~-`†¸©q$ B߯¥øhµœ•ÛÄ⨊gßf«…ÆY̘wÈânÓ§m3 ÊÊÇòç,Má†/-„±¿Ñ8¨–¼­§0aw<~_o,Áм²L¸ÙB·9Á—††Š$\ 0Zpá¬8Cè Ãr†¾‚§@ùdyòöΰM…Mð„vE½Rh{Ìx¶’HÀ„œÃ‹×³g«gìÿ™¦çñ?oê5~oÛÿ‹¹"œ(Hní ±€
+#<==
diff --git a/.gitignore b/waflib/.gitignore
index 8d35cb3..8d35cb3 100644
--- a/.gitignore
+++ b/waflib/.gitignore
diff --git a/Build.py b/waflib/Build.py
index 1afcba6..1afcba6 100644
--- a/Build.py
+++ b/waflib/Build.py
diff --git a/waflib/COPYING b/waflib/COPYING
new file mode 100644
index 0000000..a4147d2
--- /dev/null
+++ b/waflib/COPYING
@@ -0,0 +1,25 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/ConfigSet.py b/waflib/ConfigSet.py
index b300bb5..b300bb5 100644
--- a/ConfigSet.py
+++ b/waflib/ConfigSet.py
diff --git a/Configure.py b/waflib/Configure.py
index d0a4793..d0a4793 100644
--- a/Configure.py
+++ b/waflib/Configure.py
diff --git a/Context.py b/waflib/Context.py
index bb47c92..bb47c92 100644
--- a/Context.py
+++ b/waflib/Context.py
diff --git a/Errors.py b/waflib/Errors.py
index bf75c1b..bf75c1b 100644
--- a/Errors.py
+++ b/waflib/Errors.py
diff --git a/Logs.py b/waflib/Logs.py
index 2a47516..2a47516 100644
--- a/Logs.py
+++ b/waflib/Logs.py
diff --git a/Node.py b/waflib/Node.py
index 4ac1ea8..4ac1ea8 100644
--- a/Node.py
+++ b/waflib/Node.py
diff --git a/Options.py b/waflib/Options.py
index ad802d4..ad802d4 100644
--- a/Options.py
+++ b/waflib/Options.py
diff --git a/README.md b/waflib/README.md
index c5361b9..c5361b9 100644
--- a/README.md
+++ b/waflib/README.md
diff --git a/Runner.py b/waflib/Runner.py
index 261084d..261084d 100644
--- a/Runner.py
+++ b/waflib/Runner.py
diff --git a/Scripting.py b/waflib/Scripting.py
index 749d4f2..749d4f2 100644
--- a/Scripting.py
+++ b/waflib/Scripting.py
diff --git a/Task.py b/waflib/Task.py
index 0fc449d..0fc449d 100644
--- a/Task.py
+++ b/waflib/Task.py
diff --git a/TaskGen.py b/waflib/TaskGen.py
index a74e643..a74e643 100644
--- a/TaskGen.py
+++ b/waflib/TaskGen.py
diff --git a/Tools/__init__.py b/waflib/Tools/__init__.py
index 079df35..079df35 100644
--- a/Tools/__init__.py
+++ b/waflib/Tools/__init__.py
diff --git a/Tools/ar.py b/waflib/Tools/ar.py
index b39b645..b39b645 100644
--- a/Tools/ar.py
+++ b/waflib/Tools/ar.py
diff --git a/Tools/asm.py b/waflib/Tools/asm.py
index b6f26fb..b6f26fb 100644
--- a/Tools/asm.py
+++ b/waflib/Tools/asm.py
diff --git a/Tools/bison.py b/waflib/Tools/bison.py
index eef56dc..eef56dc 100644
--- a/Tools/bison.py
+++ b/waflib/Tools/bison.py
diff --git a/Tools/c.py b/waflib/Tools/c.py
index effd6b6..effd6b6 100644
--- a/Tools/c.py
+++ b/waflib/Tools/c.py
diff --git a/Tools/c_aliases.py b/waflib/Tools/c_aliases.py
index c9d5369..c9d5369 100644
--- a/Tools/c_aliases.py
+++ b/waflib/Tools/c_aliases.py
diff --git a/Tools/c_config.py b/waflib/Tools/c_config.py
index d2b3c0d..d2b3c0d 100644
--- a/Tools/c_config.py
+++ b/waflib/Tools/c_config.py
diff --git a/Tools/c_osx.py b/waflib/Tools/c_osx.py
index f70b128..f70b128 100644
--- a/Tools/c_osx.py
+++ b/waflib/Tools/c_osx.py
diff --git a/Tools/c_preproc.py b/waflib/Tools/c_preproc.py
index 7e04b4a..7e04b4a 100644
--- a/Tools/c_preproc.py
+++ b/waflib/Tools/c_preproc.py
diff --git a/Tools/c_tests.py b/waflib/Tools/c_tests.py
index f858df5..f858df5 100644
--- a/Tools/c_tests.py
+++ b/waflib/Tools/c_tests.py
diff --git a/Tools/ccroot.py b/waflib/Tools/ccroot.py
index cfef8bf..cfef8bf 100644
--- a/Tools/ccroot.py
+++ b/waflib/Tools/ccroot.py
diff --git a/Tools/clang.py b/waflib/Tools/clang.py
index 3828e39..3828e39 100644
--- a/Tools/clang.py
+++ b/waflib/Tools/clang.py
diff --git a/Tools/clangxx.py b/waflib/Tools/clangxx.py
index 152013c..152013c 100644
--- a/Tools/clangxx.py
+++ b/waflib/Tools/clangxx.py
diff --git a/Tools/compiler_c.py b/waflib/Tools/compiler_c.py
index 2dba3f8..2dba3f8 100644
--- a/Tools/compiler_c.py
+++ b/waflib/Tools/compiler_c.py
diff --git a/Tools/compiler_cxx.py b/waflib/Tools/compiler_cxx.py
index 1af65a2..1af65a2 100644
--- a/Tools/compiler_cxx.py
+++ b/waflib/Tools/compiler_cxx.py
diff --git a/Tools/compiler_d.py b/waflib/Tools/compiler_d.py
index 43bb1f6..43bb1f6 100644
--- a/Tools/compiler_d.py
+++ b/waflib/Tools/compiler_d.py
diff --git a/Tools/compiler_fc.py b/waflib/Tools/compiler_fc.py
index 96b58e7..96b58e7 100644
--- a/Tools/compiler_fc.py
+++ b/waflib/Tools/compiler_fc.py
diff --git a/Tools/cs.py b/waflib/Tools/cs.py
index aecca6d..aecca6d 100644
--- a/Tools/cs.py
+++ b/waflib/Tools/cs.py
diff --git a/Tools/cxx.py b/waflib/Tools/cxx.py
index 194fad7..194fad7 100644
--- a/Tools/cxx.py
+++ b/waflib/Tools/cxx.py
diff --git a/Tools/d.py b/waflib/Tools/d.py
index e4cf73b..e4cf73b 100644
--- a/Tools/d.py
+++ b/waflib/Tools/d.py
diff --git a/Tools/d_config.py b/waflib/Tools/d_config.py
index 6637556..6637556 100644
--- a/Tools/d_config.py
+++ b/waflib/Tools/d_config.py
diff --git a/Tools/d_scan.py b/waflib/Tools/d_scan.py
index 14c6c31..14c6c31 100644
--- a/Tools/d_scan.py
+++ b/waflib/Tools/d_scan.py
diff --git a/Tools/dbus.py b/waflib/Tools/dbus.py
index d520f1c..d520f1c 100644
--- a/Tools/dbus.py
+++ b/waflib/Tools/dbus.py
diff --git a/Tools/dmd.py b/waflib/Tools/dmd.py
index 8917ca1..8917ca1 100644
--- a/Tools/dmd.py
+++ b/waflib/Tools/dmd.py
diff --git a/Tools/errcheck.py b/waflib/Tools/errcheck.py
index de8d75a..de8d75a 100644
--- a/Tools/errcheck.py
+++ b/waflib/Tools/errcheck.py
diff --git a/Tools/fc.py b/waflib/Tools/fc.py
index d9e8d8c..d9e8d8c 100644
--- a/Tools/fc.py
+++ b/waflib/Tools/fc.py
diff --git a/Tools/fc_config.py b/waflib/Tools/fc_config.py
index 222f3a5..222f3a5 100644
--- a/Tools/fc_config.py
+++ b/waflib/Tools/fc_config.py
diff --git a/Tools/fc_scan.py b/waflib/Tools/fc_scan.py
index 12cb0fc..12cb0fc 100644
--- a/Tools/fc_scan.py
+++ b/waflib/Tools/fc_scan.py
diff --git a/Tools/flex.py b/waflib/Tools/flex.py
index 2256657..2256657 100644
--- a/Tools/flex.py
+++ b/waflib/Tools/flex.py
diff --git a/Tools/g95.py b/waflib/Tools/g95.py
index f69ba4f..f69ba4f 100644
--- a/Tools/g95.py
+++ b/waflib/Tools/g95.py
diff --git a/Tools/gas.py b/waflib/Tools/gas.py
index 77afed7..77afed7 100644
--- a/Tools/gas.py
+++ b/waflib/Tools/gas.py
diff --git a/Tools/gcc.py b/waflib/Tools/gcc.py
index acdd473..acdd473 100644
--- a/Tools/gcc.py
+++ b/waflib/Tools/gcc.py
diff --git a/Tools/gdc.py b/waflib/Tools/gdc.py
index d89a66d..d89a66d 100644
--- a/Tools/gdc.py
+++ b/waflib/Tools/gdc.py
diff --git a/Tools/gfortran.py b/waflib/Tools/gfortran.py
index 1050667..1050667 100644
--- a/Tools/gfortran.py
+++ b/waflib/Tools/gfortran.py
diff --git a/Tools/glib2.py b/waflib/Tools/glib2.py
index 949fe37..949fe37 100644
--- a/Tools/glib2.py
+++ b/waflib/Tools/glib2.py
diff --git a/Tools/gnu_dirs.py b/waflib/Tools/gnu_dirs.py
index 2847071..2847071 100644
--- a/Tools/gnu_dirs.py
+++ b/waflib/Tools/gnu_dirs.py
diff --git a/Tools/gxx.py b/waflib/Tools/gxx.py
index 22c5d26..22c5d26 100644
--- a/Tools/gxx.py
+++ b/waflib/Tools/gxx.py
diff --git a/Tools/icc.py b/waflib/Tools/icc.py
index b6492c8..b6492c8 100644
--- a/Tools/icc.py
+++ b/waflib/Tools/icc.py
diff --git a/Tools/icpc.py b/waflib/Tools/icpc.py
index 8a6cc6c..8a6cc6c 100644
--- a/Tools/icpc.py
+++ b/waflib/Tools/icpc.py
diff --git a/Tools/ifort.py b/waflib/Tools/ifort.py
index 74934f3..74934f3 100644
--- a/Tools/ifort.py
+++ b/waflib/Tools/ifort.py
diff --git a/Tools/intltool.py b/waflib/Tools/intltool.py
index af95ba8..af95ba8 100644
--- a/Tools/intltool.py
+++ b/waflib/Tools/intltool.py
diff --git a/Tools/irixcc.py b/waflib/Tools/irixcc.py
index c3ae1ac..c3ae1ac 100644
--- a/Tools/irixcc.py
+++ b/waflib/Tools/irixcc.py
diff --git a/Tools/javaw.py b/waflib/Tools/javaw.py
index f6fd20c..f6fd20c 100644
--- a/Tools/javaw.py
+++ b/waflib/Tools/javaw.py
diff --git a/Tools/ldc2.py b/waflib/Tools/ldc2.py
index a51c344..a51c344 100644
--- a/Tools/ldc2.py
+++ b/waflib/Tools/ldc2.py
diff --git a/Tools/lua.py b/waflib/Tools/lua.py
index 15a333a..15a333a 100644
--- a/Tools/lua.py
+++ b/waflib/Tools/lua.py
diff --git a/Tools/md5_tstamp.py b/waflib/Tools/md5_tstamp.py
index 6428e46..6428e46 100644
--- a/Tools/md5_tstamp.py
+++ b/waflib/Tools/md5_tstamp.py
diff --git a/Tools/msvc.py b/waflib/Tools/msvc.py
index 17b347d..17b347d 100644
--- a/Tools/msvc.py
+++ b/waflib/Tools/msvc.py
diff --git a/Tools/nasm.py b/waflib/Tools/nasm.py
index 411d582..411d582 100644
--- a/Tools/nasm.py
+++ b/waflib/Tools/nasm.py
diff --git a/Tools/nobuild.py b/waflib/Tools/nobuild.py
index 2e4b055..2e4b055 100644
--- a/Tools/nobuild.py
+++ b/waflib/Tools/nobuild.py
diff --git a/Tools/perl.py b/waflib/Tools/perl.py
index 32b03fb..32b03fb 100644
--- a/Tools/perl.py
+++ b/waflib/Tools/perl.py
diff --git a/Tools/python.py b/waflib/Tools/python.py
index 25841d0..25841d0 100644
--- a/Tools/python.py
+++ b/waflib/Tools/python.py
diff --git a/Tools/qt5.py b/waflib/Tools/qt5.py
index 4f9c690..4f9c690 100644
--- a/Tools/qt5.py
+++ b/waflib/Tools/qt5.py
diff --git a/Tools/ruby.py b/waflib/Tools/ruby.py
index 8d92a79..8d92a79 100644
--- a/Tools/ruby.py
+++ b/waflib/Tools/ruby.py
diff --git a/Tools/suncc.py b/waflib/Tools/suncc.py
index 33d34fc..33d34fc 100644
--- a/Tools/suncc.py
+++ b/waflib/Tools/suncc.py
diff --git a/Tools/suncxx.py b/waflib/Tools/suncxx.py
index 3b384f6..3b384f6 100644
--- a/Tools/suncxx.py
+++ b/waflib/Tools/suncxx.py
diff --git a/Tools/tex.py b/waflib/Tools/tex.py
index eaf9fdb..eaf9fdb 100644
--- a/Tools/tex.py
+++ b/waflib/Tools/tex.py
diff --git a/Tools/vala.py b/waflib/Tools/vala.py
index 822ec50..822ec50 100644
--- a/Tools/vala.py
+++ b/waflib/Tools/vala.py
diff --git a/Tools/waf_unit_test.py b/waflib/Tools/waf_unit_test.py
index a71ed1c..a71ed1c 100644
--- a/Tools/waf_unit_test.py
+++ b/waflib/Tools/waf_unit_test.py
diff --git a/Tools/winres.py b/waflib/Tools/winres.py
index 586c596..586c596 100644
--- a/Tools/winres.py
+++ b/waflib/Tools/winres.py
diff --git a/Tools/xlc.py b/waflib/Tools/xlc.py
index 134dd41..134dd41 100644
--- a/Tools/xlc.py
+++ b/waflib/Tools/xlc.py
diff --git a/Tools/xlcxx.py b/waflib/Tools/xlcxx.py
index 76aa59b..76aa59b 100644
--- a/Tools/xlcxx.py
+++ b/waflib/Tools/xlcxx.py
diff --git a/Utils.py b/waflib/Utils.py
index b4665c4..b4665c4 100644
--- a/Utils.py
+++ b/waflib/Utils.py
diff --git a/__init__.py b/waflib/__init__.py
index 079df35..079df35 100644
--- a/__init__.py
+++ b/waflib/__init__.py
diff --git a/ansiterm.py b/waflib/ansiterm.py
index 0d20c63..0d20c63 100644
--- a/ansiterm.py
+++ b/waflib/ansiterm.py
diff --git a/extras/__init__.py b/waflib/extras/__init__.py
index c8a3c34..c8a3c34 100644
--- a/extras/__init__.py
+++ b/waflib/extras/__init__.py
diff --git a/extras/autowaf.py b/waflib/extras/autowaf.py
index a4a06ba..a4a06ba 100644
--- a/extras/autowaf.py
+++ b/waflib/extras/autowaf.py
diff --git a/extras/batched_cc.py b/waflib/extras/batched_cc.py
index aad2872..aad2872 100644
--- a/extras/batched_cc.py
+++ b/waflib/extras/batched_cc.py
diff --git a/extras/biber.py b/waflib/extras/biber.py
index fd9db4e..fd9db4e 100644
--- a/extras/biber.py
+++ b/waflib/extras/biber.py
diff --git a/extras/bjam.py b/waflib/extras/bjam.py
index 8e04d3a..8e04d3a 100644
--- a/extras/bjam.py
+++ b/waflib/extras/bjam.py
diff --git a/extras/blender.py b/waflib/extras/blender.py
index e5efc28..e5efc28 100644
--- a/extras/blender.py
+++ b/waflib/extras/blender.py
diff --git a/extras/boo.py b/waflib/extras/boo.py
index 06623d4..06623d4 100644
--- a/extras/boo.py
+++ b/waflib/extras/boo.py
diff --git a/extras/boost.py b/waflib/extras/boost.py
index c2aaaa9..c2aaaa9 100644
--- a/extras/boost.py
+++ b/waflib/extras/boost.py
diff --git a/extras/build_file_tracker.py b/waflib/extras/build_file_tracker.py
index c4f26fd..c4f26fd 100644
--- a/extras/build_file_tracker.py
+++ b/waflib/extras/build_file_tracker.py
diff --git a/extras/build_logs.py b/waflib/extras/build_logs.py
index cdf8ed0..cdf8ed0 100644
--- a/extras/build_logs.py
+++ b/waflib/extras/build_logs.py
diff --git a/extras/buildcopy.py b/waflib/extras/buildcopy.py
index a6d9ac8..a6d9ac8 100644
--- a/extras/buildcopy.py
+++ b/waflib/extras/buildcopy.py
diff --git a/extras/c_bgxlc.py b/waflib/extras/c_bgxlc.py
index 6e3eaf7..6e3eaf7 100644
--- a/extras/c_bgxlc.py
+++ b/waflib/extras/c_bgxlc.py
diff --git a/extras/c_dumbpreproc.py b/waflib/extras/c_dumbpreproc.py
index ce9e1a4..ce9e1a4 100644
--- a/extras/c_dumbpreproc.py
+++ b/waflib/extras/c_dumbpreproc.py
diff --git a/extras/c_emscripten.py b/waflib/extras/c_emscripten.py
index e1ac494..e1ac494 100644
--- a/extras/c_emscripten.py
+++ b/waflib/extras/c_emscripten.py
diff --git a/extras/c_nec.py b/waflib/extras/c_nec.py
index 96bfae4..96bfae4 100644
--- a/extras/c_nec.py
+++ b/waflib/extras/c_nec.py
diff --git a/extras/cabal.py b/waflib/extras/cabal.py
index e10a0d1..e10a0d1 100644
--- a/extras/cabal.py
+++ b/waflib/extras/cabal.py
diff --git a/extras/cfg_altoptions.py b/waflib/extras/cfg_altoptions.py
index 47b1189..47b1189 100644
--- a/extras/cfg_altoptions.py
+++ b/waflib/extras/cfg_altoptions.py
diff --git a/extras/clang_compilation_database.py b/waflib/extras/clang_compilation_database.py
index 4d9b5e2..4d9b5e2 100644
--- a/extras/clang_compilation_database.py
+++ b/waflib/extras/clang_compilation_database.py
diff --git a/extras/codelite.py b/waflib/extras/codelite.py
index 523302c..523302c 100644
--- a/extras/codelite.py
+++ b/waflib/extras/codelite.py
diff --git a/extras/color_gcc.py b/waflib/extras/color_gcc.py
index b68c5eb..b68c5eb 100644
--- a/extras/color_gcc.py
+++ b/waflib/extras/color_gcc.py
diff --git a/extras/color_rvct.py b/waflib/extras/color_rvct.py
index f89ccbd..f89ccbd 100644
--- a/extras/color_rvct.py
+++ b/waflib/extras/color_rvct.py
diff --git a/extras/compat15.py b/waflib/extras/compat15.py
index 0e74df8..0e74df8 100644
--- a/extras/compat15.py
+++ b/waflib/extras/compat15.py
diff --git a/extras/cppcheck.py b/waflib/extras/cppcheck.py
index 13ff424..13ff424 100644
--- a/extras/cppcheck.py
+++ b/waflib/extras/cppcheck.py
diff --git a/extras/cpplint.py b/waflib/extras/cpplint.py
index e3302e5..e3302e5 100644
--- a/extras/cpplint.py
+++ b/waflib/extras/cpplint.py
diff --git a/extras/cross_gnu.py b/waflib/extras/cross_gnu.py
index 309f53b..309f53b 100644
--- a/extras/cross_gnu.py
+++ b/waflib/extras/cross_gnu.py
diff --git a/extras/cython.py b/waflib/extras/cython.py
index 481d6f4..481d6f4 100644
--- a/extras/cython.py
+++ b/waflib/extras/cython.py
diff --git a/extras/dcc.py b/waflib/extras/dcc.py
index c1a57c0..c1a57c0 100644
--- a/extras/dcc.py
+++ b/waflib/extras/dcc.py
diff --git a/extras/distnet.py b/waflib/extras/distnet.py
index 09a31a6..09a31a6 100644
--- a/extras/distnet.py
+++ b/waflib/extras/distnet.py
diff --git a/extras/doxygen.py b/waflib/extras/doxygen.py
index 28f56e9..28f56e9 100644
--- a/extras/doxygen.py
+++ b/waflib/extras/doxygen.py
diff --git a/extras/dpapi.py b/waflib/extras/dpapi.py
index b94d482..b94d482 100644
--- a/extras/dpapi.py
+++ b/waflib/extras/dpapi.py
diff --git a/extras/eclipse.py b/waflib/extras/eclipse.py
index bb78741..bb78741 100644
--- a/extras/eclipse.py
+++ b/waflib/extras/eclipse.py
diff --git a/extras/erlang.py b/waflib/extras/erlang.py
index 49f6d5b..49f6d5b 100644
--- a/extras/erlang.py
+++ b/waflib/extras/erlang.py
diff --git a/extras/fast_partial.py b/waflib/extras/fast_partial.py
index b3af513..b3af513 100644
--- a/extras/fast_partial.py
+++ b/waflib/extras/fast_partial.py
diff --git a/extras/fc_bgxlf.py b/waflib/extras/fc_bgxlf.py
index cca1810..cca1810 100644
--- a/extras/fc_bgxlf.py
+++ b/waflib/extras/fc_bgxlf.py
diff --git a/extras/fc_cray.py b/waflib/extras/fc_cray.py
index da733fa..da733fa 100644
--- a/extras/fc_cray.py
+++ b/waflib/extras/fc_cray.py
diff --git a/extras/fc_nag.py b/waflib/extras/fc_nag.py
index edcb218..edcb218 100644
--- a/extras/fc_nag.py
+++ b/waflib/extras/fc_nag.py
diff --git a/extras/fc_nec.py b/waflib/extras/fc_nec.py
index 67c8680..67c8680 100644
--- a/extras/fc_nec.py
+++ b/waflib/extras/fc_nec.py
diff --git a/extras/fc_open64.py b/waflib/extras/fc_open64.py
index 413719f..413719f 100644
--- a/extras/fc_open64.py
+++ b/waflib/extras/fc_open64.py
diff --git a/extras/fc_pgfortran.py b/waflib/extras/fc_pgfortran.py
index afb2817..afb2817 100644
--- a/extras/fc_pgfortran.py
+++ b/waflib/extras/fc_pgfortran.py
diff --git a/extras/fc_solstudio.py b/waflib/extras/fc_solstudio.py
index 53766df..53766df 100644
--- a/extras/fc_solstudio.py
+++ b/waflib/extras/fc_solstudio.py
diff --git a/extras/fc_xlf.py b/waflib/extras/fc_xlf.py
index 5a3da03..5a3da03 100644
--- a/extras/fc_xlf.py
+++ b/waflib/extras/fc_xlf.py
diff --git a/extras/file_to_object.py b/waflib/extras/file_to_object.py
index 1393b51..1393b51 100644
--- a/extras/file_to_object.py
+++ b/waflib/extras/file_to_object.py
diff --git a/extras/fluid.py b/waflib/extras/fluid.py
index 4814a35..4814a35 100644
--- a/extras/fluid.py
+++ b/waflib/extras/fluid.py
diff --git a/extras/freeimage.py b/waflib/extras/freeimage.py
index f27e525..f27e525 100644
--- a/extras/freeimage.py
+++ b/waflib/extras/freeimage.py
diff --git a/extras/fsb.py b/waflib/extras/fsb.py
index 1b8f398..1b8f398 100644
--- a/extras/fsb.py
+++ b/waflib/extras/fsb.py
diff --git a/extras/fsc.py b/waflib/extras/fsc.py
index c67e70b..c67e70b 100644
--- a/extras/fsc.py
+++ b/waflib/extras/fsc.py
diff --git a/extras/gccdeps.py b/waflib/extras/gccdeps.py
index d9758ab..d9758ab 100644
--- a/extras/gccdeps.py
+++ b/waflib/extras/gccdeps.py
diff --git a/extras/gdbus.py b/waflib/extras/gdbus.py
index 0e0476e..0e0476e 100644
--- a/extras/gdbus.py
+++ b/waflib/extras/gdbus.py
diff --git a/extras/gob2.py b/waflib/extras/gob2.py
index b4fa3b9..b4fa3b9 100644
--- a/extras/gob2.py
+++ b/waflib/extras/gob2.py
diff --git a/extras/halide.py b/waflib/extras/halide.py
index 6078e38..6078e38 100644
--- a/extras/halide.py
+++ b/waflib/extras/halide.py
diff --git a/extras/javatest.py b/waflib/extras/javatest.py
index 979b8d8..979b8d8 100755
--- a/extras/javatest.py
+++ b/waflib/extras/javatest.py
diff --git a/extras/kde4.py b/waflib/extras/kde4.py
index e49a9ec..e49a9ec 100644
--- a/extras/kde4.py
+++ b/waflib/extras/kde4.py
diff --git a/extras/local_rpath.py b/waflib/extras/local_rpath.py
index b2507e1..b2507e1 100644
--- a/extras/local_rpath.py
+++ b/waflib/extras/local_rpath.py
diff --git a/extras/lv2.py b/waflib/extras/lv2.py
index 815987f..815987f 100644
--- a/extras/lv2.py
+++ b/waflib/extras/lv2.py
diff --git a/extras/make.py b/waflib/extras/make.py
index 933d9ca..933d9ca 100644
--- a/extras/make.py
+++ b/waflib/extras/make.py
diff --git a/extras/midl.py b/waflib/extras/midl.py
index 43e6cf9..43e6cf9 100644
--- a/extras/midl.py
+++ b/waflib/extras/midl.py
diff --git a/extras/msvcdeps.py b/waflib/extras/msvcdeps.py
index fc1ecd4..fc1ecd4 100644
--- a/extras/msvcdeps.py
+++ b/waflib/extras/msvcdeps.py
diff --git a/extras/msvs.py b/waflib/extras/msvs.py
index 8aa2db0..8aa2db0 100644
--- a/extras/msvs.py
+++ b/waflib/extras/msvs.py
diff --git a/extras/netcache_client.py b/waflib/extras/netcache_client.py
index dc49048..dc49048 100644
--- a/extras/netcache_client.py
+++ b/waflib/extras/netcache_client.py
diff --git a/extras/objcopy.py b/waflib/extras/objcopy.py
index 82d8359..82d8359 100644
--- a/extras/objcopy.py
+++ b/waflib/extras/objcopy.py
diff --git a/extras/ocaml.py b/waflib/extras/ocaml.py
index afe73c0..afe73c0 100644
--- a/extras/ocaml.py
+++ b/waflib/extras/ocaml.py
diff --git a/extras/package.py b/waflib/extras/package.py
index c06498e..c06498e 100644
--- a/extras/package.py
+++ b/waflib/extras/package.py
diff --git a/extras/parallel_debug.py b/waflib/extras/parallel_debug.py
index 35883a3..35883a3 100644
--- a/extras/parallel_debug.py
+++ b/waflib/extras/parallel_debug.py
diff --git a/extras/pch.py b/waflib/extras/pch.py
index 103e752..103e752 100644
--- a/extras/pch.py
+++ b/waflib/extras/pch.py
diff --git a/extras/pep8.py b/waflib/extras/pep8.py
index 676beed..676beed 100644
--- a/extras/pep8.py
+++ b/waflib/extras/pep8.py
diff --git a/extras/pgicc.py b/waflib/extras/pgicc.py
index 9790b9c..9790b9c 100644
--- a/extras/pgicc.py
+++ b/waflib/extras/pgicc.py
diff --git a/extras/pgicxx.py b/waflib/extras/pgicxx.py
index eae121c..eae121c 100644
--- a/extras/pgicxx.py
+++ b/waflib/extras/pgicxx.py
diff --git a/extras/proc.py b/waflib/extras/proc.py
index 764abec..764abec 100644
--- a/extras/proc.py
+++ b/waflib/extras/proc.py
diff --git a/extras/protoc.py b/waflib/extras/protoc.py
index f3cb4d8..f3cb4d8 100644
--- a/extras/protoc.py
+++ b/waflib/extras/protoc.py
diff --git a/extras/pyqt5.py b/waflib/extras/pyqt5.py
index c21dfa7..c21dfa7 100644
--- a/extras/pyqt5.py
+++ b/waflib/extras/pyqt5.py
diff --git a/extras/pytest.py b/waflib/extras/pytest.py
index 7dd5a1a..7dd5a1a 100644
--- a/extras/pytest.py
+++ b/waflib/extras/pytest.py
diff --git a/extras/qnxnto.py b/waflib/extras/qnxnto.py
index 1158124..1158124 100644
--- a/extras/qnxnto.py
+++ b/waflib/extras/qnxnto.py
diff --git a/extras/qt4.py b/waflib/extras/qt4.py
index 90cae7e..90cae7e 100644
--- a/extras/qt4.py
+++ b/waflib/extras/qt4.py
diff --git a/extras/relocation.py b/waflib/extras/relocation.py
index 7e821f4..7e821f4 100644
--- a/extras/relocation.py
+++ b/waflib/extras/relocation.py
diff --git a/extras/remote.py b/waflib/extras/remote.py
index 3b038f7..3b038f7 100644
--- a/extras/remote.py
+++ b/waflib/extras/remote.py
diff --git a/extras/resx.py b/waflib/extras/resx.py
index caf4d31..caf4d31 100644
--- a/extras/resx.py
+++ b/waflib/extras/resx.py
diff --git a/extras/review.py b/waflib/extras/review.py
index 561e062..561e062 100644
--- a/extras/review.py
+++ b/waflib/extras/review.py
diff --git a/extras/rst.py b/waflib/extras/rst.py
index f3c3a5e..f3c3a5e 100644
--- a/extras/rst.py
+++ b/waflib/extras/rst.py
diff --git a/extras/run_do_script.py b/waflib/extras/run_do_script.py
index f3c5812..f3c5812 100644
--- a/extras/run_do_script.py
+++ b/waflib/extras/run_do_script.py
diff --git a/extras/run_m_script.py b/waflib/extras/run_m_script.py
index b5f27eb..b5f27eb 100644
--- a/extras/run_m_script.py
+++ b/waflib/extras/run_m_script.py
diff --git a/extras/run_py_script.py b/waflib/extras/run_py_script.py
index 3670381..3670381 100644
--- a/extras/run_py_script.py
+++ b/waflib/extras/run_py_script.py
diff --git a/extras/run_r_script.py b/waflib/extras/run_r_script.py
index b0d8f2b..b0d8f2b 100644
--- a/extras/run_r_script.py
+++ b/waflib/extras/run_r_script.py
diff --git a/extras/sas.py b/waflib/extras/sas.py
index 754c614..754c614 100644
--- a/extras/sas.py
+++ b/waflib/extras/sas.py
diff --git a/extras/satellite_assembly.py b/waflib/extras/satellite_assembly.py
index 005eb07..005eb07 100644
--- a/extras/satellite_assembly.py
+++ b/waflib/extras/satellite_assembly.py
diff --git a/extras/scala.py b/waflib/extras/scala.py
index a9880f0..a9880f0 100644
--- a/extras/scala.py
+++ b/waflib/extras/scala.py
diff --git a/extras/slow_qt4.py b/waflib/extras/slow_qt4.py
index ec7880b..ec7880b 100644
--- a/extras/slow_qt4.py
+++ b/waflib/extras/slow_qt4.py
diff --git a/extras/softlink_libs.py b/waflib/extras/softlink_libs.py
index 50c777f..50c777f 100644
--- a/extras/softlink_libs.py
+++ b/waflib/extras/softlink_libs.py
diff --git a/extras/stale.py b/waflib/extras/stale.py
index cac3f46..cac3f46 100644
--- a/extras/stale.py
+++ b/waflib/extras/stale.py
diff --git a/extras/stracedeps.py b/waflib/extras/stracedeps.py
index 37d82cb..37d82cb 100644
--- a/extras/stracedeps.py
+++ b/waflib/extras/stracedeps.py
diff --git a/extras/swig.py b/waflib/extras/swig.py
index fd3d6d2..fd3d6d2 100644
--- a/extras/swig.py
+++ b/waflib/extras/swig.py
diff --git a/extras/syms.py b/waflib/extras/syms.py
index dfa0059..dfa0059 100644
--- a/extras/syms.py
+++ b/waflib/extras/syms.py
diff --git a/extras/ticgt.py b/waflib/extras/ticgt.py
index f43a7ea..f43a7ea 100644
--- a/extras/ticgt.py
+++ b/waflib/extras/ticgt.py
diff --git a/extras/unity.py b/waflib/extras/unity.py
index 78128ed..78128ed 100644
--- a/extras/unity.py
+++ b/waflib/extras/unity.py
diff --git a/extras/use_config.py b/waflib/extras/use_config.py
index ef5129f..ef5129f 100644
--- a/extras/use_config.py
+++ b/waflib/extras/use_config.py
diff --git a/extras/valadoc.py b/waflib/extras/valadoc.py
index c50f69e..c50f69e 100644
--- a/extras/valadoc.py
+++ b/waflib/extras/valadoc.py
diff --git a/extras/waf_xattr.py b/waflib/extras/waf_xattr.py
index 351dd63..351dd63 100644
--- a/extras/waf_xattr.py
+++ b/waflib/extras/waf_xattr.py
diff --git a/extras/why.py b/waflib/extras/why.py
index 1bb941f..1bb941f 100644
--- a/extras/why.py
+++ b/waflib/extras/why.py
diff --git a/extras/win32_opts.py b/waflib/extras/win32_opts.py
index 9f7443c..9f7443c 100644
--- a/extras/win32_opts.py
+++ b/waflib/extras/win32_opts.py
diff --git a/extras/wix.py b/waflib/extras/wix.py
index d87bfbb..d87bfbb 100644
--- a/extras/wix.py
+++ b/waflib/extras/wix.py
diff --git a/extras/xcode6.py b/waflib/extras/xcode6.py
index 91bbff1..91bbff1 100644
--- a/extras/xcode6.py
+++ b/waflib/extras/xcode6.py
diff --git a/fixpy2.py b/waflib/fixpy2.py
index 24176e0..24176e0 100644
--- a/fixpy2.py
+++ b/waflib/fixpy2.py
diff --git a/processor.py b/waflib/processor.py
index 2eecf3b..2eecf3b 100755
--- a/processor.py
+++ b/waflib/processor.py
diff --git a/waflib/waf b/waflib/waf
new file mode 100755
index 0000000..e22930a
--- /dev/null
+++ b/waflib/waf
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+
+# Minimal waf script for projects that include waflib directly
+
+from waflib import Context, Scripting
+
+import inspect
+import os
+
+def main():
+ script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main)))
+ project_path = os.path.dirname(script_path)
+ Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path)
+
+if __name__ == '__main__':
+ main()
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..05895ff
--- /dev/null
+++ b/wscript
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+import os
+import shutil
+import subprocess
+import waflib.Options as Options
+import waflib.extras.autowaf as autowaf
+
+BLOP_VERSION = '1.0.1'
+
+# Mandatory waf variables
+APPNAME = 'blop-lv2' # Package name for waf dist
+VERSION = BLOP_VERSION # Package version for waf dist
+top = '.' # Source directory
+out = 'build' # Build directory
+
+def options(ctx):
+ ctx.load('compiler_c')
+ ctx.load('lv2')
+ autowaf.set_options(ctx)
+ opt = ctx.get_option_group('Configuration options')
+ opt.add_option('--rate', type='int', default=48000,
+ dest='rate',
+ help='ideal sample rate for oscillator wave tables [Default: 48000]')
+
+def configure(conf):
+ autowaf.display_header('Blop.LV2 Configuration')
+ conf.load('compiler_c', cache=True)
+ conf.load('lv2', cache=True)
+ conf.load('autowaf', cache=True)
+ autowaf.set_c_lang(conf, 'c99')
+
+ autowaf.check_pkg(conf, 'lv2', atleast_version='1.2.0', uselib_store='LV2')
+
+ autowaf.check_function(conf, 'c', 'sinf',
+ header_name = 'math.h',
+ lib = 'm',
+ define_name = 'HAVE_SINF',
+ mandatory = False)
+
+ conf.check_cc(define_name = 'HAVE_LIBDL',
+ lib = 'dl',
+ mandatory = False)
+
+ autowaf.check_function(conf, 'c', 'getopt_long',
+ header_name = 'getopt.h')
+
+
+ conf.write_config_header('blop_config.h', remove=False)
+
+ # Set env.pluginlib_PATTERN
+ pat = conf.env.cshlib_PATTERN
+ if pat[0:3] == 'lib':
+ pat = pat[3:]
+ conf.env.pluginlib_PATTERN = pat
+ conf.env.pluginlib_EXT = pat[pat.rfind('.'):]
+
+ conf.define('BLOP_SHLIB_EXT', conf.env.pluginlib_EXT)
+
+ autowaf.display_summary(conf)
+ autowaf.display_msg(conf, 'LV2 bundle directory', conf.env.LV2DIR)
+ autowaf.display_msg(conf, 'Ideal sampling rate',
+ Options.options.rate)
+ print('')
+
+def build_plugin(bld, lang, bundle, name, source, defines=None, lib=[]):
+ # Build plugin library
+ penv = bld.env.derive()
+ penv.cshlib_PATTERN = bld.env.pluginlib_PATTERN
+ obj = bld(features = '%s %sshlib' % (lang,lang),
+ env = penv,
+ source = source,
+ includes = ['.', 'src/include'],
+ name = name,
+ target = os.path.join(bundle, name),
+ uselib = ['LV2'],
+ lib = ['m'] + lib,
+ install_path = '${LV2DIR}/' + bundle)
+ if defines != None:
+ obj.defines = defines
+
+ # Install data file
+ data_file = '%s.ttl' % name
+ bld.install_files('${LV2DIR}/' + bundle, os.path.join(bundle, data_file))
+
+def build(bld):
+ for i in bld.path.ant_glob('blop.lv2/*.ttl'):
+ bld(features = 'subst',
+ is_copy = True,
+ source = i,
+ target = 'blop.lv2/%s' % i.name,
+ install_path = '${LV2DIR}/blop.lv2')
+
+ bld(features = 'subst',
+ source = 'blop.lv2/manifest.ttl.in',
+ target = 'blop.lv2/manifest.ttl',
+ LIB_EXT = bld.env.pluginlib_EXT,
+ install_path = '${LV2DIR}/blop.lv2')
+
+ plugins = '''
+ adsr
+ adsr_gt
+ amp
+ branch
+ dahdsr
+ difference
+ fmod
+ interpolator
+ product
+ random
+ ratio
+ sum
+ sync_pulse
+ sync_square
+ tracker
+ '''.split()
+
+ # Simple (single source file) plugins
+ for i in plugins:
+ build_plugin(bld, 'c', 'blop.lv2', i,
+ ['src/%s.c' % i])
+
+ # Low pass filter
+ build_plugin(bld, 'c', 'blop.lv2', 'lp4pole',
+ ['src/lp4pole.c', 'src/lp4pole_filter.c'])
+
+ # Oscillators
+ for i in ['pulse', 'sawtooth', 'square', 'triangle']:
+ lib = []
+ if bld.is_defined('HAVE_LIBDL'):
+ lib += ['dl']
+ build_plugin(bld, 'c', 'blop.lv2', i,
+ ['src/%s.c' % i, 'src/wavedata.c'],
+ lib=lib)
+
+ # Sequencers
+ for i in [16, 32, 64]:
+ uri = 'http://drobilla.net/plugins/blop/sequencer_%d' % i
+ build_plugin(bld, 'c', 'blop.lv2', 'sequencer_%d' % i,
+ ['src/sequencer.c'],
+ defines=['SEQUENCER_MAX_INPUTS=%d' % i,
+ 'SEQUENCER_URI="%s"' % uri])
+
+ # Quantisers
+ for i in [20, 50, 100]:
+ uri = 'http://drobilla.net/plugins/blop/quantiser_%d' % i
+ build_plugin(bld, 'c', 'blop.lv2', 'quantiser_%d' % i,
+ ['src/quantiser.c'],
+ defines=['QUANTISER_MAX_INPUTS=%d' % i,
+ 'QUANTISER_URI="%s"' % uri])
+
+ # Wavegen
+ wavegen = bld(features = 'c cprogram',
+ source = ['src/wavegen.c', 'src/wdatutil.c'],
+ target = 'src/wavegen',
+ name = 'wavegen',
+ includes = ['.', 'src/include'],
+ lib = ['m'],
+ install_path = None)
+
+ wavegen.post()
+
+ # Waveform data source
+ for i in ['parabola', 'sawtooth', 'square']:
+ bld(rule = '${SRC} -r %d -f 12 -s 1 -m 128 -g 1.0 -w %s -p %s -o ${TGT}' % (
+ Options.options.rate, i, i),
+ source = wavegen.link_task.outputs[0],
+ target = 'src/%s_data.c' % i,
+ name = i)
+
+ penv = bld.env.derive()
+ penv.cshlib_PATTERN = bld.env.pluginlib_PATTERN
+
+ bld(features = 'c cshlib',
+ source = bld.path.get_bld().make_node('src/%s_data.c' % i),
+ target = 'blop.lv2/%s_data' % i,
+ includes = ['.', 'src/include'],
+ env = penv,
+ install_path = '${LV2DIR}/blop.lv2',
+ uselib = ['LV2'])
+
+def lint(ctx):
+ subprocess.call('cpplint.py --filter=+whitespace/comments,-whitespace/tab,-whitespace/braces,-whitespace/labels,-build/header_guard,-readability/casting,-readability/todo,-build/include src/* serd/*', shell=True)
+
+def posts(ctx):
+ path = str(ctx.path.abspath())
+ autowaf.news_to_posts(
+ os.path.join(path, 'NEWS'),
+ {'title' : 'BLOP.LV2',
+ 'description' : autowaf.get_blurb(os.path.join(path, 'README')),
+ 'dist_pattern' : 'http://download.drobilla.net/blop-lv2-%s.tar.bz2'},
+ { 'Author' : 'drobilla',
+ 'Tags' : 'LV2, Blop.lv2' },
+ os.path.join(out, 'posts'))