cl-sql-6.7.2/0000755000175000017500000000000014327126007011735 5ustar kevinkevincl-sql-6.7.2/clsql-oracle.asd0000644000175000017500000000321011332141035014772 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-oracle.asd ;;;; Purpose: ASDF definition file for CLSQL Oracle backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-oracle-system (:use #:asdf #:cl)) (in-package #:clsql-oracle-system) ;;; System definition (defsystem clsql-oracle :name "clsql-oracle" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL Oracle Driver" :long-description "cl-sql-oracle package provides a database driver to the Oracle database system." :depends-on (clsql-uffi) :components ((:module :db-oracle :components ((:file "oracle-package") (:file "oracle-loader" :depends-on ("oracle-package")) (:file "foreign-resources" :depends-on ("oracle-package")) (:file "oracle-constants" :depends-on ("oracle-package")) (:file "oracle-api" :depends-on ("oracle-constants" "oracle-loader")) (:file "oracle-sql" :depends-on ("oracle-api" "foreign-resources")) (:file "oracle-objects" :depends-on ("oracle-sql")))))) cl-sql-6.7.2/notes/0000755000175000017500000000000010667176647013107 5ustar kevinkevincl-sql-6.7.2/notes/add-type-hints.txt0000644000175000017500000000170510667176647016505 0ustar kevinkevinHow to Add a Type to CL-SQL (Alan Shields - Alan-Shields@omrf.ouhsc.edu) I made this small guide to eliminate some of the work I went through. I hope it is useful and/or correct. To add a type to CL-SQL, the following methods need to be declared. "sql/expressions.lisp" (defmethod database-output-sql (self database)) SELF is specialized for the lisp type, such as (self integer). "sql/oodml.lisp" (defmethod database-get-type-specifier (type args database db-type)) TYPE is a symbol for the clsql type, such as (type (eql 'integer)). Note that DB-TYPE is the database type, not DATABASE. "sql/oodml.lisp" (defmethod read-sql-value (val type database db-type)) TYPE is a symbol for the clsql type, as above. Same warnings as above. If your type is stored in different ways in different sql servers, you'll need to specialize these methods. These specializations usually go in either db-/-objects.lisp or sql/generic-.lisp. cl-sql-6.7.2/clsql-sqlite3.asd0000644000175000017500000000273312303270414015125 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-sqlite3.asd ;;;; Purpose: ASDF file for CLSQL SQLite3 backend ;;;; Programmer: Aurelio Bignoli ;;;; Date Started: Oct 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-sqlite3-system (:use #:asdf #:cl)) (in-package #:clsql-sqlite3-system) (defsystem clsql-sqlite3 :name "cl-sql-sqlite3" :author "Aurelio Bignoli " :maintainer "Aurelio Bignoli" :licence "Lessor Lisp General Public License" :description "Common Lisp Sqlite3 Driver" :long-description "cl-sql-sqlite3 package provides a database driver to SQLite Versione 3 database library." :depends-on (clsql clsql-uffi) :components ((:module :db-sqlite3 :components ((:file "sqlite3-package") (:file "sqlite3-loader" :depends-on ("sqlite3-package")) (:file "sqlite3-api" :depends-on ("sqlite3-loader")) (:file "sqlite3-sql" :depends-on ("sqlite3-api")) (:file "sqlite3-methods" :depends-on ("sqlite3-sql")))))) cl-sql-6.7.2/Makefile.common0000644000175000017500000000216312305406101014654 0ustar kevinkevinUNAME=$(shell uname) UNAME_A=$(shell uname -a) DARWIN_LIBC=$(shell file /usr/lib/libc.dylib) OS_AIX=$(shell expr "$(UNAME)" : '.*AIX.*') OS_SUNOS=$(shell expr "$(UNAME)" : '.*SunOS.*') OS_DARWIN=$(shell expr "$(UNAME)" : '.*Darwin.*') ifneq ($(OS_DARWIN),0) OS_DARWIN64=$(shell expr "$(DARWIN_LIBC)" : '.*x86_64.*') else OS_DARWIN64=0 endif OS_CYGWIN=$(shell expr "$(UNAME)" : '.*CYGWIN.*') OS_LINUX=$(shell expr "$(UNAME)" : '.*Linux.*') OS_LINUX64=$(shell expr "$(UNAME_A)" : '.*Linux.*x86_64.*') ifneq ("$(wildcard /usr/bin/dpkg-buildflags)","") DPKG_BUILDFLAGS=1 else DPKG_BUILDFLAGS=0 endif all: .PHONY: clean clean: @rm -rf .bin @rm -f *.ufsl *.fsl *.fas *.x86f *.sparcf *.fasl *.pfsl *.dfsl @rm -f *.fasla8 *.fasla16 *.faslm8 *.faslm16 *.faslmt @rm -f *~ *.bak *.orig *.err \#*\# .#* @rm -f *.so *.a @rm -rf debian/cl-sql ifneq ($(SUBDIRS)$(DOCSUBDIRS),) @set -e; for i in $(SUBDIRS) $(DOCSUBDIRS); do \ $(MAKE) -C $$i $@; done endif distclean: clean ifneq ($(SUBDIRS)$(DOCSUBDIRS),) @set -e; for i in $(SUBDIRS) $(DOCSUBDIRS); do \ $(MAKE) -C $$i $@; done endif .SUFFIXES: # No default suffixes cl-sql-6.7.2/db-sqlite/0000755000175000017500000000000014327126007013621 5ustar kevinkevincl-sql-6.7.2/db-sqlite/sqlite-sql.lisp0000644000175000017500000003361512473715066016631 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite-sql.lisp ;;;; Purpose: High-level SQLite interface ;;;; Authors: Aurelio Bignoli, Kevin Rosenberg, Marcus Pearce ;;;; Created: Aug 2003 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2003 by Aurelio Bignoli and ;;;; Copyright (c) 2003-2010 by Kevin Rosenberg and Marcus Pearce. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sqlite) (defclass sqlite-database (database) ((sqlite-db :initarg :sqlite-db :accessor sqlite-db))) (defmethod database-type ((database sqlite-database)) :sqlite) (defmethod database-initialize-database-type ((database-type (eql :sqlite))) t) (defun check-sqlite-connection-spec (connection-spec) (check-connection-spec connection-spec :sqlite (name))) (defmethod database-name-from-spec (connection-spec (database-type (eql :sqlite))) (check-sqlite-connection-spec connection-spec) (first connection-spec)) (defmethod database-connect (connection-spec (database-type (eql :sqlite))) (check-sqlite-connection-spec connection-spec) (handler-case (make-instance 'sqlite-database :name (database-name-from-spec connection-spec :sqlite) :database-type :sqlite :connection-spec connection-spec :sqlite-db (sqlite:sqlite-open (first connection-spec))) (sqlite:sqlite-error (err) (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id (sqlite:sqlite-error-code err) :message (sqlite:sqlite-error-message err))))) (defmethod database-disconnect ((database sqlite-database)) (sqlite:sqlite-close (sqlite-db database)) (setf (sqlite-db database) nil) t) (defmethod database-execute-command (sql-expression (database sqlite-database)) (handler-case (multiple-value-bind (data row-n col-n) (sqlite:sqlite-get-table (sqlite-db database) sql-expression) (sqlite:sqlite-free-table data) (unless (= row-n 0) (error 'sql-warning :format-control "Result set not empty: ~@(~A~) row~:P, ~@(~A~) column~:P " :format-arguments (list row-n col-n)))) (sqlite:sqlite-error (err) (error 'sql-database-data-error :database database :expression sql-expression :error-id (sqlite:sqlite-error-code err) :message (sqlite:sqlite-error-message err)))) t) (defstruct sqlite-result-set (vm (sqlite:make-null-vm) :type sqlite:sqlite-vm-pointer) (first-row (sqlite:make-null-row) :type sqlite:sqlite-row-pointer-type) (col-names (sqlite:make-null-row) :type sqlite:sqlite-row-pointer-type) (result-types nil) (n-col 0 :type fixnum)) (defmethod database-query (query-expression (database sqlite-database) result-types field-names) (declare (optimize (speed 3) (safety 0) (debug 0) (space 0))) (handler-case (let ((vm (sqlite:sqlite-compile (sqlite-db database) query-expression)) (rows '()) (col-names '())) (unwind-protect ;; Read the first row to get column number and names. (multiple-value-bind (n-col new-row sqlite-col-names) (sqlite:sqlite-step vm) (declare (type sqlite:sqlite-row-pointer-type new-row)) (when (> n-col 0) (when field-names (setf col-names (loop for i from 0 below n-col collect (sqlite:sqlite-aref sqlite-col-names i (encoding database))))) (let ((canonicalized-result-types (canonicalize-result-types result-types n-col sqlite-col-names database))) (flet ((extract-row-data (row) (declare (type sqlite:sqlite-row-pointer-type row)) (loop for i from 0 below n-col collect (clsql-uffi:convert-raw-field (sqlite:sqlite-raw-aref row i) (nth i canonicalized-result-types) :encoding (encoding database))))) (push (extract-row-data new-row) rows) ;; Read subsequent rows. (do () (nil) (multiple-value-bind (n-col new-row) (sqlite:sqlite-step vm) (declare (type sqlite:sqlite-row-pointer-type new-row)) (if (> n-col 0) (push (extract-row-data new-row) rows) (return)))))))) (sqlite:sqlite-finalize vm)) (values (nreverse rows) col-names)) (sqlite:sqlite-error (err) (error 'sql-database-data-error :database database :expression query-expression :error-id (sqlite:sqlite-error-code err) :message (sqlite:sqlite-error-message err))))) (defmethod database-query-result-set ((query-expression string) (database sqlite-database) &key result-types full-set) (let ((vm nil)) (handler-case (progn (setf vm (sqlite:sqlite-compile (sqlite-db database) query-expression)) ;;; To obtain column number/datatypes we have to read the first row. (multiple-value-bind (n-col cols col-names) (sqlite:sqlite-step vm) (declare (type sqlite:sqlite-row-pointer-type cols)) (let ((result-set (make-sqlite-result-set :vm vm :first-row cols :n-col n-col :col-names col-names :result-types (canonicalize-result-types result-types n-col col-names database)))) (if full-set (values result-set n-col nil) (values result-set n-col))))) (sqlite:sqlite-error (err) (progn (when vm ;; The condition was thrown by sqlite-step, vm must be ;; deallocated. (ignore-errors (sqlite:sqlite-finalize vm))) (error 'sql-database-data-error :database database :expression query-expression :error-id (sqlite:sqlite-error-code err) :message (sqlite:sqlite-error-message err))11))))) (defun canonicalize-result-types (result-types n-col col-names database) (when result-types (let ((raw-types (if (eq :auto result-types) (loop for j from n-col below (* 2 n-col) collect (ensure-keyword (sqlite:sqlite-aref col-names j (encoding database)))) result-types))) (loop for type in raw-types collect (case type ((:int :integer :tinyint) :int32) (:long #+(or x86-64 64bit) :int64 #-(or x86-64 64bit) :int32) (:bigint :int64) ((:float :double) :double) ((:numeric) :number) (otherwise :string)))))) (defmethod database-dump-result-set (result-set (database sqlite-database)) (handler-case (sqlite:sqlite-finalize (sqlite-result-set-vm result-set)) (sqlite:sqlite-error (err) (error 'sql-database-error :message (format nil "Error finalizing SQLite VM: ~A" (sqlite:sqlite-error-message err)))))) (defmethod database-store-next-row (result-set (database sqlite-database) list) (let ((n-col (sqlite-result-set-n-col result-set)) (result-types (sqlite-result-set-result-types result-set))) (if (= n-col 0) ;; empty result set nil (let ((row (sqlite-result-set-first-row result-set))) (if (sqlite:null-row-p row) ;; First row already used. fetch another row from DB. (handler-case (multiple-value-bind (n new-row col-names) (sqlite:sqlite-step (sqlite-result-set-vm result-set)) (declare (ignore n col-names) (type sqlite:sqlite-row-pointer-type new-row)) (if (sqlite:null-row-p new-row) (return-from database-store-next-row nil) (setf row new-row))) (sqlite:sqlite-error (err) (error 'sql-database-error :message (format nil "Error in sqlite-step: ~A" (sqlite:sqlite-error-message err))))) ;; Use the row previously read by database-query-result-set. (setf (sqlite-result-set-first-row result-set) (sqlite:make-null-row))) (loop for i = 0 then (1+ i) for rest on list do (setf (car rest) (clsql-uffi:convert-raw-field (sqlite:sqlite-raw-aref row i) (nth i result-types) :encoding (encoding database)))) (sqlite:sqlite-free-row row) t)))) ;;; Object listing (defmethod database-list-tables-and-sequences ((database sqlite-database) &key owner) (declare (ignore owner)) ;; Query is copied from .table command of sqlite comamnd line utility. (mapcar #'car (database-query "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name" database nil nil))) (defmethod database-list-tables ((database sqlite-database) &key owner) (remove-if #'(lambda (s) (and (>= (length s) 11) (string-equal (subseq s 0 11) "_CLSQL_SEQ_"))) (database-list-tables-and-sequences database :owner owner))) (defmethod database-list-views ((database sqlite-database) &key (owner nil)) (declare (ignore owner)) (mapcar #'car (database-query "SELECT name FROM sqlite_master WHERE type='view' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='view' ORDER BY name" database nil nil))) (defmethod database-list-indexes ((database sqlite-database) &key (owner nil)) (declare (ignore owner)) (mapcar #'car (database-query "SELECT name FROM sqlite_master WHERE type='index' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' ORDER BY name" database nil nil))) (defmethod database-list-table-indexes (table (database sqlite-database) &key (owner nil)) (declare (ignore owner)) (let ((*print-circle* nil)) (mapcar #'car (database-query (format nil "SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='~A' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' AND tbl_name='~A' ORDER BY name" table table) database nil nil)))) (declaim (inline sqlite-table-info)) (defun sqlite-table-info (table database) (database-query (format nil "PRAGMA table_info('~A')" table) database nil nil)) (defmethod database-list-attributes (table (database sqlite-database) &key (owner nil)) (declare (ignore owner)) (mapcar #'(lambda (table-info) (second table-info)) (sqlite-table-info table database))) (defmethod database-attribute-type (attribute table (database sqlite-database) &key (owner nil)) (declare (ignore owner)) (loop for field-info in (sqlite-table-info table database) when (string= attribute (second field-info)) return (let* ((raw-type (third field-info)) (start-length (position #\( raw-type)) (type (if start-length (subseq raw-type 0 start-length) raw-type)) (length (if start-length (parse-integer (subseq raw-type (1+ start-length)) :junk-allowed t) nil))) (values (when type (ensure-keyword type)) length nil (if (string-equal (fourth field-info) "0") 1 0))))) (defmethod database-create (connection-spec (type (eql :sqlite))) (declare (ignore connection-spec)) ;; databases are created automatically by SQLite t) (defmethod database-destroy (connection-spec (type (eql :sqlite))) (destructuring-bind (name) connection-spec (if (probe-file name) (delete-file name) nil))) (defmethod database-probe (connection-spec (type (eql :sqlite))) (destructuring-bind (name) connection-spec ;; TODO: Add a test that this file is a real sqlite database (or (string-equal ":memory:" name) (and (probe-file name) t)))) ;;; Database capabilities (defmethod db-type-has-boolean-where? ((db-type (eql :sqlite))) nil) cl-sql-6.7.2/db-sqlite/sqlite-api.lisp0000644000175000017500000002365111335067642016576 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite-api-uffi.lisp ;;;; Purpose: Low-level SQLite interface using UFFI ;;;; Authors: Aurelio Bignoli and Kevin Rosenberg ;;;; Created: Nov 2003 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2003 by Aurelio Bignoli ;;;; and Copyright (c) 2003-2004 by Kevin Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:sqlite (:use #:common-lisp #:uffi) (:export ;;; Conditions #:sqlite-error #:sqlite-error-code #:sqlite-error-message ;;; Core API. #:sqlite-open #:sqlite-close ;;; New API. #:sqlite-compile #:sqlite-step #:sqlite-finalize ;;; Extended API. #:sqlite-get-table #:sqlite-free-table #:sqlite-version ; Defined as constant. #:sqlite-encoding ; Defined as constant. #:sqlite-last-insert-rowid ;;; Utility functions. #:make-null-row #:make-null-vm #:null-row-p #:sqlite-aref #:sqlite-raw-aref #:sqlite-free-row ;;; Types. #:sqlite-row #:sqlite-row-pointer #:sqlite-row-pointer-type #:sqlite-vm-pointer)) (in-package #:sqlite) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Return values for sqlite_exec() and sqlite_step() ;;;; (defconstant SQLITE-OK 0 "Successful result") (defconstant SQLITE-ERROR 1 "SQL error or missing database") (defconstant SQLITE-ROW 100 "sqlite_step() has another row ready") (defconstant SQLITE-DONE 101 "sqlite_step() has finished executing") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Conditions. ;;;; (define-condition sqlite-error () ((message :initarg :message :reader sqlite-error-message :initform "") (code :initarg :code :reader sqlite-error-code)) (:report (lambda (condition stream) (let ((code (sqlite-error-code condition))) (format stream "SQLite error [~A]: ~A" code (sqlite-error-message condition)))))) (defun signal-sqlite-error (code &optional message) (let ((condition (make-condition 'sqlite-error :code code :message (if message message (uffi:convert-from-cstring (sqlite-error-string code)))))) (unless (signal condition) (invoke-debugger condition)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Foreign types definitions. ;;;; (def-foreign-type errmsg (* :unsigned-char)) (def-foreign-type sqlite-db :pointer-void) (def-foreign-type sqlite-vm :pointer-void) (def-foreign-type string-pointer (* (* :unsigned-char))) (def-foreign-type sqlite-row-pointer (* (* :unsigned-char))) (defvar +null-errmsg-pointer+ (make-null-pointer 'errmsg)) (defvar +null-string-pointer-pointer+ (make-null-pointer 'string-pointer)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Lisp types used in declarations. ;;;; (def-type sqlite-db-type sqlite-db) (def-type sqlite-row string-pointer) (def-type sqlite-row-pointer-type (* string-pointer)) (def-type sqlite-vm-pointer (* sqlite-vm)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Library functions. ;;;; (defmacro def-sqlite-function (name args &key (returning :void)) `(def-function ,name ,args :module "sqlite" :returning ,returning)) (def-sqlite-function "sqlite_error_string" ((error-code :int)) :returning :cstring) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Core API. ;;;; (declaim (inline %open)) (def-sqlite-function ("sqlite_open" %open) ((dbname :cstring) (mode :int) (error-message (* errmsg))) :returning sqlite-db) (declaim (inline sqlite-close)) (def-sqlite-function "sqlite_close" ((db sqlite-db))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; New API. ;;;; (declaim (inline %compile)) (def-sqlite-function ("sqlite_compile" %compile) ((db sqlite-db) (sql :cstring) (sql-tail (* (* :unsigned-char))) (vm (* sqlite-vm)) (error-message (* errmsg))) :returning :int) (declaim (inline %step)) (def-sqlite-function ("sqlite_step" %step) ((vm sqlite-vm) (cols-n (* :int)) (cols (* (* (* :unsigned-char)))) (col-names (* (* (* :unsigned-char))))) :returning :int) (declaim (inline %finalize)) (def-sqlite-function ("sqlite_finalize" %finalize) ((vm sqlite-vm) (error-message (* errmsg))) :returning :int) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Extended API. ;;;; (declaim (inline sqlite-last-insert-rowid)) (def-sqlite-function "sqlite_last_insert_rowid" ((db sqlite-db)) :returning :int) (declaim (inline %get-table)) (def-sqlite-function ("sqlite_get_table" %get-table) ((db sqlite-db) (sql :cstring) (result (* (* (* :unsigned-char)))) (rows-n (* :int)) (cols-n (* :int)) (error-message (* errmsg))) :returning :int) (declaim (inline %free-table)) (def-sqlite-function ("sqlite_free_table" %free-table) ((rows :pointer-void))) (declaim (inline sqlite-libversion)) (def-sqlite-function "sqlite_libversion" () :returning :cstring) (declaim (inline sqlite-libencoding)) (def-sqlite-function "sqlite_libencoding" () :returning :cstring) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Wrapper functions. ;;;; (defparameter sqlite-version (sqlite-libversion)) (defparameter sqlite-encoding (sqlite-libencoding)) (defun sqlite-open (db-name &optional (mode 0)) (with-cstring (db-name-native db-name) (let ((db (%open db-name-native mode +null-errmsg-pointer+))) (if (null-pointer-p db) (signal-sqlite-error SQLITE-ERROR (format nil "unable to open ~A" db-name)) db)))) (defun sqlite-compile (db sql) (with-cstring (sql-native sql) (let ((vm (allocate-foreign-object 'sqlite-vm))) (with-foreign-object (sql-tail '(* :unsigned-char)) (let ((result (%compile db sql-native sql-tail vm +null-errmsg-pointer+))) (if (= result SQLITE-OK) vm (progn (free-foreign-object vm) (signal-sqlite-error result)))))))) (defun sqlite-step (vm) (declare (type sqlite-vm-pointer vm)) (with-foreign-object (cols-n :int) (let ((cols (allocate-foreign-object '(* (* :unsigned-char)))) (col-names (allocate-foreign-object '(* (* :unsigned-char))))) (declare (type sqlite-row-pointer-type cols col-names)) (let ((result (%step (deref-pointer vm 'sqlite-vm) cols-n cols col-names))) (cond ((= result SQLITE-ROW) (let ((n (deref-pointer cols-n :int))) (values n cols col-names))) ((= result SQLITE-DONE) (free-foreign-object cols) (free-foreign-object col-names) (values 0 +null-string-pointer-pointer+ +null-string-pointer-pointer+)) (t (free-foreign-object cols) (free-foreign-object col-names) (signal-sqlite-error result))))))) (defun sqlite-finalize (vm) (declare (type sqlite-vm-pointer vm)) (let ((result (%finalize (deref-pointer vm 'sqlite-vm) +null-errmsg-pointer+))) (if (= result SQLITE-OK) (progn (free-foreign-object vm) t) (signal-sqlite-error result)))) (defun sqlite-get-table (db sql) (declare (type sqlite-db-type db)) (with-cstring (sql-native sql) (let ((rows (allocate-foreign-object '(* (* :unsigned-char))))) (declare (type sqlite-row-pointer-type rows)) (with-foreign-object (rows-n :int) (with-foreign-object (cols-n :int) (let ((result (%get-table db sql-native rows rows-n cols-n +null-errmsg-pointer+))) (if (= result SQLITE-OK) (let ((cn (deref-pointer cols-n :int)) (rn (deref-pointer rows-n :int))) (values rows rn cn)) (progn (free-foreign-object rows) (signal-sqlite-error result))))))))) (declaim (inline sqlite-free-table)) (defun sqlite-free-table (table) (declare (type sqlite-row-pointer-type table)) (%free-table (deref-pointer table 'sqlite-row-pointer))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Utility functions. ;;;; (declaim (inline make-null-row)) (defun make-null-row () +null-string-pointer-pointer+) (declaim (inline make-null-vm)) (defun make-null-vm () (uffi:make-null-pointer 'sqlite-vm)) (declaim (inline null-row-p)) (defun null-row-p (row) (null-pointer-p row)) (declaim (inline sqlite-aref)) (defun sqlite-aref (a n encoding) (declare (type sqlite-row-pointer-type a)) (convert-from-foreign-string (deref-array (deref-pointer a 'sqlite-row-pointer) '(:array (* :unsigned-char)) n) :encoding encoding)) (declaim (inline sqlite-raw-aref)) (defun sqlite-raw-aref (a n) (declare (type sqlite-row-pointer-type a)) (deref-array (deref-pointer a 'sqlite-row-pointer) '(:array (* :unsigned-char)) n)) (declaim (inline sqlite-free-row)) (defun sqlite-free-row (row) (declare (type sqlite-row-pointer-type row)) (free-foreign-object row)) cl-sql-6.7.2/db-sqlite/sqlite-package.lisp0000644000175000017500000000151211335067642017410 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite-package.lisp ;;;; Purpose: Package definition for low-level SQLite interface ;;;; Programmer: Aurelio Bignoli ;;;; Date Started: Aug 2003 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2003 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-sqlite (:use #:common-lisp #:clsql-sys) (:export #:sqlite-database)) cl-sql-6.7.2/db-sqlite/sqlite-loader.lisp0000644000175000017500000000313511335067642017266 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite-loader.lisp ;;;; Purpose: SQLite library loader using UFFI ;;;; Programmer: Aurelio Bignoli ;;;; Date Started: Nov 2003 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2003 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sqlite) (defvar *sqlite-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the SQLite library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *sqlite-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod database-type-library-loaded ((database-type (eql :sqlite))) "T if foreign library was able to be loaded successfully. " *sqlite-library-loaded*) (defmethod database-type-load-foreign ((database-type (eql :sqlite))) (clsql-uffi:find-and-load-foreign-library '("libsqlite" "sqlite") :module "sqlite" :supporting-libraries *sqlite-supporting-libraries*) (setq *sqlite-library-loaded* t)) (clsql-sys:database-type-load-foreign :sqlite) cl-sql-6.7.2/db-sqlite/Makefile0000644000175000017500000000126411335067642015271 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL SQLITE interface # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/clsql-postgresql-socket3.asd0000644000175000017500000000310012651763351017317 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-postgresql-socket.asd ;;;; Purpose: ASDF file for CLSQL PostgresSQL socket (protocol vs 3) backend ;;;; Programmer: Russ Tyndall ;;;; Date Started: Sept 2009 ;;;; ;;;; $Id$ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-postgresql-socket-system (:use #:asdf #:cl)) (in-package #:clsql-postgresql-socket-system) ;;; System definition (defsystem clsql-postgresql-socket3 :name "cl-sql-postgresql-socket3" :author "Russ Tyndall " :maintainer "Russ Tyndall " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL PostgreSQL Socket Driver" :long-description "cl-sql-postgresql-socket package provides a database driver to the PostgreSQL database via a socket interface." :depends-on (clsql md5 :cl-postgres (:feature sbcl sb-bsd-sockets)) :components ((:module :db-postgresql-socket3 :serial T :components ((:file "package") (:file "api") (:file "sql"))))) cl-sql-6.7.2/db-odbc/0000755000175000017500000000000014327126007013227 5ustar kevinkevincl-sql-6.7.2/db-odbc/odbc-dbi.lisp0000644000175000017500000007372111725170505015576 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-dbi.cl ;;;; Purpose: Mid-level (DBI) interface for CLSQL ODBC backend ;;;; Author: Kevin M. Rosenberg ;;;; Create: April 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:odbc-dbi (:use #:cl #:odbc) (:export #:bind-parameter #:close-query #:connect #:db-external-format #:db-hstmt #:db-width #:disconnect #:end-transaction #:fetch-row #:list-all-data-sources #:list-all-database-tables #:list-all-table-columns #:list-table-indexes #:loop-over-results #:prepare-sql #:rr-sql #:run-prepared-sql #:set-autocommit #:sql #:*auto-trim-strings* #:*default-database* #:*default-odbc-external-format* #:*null-value* ) (:documentation "This is the mid-level interface ODBC.")) (in-package #:odbc-dbi) (defgeneric terminate (src)) (defgeneric db-open-query (src query-expression &key arglen col-positions result-types width &allow-other-keys)) (defgeneric db-fetch-query-results (src &optional count)) (defgeneric %db-execute (src sql-expression &key &allow-other-keys)) (defgeneric db-execute-command (src sql-string)) (defgeneric %initialize-query (src arglen col-positions &key result-types width)) (defgeneric %read-query-data (src ignore-columns)) (defgeneric db-map-query (src type function query-exp &key result-types)) (defgeneric db-prepare-statement (src sql &key parameter-table parameter-columns)) (defgeneric get-odbc-info (src info-type)) (defvar *reuse-query-objects* t) ;;; SQL Interface (defclass odbc-db () (;; any reason to have more than one henv? (width :initform +max-precision+ :accessor db-width) (hstmt :initform nil :accessor db-hstmt) (henv :initform nil :allocation :class :initarg :henv :accessor henv) (hdbc :initform nil :initarg :hdbc :accessor hdbc) ;; info returned from SQLGetInfo (info :initform (make-hash-table) :reader db-info) (type :initform nil :initarg :db-type :reader db-type) (connected-p :initform nil :accessor db-connected-p) ;; not used yet (count :initform 0 :initarg :count :accessor db-count) ;; not used yet (total-count :initform 0 :allocation :class :accessor db-total-count) ;; the use of this slot is deprecated; it will be removed when dtf works without it. (query :initform nil :accessor db-query-object) ;; resource of (active and inactive) query objects (queries :initform () :accessor db-queries))) (defclass odbc-query () ((hstmt :initform nil :initarg :hstmt :accessor hstmt) ; = cursor?? (width :initform +max-precision+ :accessor query-width) (computed-result-types :initform nil :initarg :computed-result-types :accessor computed-result-types) (column-count :initform nil :accessor column-count) (column-names :initform (make-array 0 :element-type 'string :adjustable t :fill-pointer t) :accessor column-names) (column-c-types :initform (make-array 0 :element-type 'fixnum :adjustable t :fill-pointer t) :accessor column-c-types) (column-sql-types :initform (make-array 0 :element-type 'fixnum :adjustable t :fill-pointer t) :accessor column-sql-types) (column-data-ptrs :initform (make-array 0 :adjustable t :fill-pointer t) :accessor data-ptrs) (column-out-len-ptrs :initform (make-array 0 :adjustable t :fill-pointer t) :accessor column-out-len-ptrs) (column-precisions :initform (make-array 0 :element-type 'integer :adjustable t :fill-pointer t) :accessor column-precisions) (column-scales :initform (make-array 0 :element-type 'fixnum :adjustable t :fill-pointer t) :accessor column-scales) (column-nullables-p :initform (make-array 0 :element-type 'fixnum :adjustable t :fill-pointer t) :accessor column-nullables-p) ;;(parameter-count :initform 0 :accessor parameter-count) (parameter-data-ptrs :initform (make-array 0 :adjustable t :fill-pointer t) :accessor parameter-ptrs) ;; a query string or a query expression object (sql-expression :initform nil :initarg :sql-expression :accessor sql-expression) ;; database object the query is to be run against (database :initarg :database :reader query-database) (active-p :initform nil :initarg :active-p :accessor query-active-p)) (:documentation "Stores query information, like SQL query string/expression and database to run the query against." )) ;;; AODBC Compatible interface (defun connect (&key data-source-name user password connection-string completion window-handle (autocommit t)) (let ((db (make-instance 'odbc-db))) (unless (henv db) ;; has class allocation! (setf (henv db) (%new-environment-handle))) (setf (hdbc db) (%new-db-connection-handle (henv db))) (if connection-string (%sql-driver-connect (hdbc db) connection-string (ecase completion (:no-prompt odbc::$SQL_DRIVER_NOPROMPT) (:complete odbc::$SQL_DRIVER_COMPLETE) (:prompt odbc::$SQL_DRIVER_PROMPT) (:complete-required odbc::$SQL_DRIVER_COMPLETE_REQUIRED)) window-handle) (%sql-connect (hdbc db) data-source-name user password)) #+ignore (setf (db-hstmt db) (%new-statement-handle (hdbc db))) (when (/= (get-odbc-info db odbc::$SQL_TXN_CAPABLE) odbc::$SQL_TC_NONE) (if autocommit (enable-autocommit (hdbc db)) (disable-autocommit (hdbc db)))) db)) (defun disconnect (database) "This is set in the generic-odbc-database disconnect-fn slot so xref fails but this does get called on generic ODBC connections " (with-slots (hdbc queries) database (dolist (query queries) (db-close-query query :drop-p T)) (when (db-hstmt database) (%free-statement (db-hstmt database) :drop)) (%disconnect hdbc))) (defun sql (expr &key db result-types row-count (column-names t) query hstmt width) (declare (ignore hstmt)) (cond (query (let ((q (db-open-query db expr :result-types result-types :width width))) (if column-names (values q (column-names q)) q))) (t (multiple-value-bind (data col-names) (db-query db expr :result-types result-types :width width) (cond (row-count (if (consp data) (length data) data)) (column-names (values data col-names)) (t data)))))) (defun fetch-row (query &optional (eof-errorp t) eof-value) (multiple-value-bind (row query count) (db-fetch-query-results query 1) (cond ((zerop count) (close-query query) (when eof-errorp (error 'clsql:sql-database-data-error :message "ODBC: Ran out of data in fetch-row")) eof-value) (t (car row))))) (defun close-query (query) (db-close-query query)) (defun list-all-database-tables (&key db hstmt) (declare (ignore hstmt)) (let ((query (get-free-query db))) (unwind-protect (progn (with-slots (hstmt) query (unless hstmt (setf hstmt (%new-statement-handle (hdbc db)))) (%list-tables hstmt) (%initialize-query query nil nil) (values (db-fetch-query-results query) (coerce (column-names query) 'list)))) (db-close-query query)))) (defun list-table-indexes (table &key db unique hstmt &aux (table (princ-to-string (clsql-sys::unescaped-database-identifier table)))) (declare (ignore hstmt)) (let ((query (get-free-query db))) (unwind-protect (progn (with-slots (hstmt) query (unless hstmt (setf hstmt (%new-statement-handle (hdbc db)))) (%table-statistics table hstmt :unique unique) (%initialize-query query nil nil) (values (db-fetch-query-results query) (coerce (column-names query) 'list)))) (db-close-query query)))) (defun list-all-table-columns (table &key db hstmt &aux (table (princ-to-string (clsql-sys::unescaped-database-identifier table)))) (declare (ignore hstmt)) (db-describe-columns db nil nil table nil)) ;; use nil rather than "" for unspecified values (defun list-all-data-sources () (let ((db (make-instance 'odbc-db))) (unless (henv db) ;; has class allocation! (setf (henv db) (%new-environment-handle))) (%list-data-sources (henv db)))) (defun rr-sql (hstmt sql-statement &key db) (declare (ignore hstmt sql-statement db)) (warn "rr-sql not implemented.")) ;;; Mid-level interface (defun db-commit (database) (%commit (henv database) (hdbc database))) (defun db-rollback (database) (%rollback (henv database) (hdbc database))) (defun db-cancel-query (query) (with-slots (hstmt) query (%sql-cancel hstmt) (setf (query-active-p query) nil))) #+simple-version (defmacro with-transaction (&body body) `(%with-transaction (:henv (henv ,*default-database*) :hdbc (hdbc ,*default-database*)) ,@body)) (defmethod initialize-instance :after ((query odbc-query) &key sql henv hdbc &allow-other-keys) (when sql (let ((hstmt (%new-statement-handle hdbc))) (%sql-exec-direct sql hstmt henv hdbc) (with-slots (column-count column-names column-c-types column-sql-types column-data-ptrs column-out-len-ptrs column-precisions column-scales column-nullables-p active-p) query (setf (hstmt query) hstmt) (%initialize-query query nil nil) (setf active-p t))))) ;; one for odbc-db is missing ;; TODO: Seems to be uncalled (defmethod terminate ((query odbc-query)) ;;(format tb::*local-output* "~%*** terminated: ~s" query) (db-close-query query)) (defun %dispose-column-ptrs (query) "frees memory allocated for query object column-data and column-data-length" (with-slots (column-data-ptrs column-out-len-ptrs hstmt) query (loop for data-ptr across column-data-ptrs for out-len-ptr across column-out-len-ptrs when data-ptr do (uffi:free-foreign-object data-ptr) when out-len-ptr do (uffi:free-foreign-object out-len-ptr)) (setf (fill-pointer column-data-ptrs) 0 (fill-pointer column-out-len-ptrs) 0))) (defmethod db-open-query ((database odbc-db) query-expression &key arglen col-positions result-types width &allow-other-keys) (db-open-query (get-free-query database) query-expression :arglen arglen :col-positions col-positions :result-types result-types :width (if width width (db-width database)))) (defmethod db-open-query ((query odbc-query) query-expression &key arglen col-positions result-types width &allow-other-keys) (%db-execute query query-expression) (%initialize-query query arglen col-positions :result-types result-types :width width)) (defmethod db-fetch-query-results ((database odbc-db) &optional count) (db-fetch-query-results (db-query-object database) count)) (defmethod db-fetch-query-results ((query odbc-query) &optional count) (when (query-active-p query) (with-slots (column-count column-data-ptrs column-c-types column-sql-types column-out-len-ptrs column-precisions hstmt computed-result-types) query (let* ((rows-fetched 0) (rows (loop for i from 0 until (or (and count (= i count)) (= (%sql-fetch hstmt) odbc::$SQL_NO_DATA_FOUND)) collect (loop for result-type across computed-result-types for data-ptr across column-data-ptrs for c-type across column-c-types for sql-type across column-sql-types for out-len-ptr across column-out-len-ptrs for precision across column-precisions for j from 0 ; column count is zero based in lisp collect (progn (incf rows-fetched) (cond ((< 0 precision (query-width query)) (read-data data-ptr c-type sql-type out-len-ptr result-type)) ((zerop (get-cast-long out-len-ptr)) nil) (t (read-data-in-chunks hstmt j data-ptr c-type sql-type out-len-ptr result-type)))))))) (values rows query rows-fetched))))) (defun db-query (database query-expression &key result-types width) (let ((free-query (get-free-query database))) (setf (sql-expression free-query) query-expression) (unwind-protect (progn (%db-execute free-query query-expression) (%initialize-query free-query nil nil :result-types result-types :width width) (if (plusp (column-count free-query)) ;; KMR: Added check for commands that don't return columns (values (db-fetch-query-results free-query nil) (map 'list #'identity (column-names free-query))) (values (result-rows-count (hstmt free-query)) nil))) (db-close-query free-query) ))) (defmethod %db-execute ((database odbc-db) sql-expression &key &allow-other-keys) (%db-execute (get-free-query database) sql-expression)) (defmethod %db-execute ((query odbc-query) sql-expression &key &allow-other-keys) (with-slots (henv hdbc) (odbc::query-database query) (with-slots (hstmt) query (unless hstmt (setf hstmt (%new-statement-handle hdbc))) (setf (sql-expression query) sql-expression) (%sql-exec-direct sql-expression hstmt henv hdbc) query))) ;; reuse inactive queries (defun get-free-query (database) "get-free-query finds or makes a nonactive query object, and then sets it to active. This makes the functions db-execute-command and db-query thread safe." (with-slots (queries hdbc) database (or (and *reuse-query-objects* (clsql-sys:without-interrupts (let ((inactive-query (find-if (lambda (query) (not (query-active-p query))) queries))) (when inactive-query (with-slots (column-count column-names column-c-types width hstmt column-sql-types column-data-ptrs column-out-len-ptrs column-precisions column-scales column-nullables-p) inactive-query (setf column-count 0 width +max-precision+ ;; KMR hstmt (%new-statement-handle hdbc) (fill-pointer column-names) 0 (fill-pointer column-c-types) 0 (fill-pointer column-sql-types) 0 (fill-pointer column-data-ptrs) 0 (fill-pointer column-out-len-ptrs) 0 (fill-pointer column-precisions) 0 (fill-pointer column-scales) 0 (fill-pointer column-nullables-p) 0)) (setf (query-active-p inactive-query) t)) inactive-query))) (let ((new-query (make-instance 'odbc-query :database database ;;(clone-database database) :active-p t))) (push new-query queries) new-query)))) (defmethod db-execute-command ((database odbc-db) sql-string) (db-execute-command (get-free-query database) sql-string)) (defmethod db-execute-command ((query odbc-query) sql-string) (with-slots (hstmt database) query (with-slots (henv hdbc) database (unless hstmt (setf hstmt (%new-statement-handle hdbc))) (unwind-protect (%sql-exec-direct sql-string hstmt henv hdbc) (db-close-query query))))) (defmethod %initialize-query ((database odbc-db) arglen col-positions &key result-types width) (%initialize-query (db-query-object database) arglen col-positions :result-types result-types :width (if width width (db-width database)))) (defmethod %initialize-query ((query odbc-query) arglen col-positions &key result-types width) (with-slots (hstmt computed-result-types column-count column-names column-c-types column-sql-types column-data-ptrs column-out-len-ptrs column-precisions column-scales column-nullables-p) query (setf column-count (if arglen (min arglen (result-columns-count hstmt)) (result-columns-count hstmt))) (when width (setf (query-width query) width)) ;;(format tb::*local-output* "~%column-count: ~d, col-positions: ~d" column-count col-positions) (labels ((initialize-column (col-nr) (multiple-value-bind (name sql-type precision scale nullable-p) (%describe-column hstmt (1+ col-nr)) ;; allocate space to bind result rows to (multiple-value-bind (c-type data-ptr out-len-ptr size long-p) (%allocate-bindings sql-type precision) (if long-p ;; if long-p we fetch in chunks with %sql-get-data but must ensure that out_len_ptr is non zero (setf (uffi:deref-pointer out-len-ptr #.odbc::$ODBC-LONG-TYPE) #.odbc::$SQL_NO_TOTAL) (%bind-column hstmt col-nr c-type data-ptr (1+ size) out-len-ptr)) (vector-push-extend name column-names) (vector-push-extend sql-type column-sql-types) (vector-push-extend (sql-to-c-type sql-type) column-c-types) (vector-push-extend precision column-precisions) (vector-push-extend scale column-scales) (vector-push-extend nullable-p column-nullables-p) (vector-push-extend data-ptr column-data-ptrs) (vector-push-extend out-len-ptr column-out-len-ptrs))))) (if col-positions (dolist (col-nr col-positions) (initialize-column col-nr)) (dotimes (col-nr column-count) ;; get column information (initialize-column col-nr)))) ;; TODO: move this into the above loop (setf computed-result-types (make-array column-count)) (dotimes (i column-count) (setf (aref computed-result-types i) (cond ((consp result-types) (nth i result-types)) ((eq result-types :auto) (case (aref column-c-types i) (#.odbc::$SQL_C_SLONG :int) (#.odbc::$SQL_C_DOUBLE :double) (#.odbc::$SQL_C_FLOAT :float) (#.odbc::$SQL_C_SSHORT :short) (#.odbc::$SQL_C_STINYINT :short) (#.odbc::$SQL_C_SBIGINT #.odbc::$ODBC-BIG-TYPE) (#.odbc::$SQL_C_TYPE_TIMESTAMP :time) (#.odbc::$SQL_C_CHAR ;; TODO: Read this as rational instead of double (or (case (aref column-sql-types i) ((#.odbc::$SQL_NUMERIC #.odbc::$SQL_DECIMAL) :double)) T)) (t t))) (t t))))) query) (defun db-close-query (query &key (drop-p (not *reuse-query-objects*))) (with-slots (hstmt column-count column-names column-c-types column-sql-types column-data-ptrs column-out-len-ptrs column-precisions column-scales column-nullables-p database) query (%dispose-column-ptrs query) (cond ((null hstmt) nil) (drop-p (%free-statement hstmt :drop) ;; dont free with uffi/ this is a double free and crashes everything ;; (uffi:free-foreign-object hstmt) (setf hstmt nil)) (t (%free-statement hstmt :unbind) (%free-statement hstmt :reset) (%free-statement hstmt :close))) (setf (query-active-p query) nil) (when drop-p (clsql-sys:without-interrupts (with-slots (queries) database (setf queries (remove query queries)))))) query) (defmethod %read-query-data ((database odbc-db) ignore-columns) (%read-query-data (db-query-object database) ignore-columns)) (defmethod %read-query-data ((query odbc-query) ignore-columns) (with-slots (hstmt column-count column-c-types column-sql-types column-data-ptrs column-out-len-ptrs column-precisions computed-result-types) query (unless (= (odbc::SQLFetch hstmt) odbc::$SQL_NO_DATA_FOUND) (values (loop for col-nr from 0 to (- column-count (if (eq ignore-columns :last) 2 1)) for result-type across computed-result-types collect (let ((precision (aref column-precisions col-nr)) (sql-type (aref column-sql-types col-nr))) (cond ((or (< 0 precision (query-width query)) (and (zerop precision) (not (find sql-type '($SQL_C_CHAR))))) (read-data (aref column-data-ptrs col-nr) (aref column-c-types col-nr) sql-type (aref column-out-len-ptrs col-nr) result-type)) ((zerop (get-cast-long (aref column-out-len-ptrs col-nr))) *null*) (t (read-data-in-chunks hstmt col-nr (aref column-data-ptrs col-nr) (aref column-c-types col-nr) (aref column-sql-types col-nr) (aref column-out-len-ptrs col-nr) result-type))))) t)))) (defmethod db-map-query ((database odbc-db) type function query-exp &key result-types) (db-map-query (get-free-query database) type function query-exp :result-types result-types)) (defmethod db-map-query ((query odbc-query) type function query-exp &key result-types) (declare (ignore type)) ; preliminary. Do a type coersion here (%db-execute query (sql-expression query-exp)) (unwind-protect (progn (%initialize-query query nil nil :result-types result-types) ;; the main loop (loop for data = (%read-query-data query nil) while data do (apply function data))) ;; dispose of memory and set query inactive or get rid of it (db-close-query query))) (defun db-map-bind-query (query type function &rest parameters) (declare (ignore type)) ; preliminary. Do a type coersion here (unwind-protect (progn (apply #'%db-bind-execute query parameters) ;; the main loop (loop with data while (setf data (%read-query-data query nil)) do (apply function data))) ;; dispose of memory and set query inactive or get rid of it (%db-reset-query query))) ;; does not always return exactly a lisp type... (defun sql-to-lisp-type (sql-type) (ecase sql-type ((#.odbc::$SQL_CHAR #.odbc::$SQL_VARCHAR #.odbc::$SQL_LONGVARCHAR) :string) ((#.odbc::$SQL_NUMERIC #.odbc::$SQL_DECIMAL) :string) ; ?? (#.odbc::$SQL_BIGINT #.odbc::$ODBC-BIG-TYPE) (#.odbc::$SQL_INTEGER #.odbc::$ODBC-LONG-TYPE) (#.odbc::$SQL_SMALLINT :short) ((#.odbc::$SQL_FLOAT #.odbc::$SQL_DOUBLE) #.odbc::$ODBC-LONG-TYPE) (#.odbc::$SQL_REAL #.odbc::$ODBC-LONG-TYPE) ((#.odbc::$SQL_DATE #.odbc::$SQL_TYPE_DATE) 'sql-c-date) ((#.odbc::$SQL_TIME #.odbc::$SQL_TYPE_TIME) 'sql-c-time) ((#.odbc::$SQL_TIMESTAMP #.odbc::$SQL_TYPE_TIMESTAMP) 'sql-c-timestamp) ;;((#.odbc::$SQL_BINARY #.odbc::$SQL_VARBINARY #.odbc::$SQL_LONGVARBINARY) odbc::$SQL_C_BINARY) ; ?? (#.odbc::$SQL_TINYINT :short) ;;(#.odbc::$SQL_BIT odbc::$SQL_C_BIT) ; ?? (#.odbc::$SQL_BIT :short) ((#.odbc::$SQL_VARBINARY #.odbc::$SQL_LONGVARBINARY) :binary) )) ;; prepared queries (defmethod db-prepare-statement ((database odbc-db) sql &key parameter-table parameter-columns) (with-slots (hdbc) database (let ((query (get-free-query database))) (with-slots (hstmt) query (unless hstmt (setf hstmt (%new-statement-handle hdbc)))) (db-prepare-statement query sql :parameter-table parameter-table :parameter-columns parameter-columns)))) (defmethod db-prepare-statement ((query odbc-query) (sql string) &key parameter-table parameter-columns) ;; this is a workaround to get hold of the column types when the driver does not ;; support SQLDescribeParam. To do: put code in here for drivers that do ;; support it. (unless (string-equal sql "insert" :end1 6) (error 'clsql:sql-database-error (format nil "Only insert expressions are supported in literal ODBC: '~a'." sql))) (%db-execute query (format nil "select ~{~a~^,~} from ~a where 0 = 1" (or parameter-columns '("*")) parameter-table)) (%initialize-query query nil nil) (with-slots (hstmt) query (%free-statement hstmt :unbind) (%free-statement hstmt :reset) (setf (sql-expression query) sql) (%sql-prepare hstmt sql)) query) (defun %db-bind-execute (query &rest parameters) "Only used from db-map-bind-query parameters are released in %reset-query " (with-slots (hstmt parameter-data-ptrs) query (loop for parameter in parameters with data-ptr and size and parameter-string do (setf parameter-string (if (stringp parameter) parameter (write-to-string parameter)) size (length parameter-string) data-ptr (uffi:allocate-foreign-string (1+ size))) (vector-push-extend data-ptr parameter-data-ptrs) (%sql-bind-parameter hstmt (1- (fill-pointer parameter-data-ptrs)) odbc::$SQL_PARAM_INPUT odbc::$SQL_C_CHAR ; (aref column-c-types parameter-count) odbc::$SQL_CHAR ; sql-type (query-width query) ;precision ; this should be the actual precision! ;; scale 0 ;; should be calculated for odbc::$SQL_DECIMAL, ;;$SQL_NUMERIC and odbc::$SQL_TIMESTAMP data-ptr ;; = rgbValue 0 ;; *pcbValue; ;; change this for output and binary input! (see 3-32) +null-ptr+) (%put-str data-ptr parameter-string size)) (%sql-execute hstmt))) (defun %db-reset-query (query) "Only used from db-map-bind-query parameters are allocated in %db-bind-execute " (with-slots (hstmt parameter-data-ptrs) query (prog1 (db-fetch-query-results query nil) (%free-statement hstmt :reset) ;; but _not_ :unbind ! (%free-statement hstmt :close) (dotimes (param-nr (fill-pointer parameter-data-ptrs)) (let ((data-ptr (aref parameter-data-ptrs param-nr))) (when data-ptr (uffi:free-foreign-object data-ptr)))) (setf (fill-pointer parameter-data-ptrs) 0)))) (defun data-parameter-ptr (hstmt) (uffi:with-foreign-object (param-ptr :pointer-void) (let ((return-code (%sql-param-data hstmt param-ptr))) ;;(format t "~%return-code from %sql-param-data: ~a~%" return-code) (when (= return-code odbc::$SQL_NEED_DATA) ;;(ffc::%pointer-to-address (%get-ptr param-ptr)) (uffi:deref-pointer param-ptr :pointer-void))))) ;; database inquiery functions (defun db-describe-columns (database table-qualifier table-owner table-name column-name) (with-slots (hdbc) database (%describe-columns hdbc table-qualifier table-owner table-name column-name))) ;; should translate info-type integers to keywords in order to make this ;; more readable? (defmethod get-odbc-info ((database odbc-db) info-type) (with-slots (hdbc info) database (or (gethash info-type info) (setf (gethash info-type info) (%sql-get-info hdbc info-type))))) (defmethod get-odbc-info ((query odbc-query) info-type) (get-odbc-info (odbc::query-database query) info-type)) ;; driver inquiry ;; How does this differ from list-data-sources? (defgeneric db-data-sources (db-type)) (defmethod db-data-sources ((db-type (eql :odbc))) "Returns a list of (data-source description) - pairs" (let ((henv (%new-environment-handle))) (unwind-protect (loop with direction = :first for data-source+description = (multiple-value-list (%sql-data-sources henv :direction direction)) while (car data-source+description) collect data-source+description do (setf direction :next)) (%sql-free-environment henv)))) cl-sql-6.7.2/db-odbc/odbc-sql.lisp0000644000175000017500000001562212303270414015624 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-sql.cl ;;;; Purpose: Medium-level interface for CLSQL ODBC backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-odbc (:use #:common-lisp #:clsql-sys) (:export #:odbc-database) (:documentation "This is the CLSQL interface to ODBC.")) (in-package #:clsql-odbc) ;; ODBC interface (defclass odbc-database (generic-odbc-database) ()) (defclass odbc-postgresql-database (generic-odbc-database generic-postgresql-database) ()) (defmethod database-name-from-spec (connection-spec (database-type (eql :odbc))) (check-connection-spec connection-spec database-type (dsn user password &key connection-string completion window-handle)) (destructuring-bind (dsn user password &key connection-string completion window-handle) connection-spec (declare (ignore password connection-string completion window-handle)) (concatenate 'string dsn "/" user))) (defmethod database-connect (connection-spec (database-type (eql :odbc))) (check-connection-spec connection-spec database-type (dsn user password &key connection-string completion window-handle)) (destructuring-bind (dsn user password &key connection-string (completion :no-prompt) window-handle) connection-spec (handler-case (let ((db (make-instance 'odbc-database :name (database-name-from-spec connection-spec :odbc) :database-type :odbc :connection-spec connection-spec :dbi-package (find-package '#:odbc-dbi) :odbc-conn (odbc-dbi:connect :user user :password password :data-source-name dsn :connection-string connection-string :completion completion :window-handle window-handle)))) (store-type-of-connected-database db) ;; Ensure this database type is initialized so can check capabilities of ;; underlying database (initialize-database-type :database-type database-type) (if (eql :postgresql (database-underlying-type db)) (make-instance 'odbc-postgresql-database :name (database-name-from-spec connection-spec :odbc) :database-type :odbc :connection-spec connection-spec :dbi-package (find-package '#:odbc-dbi) :odbc-db-type :postgresql :odbc-conn (clsql-sys::odbc-conn db)) db)) #+ignore (error () ;; Init or Connect failed (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :message "Connection failed"))))) (defmethod database-underlying-type ((database generic-odbc-database)) (clsql-sys::database-odbc-db-type database)) (defun store-type-of-connected-database (db) (let* ((odbc-conn (clsql-sys::odbc-conn db)) (server-name (odbc-dbi::get-odbc-info odbc-conn odbc::$SQL_SERVER_NAME)) (dbms-name (odbc-dbi::get-odbc-info odbc-conn odbc::$SQL_DBMS_NAME)) (type ;; need SERVER-NAME and DBMS-NAME because many drivers mix this up (cond ((or (search "postgresql" server-name :test #'char-equal) (search "postgresql" dbms-name :test #'char-equal)) (unless (find-package 'clsql-postgresql) (ignore-errors (asdf:operate 'asdf:load-op 'clsql-postgresql-socket))) :postgresql) ((or (search "Microsoft SQL Server" server-name :test #'char-equal) (search "Microsoft SQL Server" dbms-name :test #'char-equal)) :mssql) ((or (search "mysql" server-name :test #'char-equal) (search "mysql" dbms-name :test #'char-equal)) (unless (find-package 'clsql-mysql) ;; ignore errors on platforms where the shared libraries are not available (ignore-errors (asdf:operate 'asdf:load-op 'clsql-mysql))) :mysql) ((or (search "oracle" server-name :test #'char-equal) (search "oracle" dbms-name :test #'char-equal)) :oracle)))) (setf (clsql-sys::database-odbc-db-type db) type))) (defmethod database-create (connection-spec (type (eql :odbc))) (declare (ignore connection-spec)) (warn "Not implemented.")) (defmethod database-destroy (connection-spec (type (eql :odbc))) (declare (ignore connection-spec)) (warn "Not implemented.")) (defmethod database-probe (connection-spec (type (eql :odbc))) (when (find (car connection-spec) (database-list connection-spec type) :test #'string-equal) t)) (defmethod database-list (connection-spec (type (eql :odbc))) (declare (ignore connection-spec)) (odbc-dbi:list-all-data-sources)) (defmethod database-list-indexes ((database odbc-database) &key (owner nil)) (let ((result '())) (dolist (table (database-list-tables database :owner owner) result) (setq result (append (database-list-table-indexes table database :owner owner) result))))) (defmethod database-list-table-indexes (table (database odbc-database) &key (owner nil)) (declare (ignore owner)) (multiple-value-bind (rows col-names) (odbc-dbi:list-table-indexes table :db (clsql-sys::odbc-conn database)) (declare (ignore col-names)) ;; INDEX_NAME is hard-coded in sixth position by ODBC driver ;; FIXME: ??? is hard-coded in the fourth position (do ((results nil) (loop-rows rows (cdr loop-rows))) ((null loop-rows) (nreverse results)) (let* ((row (car loop-rows)) (col (nth 5 row))) (unless (or (null col) (find col results :test #'string-equal)) (push col results)))))) ;;; Database capabilities (defmethod db-backend-has-create/destroy-db? ((db-type (eql :odbc))) nil) (defmethod database-initialize-database-type ((database-type (eql :odbc))) ;; nothing to do t) (when (clsql-sys:database-type-library-loaded :odbc) (clsql-sys:initialize-database-type :database-type :odbc)) cl-sql-6.7.2/db-odbc/odbc-ff-interface.lisp0000644000175000017500000003362511610324732017364 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Package: odbc -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-ff-interface.lisp ;;;; Purpose: Function definitions for UFFI interface to ODBC ;;;; Author: Kevin M. Rosenberg ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg ;;;; and Copyright (C) Paul Meurer 1999 - 2001. All rights reserved. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:odbc) (def-foreign-type sql-handle :pointer-void) (def-foreign-type sql-handle-ptr (* sql-handle)) (def-foreign-type string-ptr (* :unsigned-char)) (def-type long-ptr-type (* #.$ODBC-LONG-TYPE)) ;; ODBC3 (def-function "SQLAllocHandle" ((handle-type :short) (input-handle sql-handle) (*phenv sql-handle-ptr)) :module "odbc" :returning :short) ;; ODBC3 version of SQLFreeStmt, SQLFreeConnect, and SSQLFreeStmt (def-function "SQLFreeHandle" ((handle-type :short) ; HandleType (input-handle sql-handle)) ; Handle :module "odbc" :returning :short) ; RETCODE_SQL_API ;; deprecated (def-function "SQLAllocEnv" ((*phenv sql-handle-ptr) ; HENV FAR *phenv ) :module "odbc" :returning :short) ; RETCODE_SQL_API ;; deprecated (def-function "SQLAllocConnect" ((henv sql-handle) ; HENV henv (*phdbc sql-handle-ptr) ; HDBC FAR *phdbc ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLConnect" ((hdbc sql-handle) ; HDBC hdbc (*szDSN :cstring) ; UCHAR FAR *szDSN (cbDSN :short) ; SWORD cbDSN (*szUID :cstring) ; UCHAR FAR *szUID (cbUID :short) ; SWORD cbUID (*szAuthStr :cstring) ; UCHAR FAR *szAuthStr (cbAuthStr :short) ; SWORD cbAuthStr ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLDriverConnect" ((hdbc sql-handle) ; HDBC hdbc (hwnd sql-handle) ; SQLHWND hwnd (*szConnStrIn :cstring) ; UCHAR FAR *szConnStrIn (cbConnStrIn :short) ; SWORD cbConnStrIn (*szConnStrOut string-ptr) ; UCHAR FAR *szConnStrOut (cbConnStrOutMax :short) ; SWORD cbConnStrOutMax (*pcbConnStrOut :pointer-void) ; SWORD FAR *pcbConnStrOut (fDriverCompletion :short) ; UWORD fDriverCompletion ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLDisconnect" ((hdbc sql-handle)) ; HDBC hdbc :module "odbc" :returning :short) ; RETCODE_SQL_API ;;deprecated (def-function "SQLFreeConnect" ((hdbc sql-handle)) ; HDBC hdbc :module "odbc" :returning :short) ; RETCODE_SQL_API ;; deprecated (def-function "SQLAllocStmt" ((hdbc sql-handle) ; HDBC hdbc (*phstmt sql-handle-ptr) ; HSTMT FAR *phstmt ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLGetInfo" ((hdbc sql-handle) ; HDBC hdbc (fInfoType :short) ; UWORD fInfoType (rgbInfoValue :pointer-void) ; PTR rgbInfoValue (cbInfoValueMax :short) ; SWORD cbInfoValueMax (*pcbInfoValue :pointer-void) ; SWORD FAR *pcbInfoValue ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLPrepare" ((hstmt sql-handle) ; HSTMT hstmt (*szSqlStr :cstring) ; UCHAR FAR *szSqlStr (cbSqlStr :int) ; SDWORD cbSqlStr ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLExecute" ((hstmt sql-handle) ; HSTMT hstmt ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLExecDirect" ((hstmt sql-handle) ; HSTMT hstmt (*szSqlStr :cstring) ; UCHAR FAR *szSqlStr (cbSqlStr :int) ; SDWORD cbSqlStr ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLFreeStmt" ((hstmt sql-handle) ; HSTMT hstmt (fOption :short)) ; UWORD fOption :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLCancel" ((hstmt sql-handle) ; HSTMT hstmt ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLError" ((henv sql-handle) ; HENV henv (hdbc sql-handle) ; HDBC hdbc (hstmt sql-handle) ; HSTMT hstmt (*szSqlState string-ptr) ; UCHAR FAR *szSqlState (*pfNativeError (* :int)) ; SDWORD FAR *pfNativeError (*szErrorMsg string-ptr) ; UCHAR FAR *szErrorMsg (cbErrorMsgMax :short) ; SWORD cbErrorMsgMax (*pcbErrorMsg (* :short)) ; SWORD FAR *pcbErrorMsg ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLNumResultCols" ((hstmt sql-handle) ; HSTMT hstmt (*pccol (* :short)) ; SWORD FAR *pccol ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLRowCount" ((hstmt sql-handle) ; HSTMT hstmt (*pcrow (* :int)) ; SDWORD FAR *pcrow ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLDescribeCol" ((hstmt sql-handle) ; HSTMT hstmt (icol :short) ; UWORD icol (*szColName string-ptr) ; UCHAR FAR *szColName (cbColNameMax :short) ; SWORD cbColNameMax (*pcbColName (* :short)) ; SWORD FAR *pcbColName (*pfSqlType (* :short)) ; SWORD FAR *pfSqlType (*pcbColDef (* #.$ODBC-ULONG-TYPE)) ; UDWORD FAR *pcbColDef (*pibScale (* :short)) ; SWORD FAR *pibScale (*pfNullable (* :short)) ; SWORD FAR *pfNullable ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLColAttributes" ((hstmt sql-handle) ; HSTMT hstmt (icol :short) ; UWORD icol (fDescType :short) ; UWORD fDescType (rgbDesc string-ptr) ; PTR rgbDesc (cbDescMax :short) ; SWORD cbDescMax (*pcbDesc (* :short)) ; SWORD FAR *pcbDesc (*pfDesc (* :int)) ; SDWORD FAR *pfDesc ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLColumns" ((hstmt sql-handle) ; HSTMT hstmt (*szTableQualifier :cstring) ; UCHAR FAR *szTableQualifier (cbTableQualifier :short) ; SWORD cbTableQualifier (*szTableOwner :cstring) ; UCHAR FAR *szTableOwner (cbTableOwner :short) ; SWORD cbTableOwner (*szTableName :cstring) ; UCHAR FAR *szTableName (cbTableName :short) ; SWORD cbTableName (*szColumnName :cstring) ; UCHAR FAR *szColumnName (cbColumnName :short) ; SWORD cbColumnName ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLBindCol" ((hstmt sql-handle) ; HSTMT hstmt (icol :short) ; UWORD icol (fCType :short) ; SWORD fCType (rgbValue :pointer-void) ; PTR rgbValue (cbValueMax :int) ; SDWORD cbValueMax (*pcbValue (* :int)) ; SDWORD FAR *pcbValue ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLFetch" ((hstmt sql-handle) ; HSTMT hstmt ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLTransact" ((henv sql-handle) ; HENV henv (hdbc sql-handle) ; HDBC hdbc (fType :short) ; UWORD fType ($SQL_COMMIT or $SQL_ROLLBACK) ) :module "odbc" :returning :short) ; RETCODE_SQL_API ;; ODBC 2.0 (def-function "SQLDescribeParam" ((hstmt sql-handle) ; HSTMT hstmt (ipar :short) ; UWORD ipar (*pfSqlType (* :short)) ; SWORD FAR *pfSqlType (*pcbColDef (* :unsigned-int)) ; UDWORD FAR *pcbColDef (*pibScale (* :short)) ; SWORD FAR *pibScale (*pfNullable (* :short)) ; SWORD FAR *pfNullable ) :module "odbc" :returning :short) ; RETCODE_SQL_API ;; ODBC 2.0 (def-function "SQLBindParameter" ((hstmt sql-handle) ; HSTMT hstmt (ipar :short) ; UWORD ipar (fParamType :short) ; SWORD fParamType (fCType :short) ; SWORD fCType (fSqlType :short) ; SWORD fSqlType (cbColDef :int) ; UDWORD cbColDef (ibScale :short) ; SWORD ibScale (rgbValue :pointer-void) ; PTR rgbValue (cbValueMax :int) ; SDWORD cbValueMax (*pcbValue :pointer-void) ; SDWORD FAR *pcbValue ) :module "odbc" :returning :short) ; RETCODE_SQL_API ;; level 1 (def-function "SQLGetData" ((hstmt sql-handle) ; HSTMT hstmt (icol :short) ; UWORD icol (fCType :short) ; SWORD fCType (rgbValue :pointer-void) ; PTR rgbValue (cbValueMax :int) ; SDWORD cbValueMax (*pcbValue :pointer-void) ; SDWORD FAR *pcbValue ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLParamData" ((hstmt sql-handle) ; HSTMT hstmt (*prgbValue :pointer-void) ; PTR FAR *prgbValue ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLPutData" ((hstmt sql-handle) ; HSTMT hstmt (rgbValue :pointer-void) ; PTR rgbValue (cbValue :int) ; SDWORD cbValue ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLGetConnectOption" ((hdbc sql-handle) ; HDBC hdbc (fOption :short) ; UWORD fOption (pvParam :pointer-void) ; PTR pvParam ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLSetConnectOption" ((hdbc sql-handle) ; HDBC hdbc (fOption :short) ; UWORD fOption (vParam :int) ; UDWORD vParam ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLSetPos" ((hstmt sql-handle) ; HSTMT hstmt (irow :short) ; UWORD irow (fOption :short) ; UWORD fOption (fLock :short) ; UWORD fLock ) :module "odbc" :returning :short) ; RETCODE_SQL_API ; level 2 (def-function "SQLExtendedFetch" ((hstmt sql-handle) ; HSTMT hstmt (fFetchType :short) ; UWORD fFetchType (irow :int) ; SDWORD irow (*pcrow :pointer-void) ; UDWORD FAR *pcrow (*rgfRowStatus :pointer-void) ; UWORD FAR *rgfRowStatus ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLDataSources" ((henv sql-handle) ; HENV henv (fDirection :short) (*szDSN string-ptr) ; UCHAR FAR *szDSN (cbDSNMax :short) ; SWORD cbDSNMax (*pcbDSN (* :short)) ; SWORD *pcbDSN (*szDescription string-ptr) ; UCHAR *szDescription (cbDescriptionMax :short) ; SWORD cbDescriptionMax (*pcbDescription (* :short)) ; SWORD *pcbDescription ) :module "odbc" :returning :short) ; RETCODE_SQL_API (def-function "SQLFreeEnv" ((henv sql-handle) ; HSTMT hstmt ) :module "odbc" :returning :short) ; RETCODE_SQL_API ;;; foreign type definitions ;;(defmacro %sql-len-data-at-exec (length) ;; `(- $SQL_LEN_DATA_AT_EXEC_OFFSET ,length)) (def-struct sql-c-time (hour :short) (minute :short) (second :short)) (def-struct sql-c-date (year :short) (month :short) (day :short)) (def-struct sql-c-timestamp (year :short) (month :short) (day :short) (hour :short) (minute :short) (second :short) (fraction :int)) ;;; Added by KMR (def-function "SQLSetEnvAttr" ((henv sql-handle) ; HENV henv (attr :int) (*value :pointer-void) (szLength :int)) :module "odbc" :returning :short) (def-function "SQLGetEnvAttr" ((henv sql-handle) ; HENV henv (attr :int) (*value :pointer-void) (szLength :int) (string-length-ptr (* :int))) :module "odbc" :returning :short) (def-function "SQLTables" ((hstmt :pointer-void) (catalog-name :pointer-void) (catalog-name-length :short) (schema-name :pointer-void) (schema-name-length :short) (table-name :pointer-void) (table-name-length :short) (table-type-name :pointer-void) (table-type-name-length :short)) :module "odbc" :returning :short) (def-function "SQLStatistics" ((hstmt :pointer-void) (catalog-name :pointer-void) (catalog-name-length :short) (schema-name :pointer-void) (schema-name-length :short) (table-name :cstring) (table-name-length :short) (unique :short) (reserved :short)) :module "odbc" :returning :short) cl-sql-6.7.2/db-odbc/odbc-constants.lisp0000644000175000017500000011621411610324732017043 0ustar kevinkevin ;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Package: odbc -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-constants.lisp ;;;; Purpose: Constants for UFFI interface to ODBC ;;;; Authors: Kevin M. Rosenberg and Paul Meurer ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg ;;;; and Copyright (C) Paul Meurer 1999 - 2001. All rights reserved. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:odbc) ;; on SuSE AMD64 9.0, unixODBC is compiled with with SQLLEN being 4 bytes long (defconstant $ODBC-LONG-TYPE :int) (defconstant $ODBC-ULONG-TYPE :unsigned-int) (defconstant $ODBC-BIG-TYPE :long-long) ;; (defconstant $ODBCVER #x0210) ;; for new SQLAllocHandle functiion (defconstant $SQL_HANDLE_ENV 1) (defconstant $SQL_HANDLE_DBC 2) (defconstant $SQL_HANDLE_STMT 3) (defconstant $SQL_HANDLE_DESC 4) ;; generally useful constants (defconstant $SQL_SPEC_MAJOR 2) ;; Major version of specification (defconstant $SQL_SPEC_MINOR 10) ;; Minor version of specification (defvar $SQL_SPEC_STRING "02.10") ;; String constant for version (defconstant $SQL_SQLSTATE_SIZE 5) ;; size of SQLSTATE (defconstant $SQL_MAX_MESSAGE_LENGTH 512) ;; message buffer size (defconstant $SQL_MAX_DSN_LENGTH 32) ;; maximum data source name size ;; RETCODEs (defconstant $SQL_INVALID_HANDLE -2) (defconstant $SQL_ERROR -1) (defconstant $SQL_SUCCESS 0) (defconstant $SQL_SUCCESS_WITH_INFO 1) (defconstant $SQL_NO_DATA_FOUND 100) ;; Standard SQL datatypes, using ANSI type numbering (defconstant $SQL_CHAR 1) (defconstant $SQL_NUMERIC 2) (defconstant $SQL_DECIMAL 3) (defconstant $SQL_INTEGER 4) (defconstant $SQL_SMALLINT 5) (defconstant $SQL_FLOAT 6) (defconstant $SQL_REAL 7) (defconstant $SQL_DOUBLE 8) (defconstant $SQL_VARCHAR 12) (defconstant $SQL_TYPE_MIN $SQL_CHAR) (defconstant $SQL_TYPE_NULL 0) (defconstant $SQL_TYPE_MAX $SQL_VARCHAR) ;; C datatype to SQL datatype mapping SQL types (defconstant $SQL_C_CHAR $SQL_CHAR) ;; CHAR, VARCHAR, DECIMAL, NUMERIC (defconstant $SQL_C_LONG $SQL_INTEGER) ;; INTEGER (defconstant $SQL_C_SHORT $SQL_SMALLINT) ;; SMALLINT (defconstant $SQL_C_FLOAT $SQL_REAL) ;; REAL (defconstant $SQL_C_DOUBLE $SQL_DOUBLE) ;; FLOAT, DOUBLE (defconstant $SQL_C_DEFAULT 99) ;; NULL status constants. These are used in SQLColumns, SQLColAttributes, ;;SQLDescribeCol, SQLDescribeParam, and SQLSpecialColumns to describe the ;;nullablity of a column in a table. (defconstant $SQL_NO_NULLS 0) (defconstant $SQL_NULLABLE 1) (defconstant $SQL_NULLABLE_UNKNOWN 2) ;; Special length values (defconstant $SQL_NULL_DATA -1) (defconstant $SQL_DATA_AT_EXEC -2) (defconstant $SQL_NTS -3) ;; SQLFreeStmt defines (defconstant $SQL_CLOSE 0) (defconstant $SQL_DROP 1) (defconstant $SQL_UNBIND 2) (defconstant $SQL_RESET_PARAMS 3) ;; SQLTransact defines (defconstant $SQL_COMMIT 0) (defconstant $SQL_ROLLBACK 1) ;; SQLColAttributes defines (defconstant $SQL_COLUMN_COUNT 0) (defconstant $SQL_COLUMN_NAME 1) (defconstant $SQL_COLUMN_TYPE 2) (defconstant $SQL_COLUMN_LENGTH 3) (defconstant $SQL_COLUMN_PRECISION 4) (defconstant $SQL_COLUMN_SCALE 5) (defconstant $SQL_COLUMN_DISPLAY_SIZE 6) (defconstant $SQL_COLUMN_NULLABLE 7) (defconstant $SQL_COLUMN_UNSIGNED 8) (defconstant $SQL_COLUMN_MONEY 9) (defconstant $SQL_COLUMN_UPDATABLE 10) (defconstant $SQL_COLUMN_AUTO_INCREMENT 11) (defconstant $SQL_COLUMN_CASE_SENSITIVE 12) (defconstant $SQL_COLUMN_SEARCHABLE 13) (defconstant $SQL_COLUMN_TYPE_NAME 14) (defconstant $SQL_COLUMN_TABLE_NAME 15) (defconstant $SQL_COLUMN_OWNER_NAME 16) (defconstant $SQL_COLUMN_QUALIFIER_NAME 17) (defconstant $SQL_COLUMN_LABEL 18) (defconstant $SQL_COLATT_OPT_MAX $SQL_COLUMN_LABEL) (defconstant $SQL_COLUMN_DRIVER_START 1000) (defconstant $SQL_COLATT_OPT_MIN $SQL_COLUMN_COUNT) ;; SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE (defconstant $SQL_ATTR_READONLY 0) (defconstant $SQL_ATTR_WRITE 1) (defconstant $SQL_ATTR_READWRITE_UNKNOWN 2) ;; SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE ;; These are also used by SQLGetInfo (defconstant $SQL_UNSEARCHABLE 0) (defconstant $SQL_LIKE_ONLY 1) (defconstant $SQL_ALL_EXCEPT_LIKE 2) (defconstant $SQL_SEARCHABLE 3) ;; SQLError defines (defconstant $SQL_NULL_HENV 0) (defconstant $SQL_NULL_HDBC 0) (defconstant $SQL_NULL_HSTMT 0) ;; Defines for SQLGetFunctions ;; Core Functions ;; (defconstant $SQL_API_SQLALLOCCONNECT 1) (defconstant $SQL_API_SQLALLOCENV 2) (defconstant $SQL_API_SQLALLOCSTMT 3) (defconstant $SQL_API_SQLBINDCOL 4) (defconstant $SQL_API_SQLCANCEL 5) (defconstant $SQL_API_SQLCOLATTRIBUTES 6) (defconstant $SQL_API_SQLCONNECT 7) (defconstant $SQL_API_SQLDESCRIBECOL 8) (defconstant $SQL_API_SQLDISCONNECT 9) (defconstant $SQL_API_SQLERROR 10) (defconstant $SQL_API_SQLEXECDIRECT 11) (defconstant $SQL_API_SQLEXECUTE 12) (defconstant $SQL_API_SQLFETCH 13) (defconstant $SQL_API_SQLFREECONNECT 14) (defconstant $SQL_API_SQLFREEENV 15) (defconstant $SQL_API_SQLFREESTMT 16) (defconstant $SQL_API_SQLGETCURSORNAME 17) (defconstant $SQL_API_SQLNUMRESULTCOLS 18) (defconstant $SQL_API_SQLPREPARE 19) (defconstant $SQL_API_SQLROWCOUNT 20) (defconstant $SQL_API_SQLSETCURSORNAME 21) (defconstant $SQL_API_SQLSETPARAM 22) (defconstant $SQL_API_SQLTRANSACT 23) (defconstant $SQL_NUM_FUNCTIONS 23) (defconstant $SQL_EXT_API_START 40) ;; Level 1 Functions (defconstant $SQL_API_SQLCOLUMNS 40) (defconstant $SQL_API_SQLDRIVERCONNECT 41) (defconstant $SQL_API_SQLGETCONNECTOPTION 42) (defconstant $SQL_API_SQLGETDATA 43) (defconstant $SQL_API_SQLGETFUNCTIONS 44) (defconstant $SQL_API_SQLGETINFO 45) (defconstant $SQL_API_SQLGETSTMTOPTION 46) (defconstant $SQL_API_SQLGETTYPEINFO 47) (defconstant $SQL_API_SQLPARAMDATA 48) (defconstant $SQL_API_SQLPUTDATA 49) (defconstant $SQL_API_SQLSETCONNECTOPTION 50) (defconstant $SQL_API_SQLSETSTMTOPTION 51) (defconstant $SQL_API_SQLSPECIALCOLUMNS 52) (defconstant $SQL_API_SQLSTATISTICS 53) (defconstant $SQL_API_SQLTABLES 54) ;; Level 2 Functions (defconstant $SQL_API_SQLBROWSECONNECT 55) (defconstant $SQL_API_SQLCOLUMNPRIVILEGES 56) (defconstant $SQL_API_SQLDATASOURCES 57) (defconstant $SQL_API_SQLDESCRIBEPARAM 58) (defconstant $SQL_API_SQLEXTENDEDFETCH 59) (defconstant $SQL_API_SQLFOREIGNKEYS 60) (defconstant $SQL_API_SQLMORERESULTS 61) (defconstant $SQL_API_SQLNATIVESQL 62) (defconstant $SQL_API_SQLNUMPARAMS 63) (defconstant $SQL_API_SQLPARAMOPTIONS 64) (defconstant $SQL_API_SQLPRIMARYKEYS 65) (defconstant $SQL_API_SQLPROCEDURECOLUMNS 66) (defconstant $SQL_API_SQLPROCEDURES 67) (defconstant $SQL_API_SQLSETPOS 68) (defconstant $SQL_API_SQLSETSCROLLOPTIONS 69) (defconstant $SQL_API_SQLTABLEPRIVILEGES 70) ;/* SDK 2.0 Additions */ (defconstant $SQL_API_SQLDRIVERS 71) (defconstant $SQL_API_SQLBINDPARAMETER 72) (defconstant $SQL_EXT_API_LAST $SQL_API_SQLBINDPARAMETER) (defconstant $SQL_API_ALL_FUNCTIONS 0) (defconstant $SQL_NUM_EXTENSIONS (- $SQL_EXT_API_LAST $SQL_EXT_API_START -1)) (defconstant $SQL_API_LOADBYORDINAL 199) ;;; Defines for SQLGetInfo (defconstant $SQL_INFO_FIRST 0) (defconstant $SQL_ACTIVE_CONNECTIONS 0) (defconstant $SQL_ACTIVE_STATEMENTS 1) (defconstant $SQL_DATA_SOURCE_NAME 2) (defconstant $SQL_DRIVER_HDBC 3) (defconstant $SQL_DRIVER_HENV 4) (defconstant $SQL_DRIVER_HSTMT 5) (defconstant $SQL_DRIVER_NAME 6) (defconstant $SQL_DRIVER_VER 7) (defconstant $SQL_FETCH_DIRECTION 8) (defconstant $SQL_ODBC_API_CONFORMANCE 9) (defconstant $SQL_ODBC_VER 10) (defconstant $SQL_ROW_UPDATES 11) (defconstant $SQL_ODBC_SAG_CLI_CONFORMANCE 12) (defconstant $SQL_SERVER_NAME 13) (defconstant $SQL_SEARCH_PATTERN_ESCAPE 14) (defconstant $SQL_ODBC_SQL_CONFORMANCE 15) (defconstant $SQL_DBMS_NAME 17) (defconstant $SQL_DBMS_VER 18) (defconstant $SQL_ACCESSIBLE_TABLES 19) (defconstant $SQL_ACCESSIBLE_PROCEDURES 20) (defconstant $SQL_PROCEDURES 21) (defconstant $SQL_CONCAT_NULL_BEHAVIOR 22) (defconstant $SQL_CURSOR_COMMIT_BEHAVIOR 23) (defconstant $SQL_CURSOR_ROLLBACK_BEHAVIOR 24) (defconstant $SQL_DATA_SOURCE_READ_ONLY 25) (defconstant $SQL_DEFAULT_TXN_ISOLATION 26) (defconstant $SQL_EXPRESSIONS_IN_ORDERBY 27) (defconstant $SQL_IDENTIFIER_CASE 28) (defconstant $SQL_IDENTIFIER_QUOTE_CHAR 29) (defconstant $SQL_MAX_COLUMN_NAME_LEN 30) (defconstant $SQL_MAX_CURSOR_NAME_LEN 31) (defconstant $SQL_MAX_OWNER_NAME_LEN 32) (defconstant $SQL_MAX_PROCEDURE_NAME_LEN 33) (defconstant $SQL_MAX_QUALIFIER_NAME_LEN 34) (defconstant $SQL_MAX_TABLE_NAME_LEN 35) (defconstant $SQL_MULT_RESULT_SETS 36) (defconstant $SQL_MULTIPLE_ACTIVE_TXN 37) (defconstant $SQL_OUTER_JOINS 38) (defconstant $SQL_OWNER_TERM 39) (defconstant $SQL_PROCEDURE_TERM 40) (defconstant $SQL_QUALIFIER_NAME_SEPARATOR 41) (defconstant $SQL_QUALIFIER_TERM 42) (defconstant $SQL_SCROLL_CONCURRENCY 43) (defconstant $SQL_SCROLL_OPTIONS 44) (defconstant $SQL_TABLE_TERM 45) (defconstant $SQL_TXN_CAPABLE 46) (defconstant $SQL_USER_NAME 47) (defconstant $SQL_CONVERT_FUNCTIONS 48) (defconstant $SQL_NUMERIC_FUNCTIONS 49) (defconstant $SQL_STRING_FUNCTIONS 50) (defconstant $SQL_SYSTEM_FUNCTIONS 51) (defconstant $SQL_TIMEDATE_FUNCTIONS 52) (defconstant $SQL_CONVERT_BIGINT 53) (defconstant $SQL_CONVERT_BINARY 54) (defconstant $SQL_CONVERT_BIT 55) (defconstant $SQL_CONVERT_CHAR 56) (defconstant $SQL_CONVERT_DATE 57) (defconstant $SQL_CONVERT_DECIMAL 58) (defconstant $SQL_CONVERT_DOUBLE 59) (defconstant $SQL_CONVERT_FLOAT 60) (defconstant $SQL_CONVERT_INTEGER 61) (defconstant $SQL_CONVERT_LONGVARCHAR 62) (defconstant $SQL_CONVERT_NUMERIC 63) (defconstant $SQL_CONVERT_REAL 64) (defconstant $SQL_CONVERT_SMALLINT 65) (defconstant $SQL_CONVERT_TIME 66) (defconstant $SQL_CONVERT_TIMESTAMP 67) (defconstant $SQL_CONVERT_TINYINT 68) (defconstant $SQL_CONVERT_VARBINARY 69) (defconstant $SQL_CONVERT_VARCHAR 70) (defconstant $SQL_CONVERT_LONGVARBINARY 71) (defconstant $SQL_TXN_ISOLATION_OPTION 72) (defconstant $SQL_ODBC_SQL_OPT_IEF 73) ;;; ODBC SDK 1.0 Additions (defconstant $SQL_CORRELATION_NAME 74) (defconstant $SQL_NON_NULLABLE_COLUMNS 75) ;;; ODBC SDK 2.0 Additions (defconstant $SQL_DRIVER_HLIB 76) (defconstant $SQL_DRIVER_ODBC_VER 77) (defconstant $SQL_LOCK_TYPES 78) (defconstant $SQL_POS_OPERATIONS 79) (defconstant $SQL_POSITIONED_STATEMENTS 80) (defconstant $SQL_GETDATA_EXTENSIONS 81) (defconstant $SQL_BOOKMARK_PERSISTENCE 82) (defconstant $SQL_STATIC_SENSITIVITY 83) (defconstant $SQL_FILE_USAGE 84) (defconstant $SQL_NULL_COLLATION 85) (defconstant $SQL_ALTER_TABLE 86) (defconstant $SQL_COLUMN_ALIAS 87) (defconstant $SQL_GROUP_BY 88) (defconstant $SQL_KEYWORDS 89) (defconstant $SQL_ORDER_BY_COLUMNS_IN_SELECT 90) (defconstant $SQL_OWNER_USAGE 91) (defconstant $SQL_QUALIFIER_USAGE 92) (defconstant $SQL_QUOTED_IDENTIFIER_CASE 93) (defconstant $SQL_SPECIAL_CHARACTERS 94) (defconstant $SQL_SUBQUERIES 95) (defconstant $SQL_UNION 96) (defconstant $SQL_MAX_COLUMNS_IN_GROUP_BY 97) (defconstant $SQL_MAX_COLUMNS_IN_INDEX 98) (defconstant $SQL_MAX_COLUMNS_IN_ORDER_BY 99) (defconstant $SQL_MAX_COLUMNS_IN_SELECT 100) (defconstant $SQL_MAX_COLUMNS_IN_TABLE 101) (defconstant $SQL_MAX_INDEX_SIZE 102) (defconstant $SQL_MAX_ROW_SIZE_INCLUDES_LONG 103) (defconstant $SQL_MAX_ROW_SIZE 104) (defconstant $SQL_MAX_STATEMENT_LEN 105) (defconstant $SQL_MAX_TABLES_IN_SELECT 106) (defconstant $SQL_MAX_USER_NAME_LEN 107) (defconstant $SQL_MAX_CHAR_LITERAL_LEN 108) (defconstant $SQL_TIMEDATE_ADD_INTERVALS 109) (defconstant $SQL_TIMEDATE_DIFF_INTERVALS 110) (defconstant $SQL_NEED_LONG_DATA_LEN 111) (defconstant $SQL_MAX_BINARY_LITERAL_LEN 112) (defconstant $SQL_LIKE_ESCAPE_CLAUSE 113) (defconstant $SQL_QUALIFIER_LOCATION 114) (defconstant $SQL_ACTIVE_ENVIRONMENTS 116) #| /*** ODBC SDK 2.01 Additions ***/) (defconstant $SQL_OJ_CAPABILITIES 65003 ;; Temp value until ODBC 3.0 (defconstant $SQL_INFO_LAST SQL_QUALIFIER_LOCATION ) (defconstant $SQL_INFO_DRIVER_START 1000 ;; SQL_CONVERT_* return value bitmasks ) (defconstant $SQL_CVT_CHAR #x00000001L) (defconstant $SQL_CVT_NUMERIC #x00000002L) (defconstant $SQL_CVT_DECIMAL #x00000004L) (defconstant $SQL_CVT_INTEGER #x00000008L) (defconstant $SQL_CVT_SMALLINT #x00000010L) (defconstant $SQL_CVT_FLOAT #x00000020L) (defconstant $SQL_CVT_REAL #x00000040L) (defconstant $SQL_CVT_DOUBLE #x00000080L) (defconstant $SQL_CVT_VARCHAR #x00000100L) (defconstant $SQL_CVT_LONGVARCHAR #x00000200L) (defconstant $SQL_CVT_BINARY #x00000400L) (defconstant $SQL_CVT_VARBINARY #x00000800L) (defconstant $SQL_CVT_BIT #x00001000L) (defconstant $SQL_CVT_TINYINT #x00002000L) (defconstant $SQL_CVT_BIGINT #x00004000L) (defconstant $SQL_CVT_DATE #x00008000L) (defconstant $SQL_CVT_TIME #x00010000L) (defconstant $SQL_CVT_TIMESTAMP #x00020000L) (defconstant $SQL_CVT_LONGVARBINARY #x00040000L) ;; SQL_CONVERT_FUNCTIONS functions) (defconstant $SQL_FN_CVT_CONVERT #x00000001L) ;; SQL_STRING_FUNCTIONS functions (defconstant $SQL_FN_STR_CONCAT #x00000001L) (defconstant $SQL_FN_STR_INSERT #x00000002L) (defconstant $SQL_FN_STR_LEFT #x00000004L) (defconstant $SQL_FN_STR_LTRIM #x00000008L) (defconstant $SQL_FN_STR_LENGTH #x00000010L) (defconstant $SQL_FN_STR_LOCATE #x00000020L) (defconstant $SQL_FN_STR_LCASE #x00000040L) (defconstant $SQL_FN_STR_REPEAT #x00000080L) (defconstant $SQL_FN_STR_REPLACE #x00000100L) (defconstant $SQL_FN_STR_RIGHT #x00000200L) (defconstant $SQL_FN_STR_RTRIM #x00000400L) (defconstant $SQL_FN_STR_SUBSTRING #x00000800L) (defconstant $SQL_FN_STR_UCASE #x00001000L) (defconstant $SQL_FN_STR_ASCII #x00002000L) (defconstant $SQL_FN_STR_CHAR #x00004000L (defconstant $SQL_FN_STR_DIFFERENCE #x00008000L) (defconstant $SQL_FN_STR_LOCATE_2 #x00010000L) (defconstant $SQL_FN_STR_SOUNDEX #x00020000L) (defconstant $SQL_FN_STR_SPACE #x00040000L ;; SQL_NUMERIC_FUNCTIONS functions ) (defconstant $SQL_FN_NUM_ABS #x00000001L) (defconstant $SQL_FN_NUM_ACOS #x00000002L) (defconstant $SQL_FN_NUM_ASIN #x00000004L) (defconstant $SQL_FN_NUM_ATAN #x00000008L) (defconstant $SQL_FN_NUM_ATAN2 #x00000010L) (defconstant $SQL_FN_NUM_CEILING #x00000020L) (defconstant $SQL_FN_NUM_COS #x00000040L) (defconstant $SQL_FN_NUM_COT #x00000080L) (defconstant $SQL_FN_NUM_EXP #x00000100L) (defconstant $SQL_FN_NUM_FLOOR #x00000200L) (defconstant $SQL_FN_NUM_LOG #x00000400L) (defconstant $SQL_FN_NUM_MOD #x00000800L) (defconstant $SQL_FN_NUM_SIGN #x00001000L) (defconstant $SQL_FN_NUM_SIN #x00002000L) (defconstant $SQL_FN_NUM_SQRT #x00004000L) (defconstant $SQL_FN_NUM_TAN #x00008000L) (defconstant $SQL_FN_NUM_PI #x00010000L) (defconstant $SQL_FN_NUM_RAND #x00020000L (defconstant $SQL_FN_NUM_DEGREES #x00040000L) (defconstant $SQL_FN_NUM_LOG10 #x00080000L) (defconstant $SQL_FN_NUM_POWER #x00100000L) (defconstant $SQL_FN_NUM_RADIANS #x00200000L) (defconstant $SQL_FN_NUM_ROUND #x00400000L) (defconstant $SQL_FN_NUM_TRUNCATE #x00800000L ;; SQL_TIMEDATE_FUNCTIONS functions ) (defconstant $SQL_FN_TD_NOW #x00000001L) (defconstant $SQL_FN_TD_CURDATE #x00000002L) (defconstant $SQL_FN_TD_DAYOFMONTH #x00000004L) (defconstant $SQL_FN_TD_DAYOFWEEK #x00000008L) (defconstant $SQL_FN_TD_DAYOFYEAR #x00000010L) (defconstant $SQL_FN_TD_MONTH #x00000020L) (defconstant $SQL_FN_TD_QUARTER #x00000040L) (defconstant $SQL_FN_TD_WEEK #x00000080L) (defconstant $SQL_FN_TD_YEAR #x00000100L) (defconstant $SQL_FN_TD_CURTIME #x00000200L) (defconstant $SQL_FN_TD_HOUR #x00000400L) (defconstant $SQL_FN_TD_MINUTE #x00000800L) (defconstant $SQL_FN_TD_SECOND #x00001000L (defconstant $SQL_FN_TD_TIMESTAMPADD #x00002000L) (defconstant $SQL_FN_TD_TIMESTAMPDIFF #x00004000L) (defconstant $SQL_FN_TD_DAYNAME #x00008000L) (defconstant $SQL_FN_TD_MONTHNAME #x00010000L ;; SQL_SYSTEM_FUNCTIONS functions ) (defconstant $SQL_FN_SYS_USERNAME #x00000001L) (defconstant $SQL_FN_SYS_DBNAME #x00000002L) (defconstant $SQL_FN_SYS_IFNULL #x00000004L ;; SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions (defconstant $SQL_FN_TSI_FRAC_SECOND #x00000001L) (defconstant $SQL_FN_TSI_SECOND #x00000002L) (defconstant $SQL_FN_TSI_MINUTE #x00000004L) (defconstant $SQL_FN_TSI_HOUR #x00000008L) (defconstant $SQL_FN_TSI_DAY #x00000010L) (defconstant $SQL_FN_TSI_WEEK #x00000020L) (defconstant $SQL_FN_TSI_MONTH #x00000040L) (defconstant $SQL_FN_TSI_QUARTER #x00000080L) (defconstant $SQL_FN_TSI_YEAR #x00000100L ;; SQL_ODBC_API_CONFORMANCE values ) (defconstant $SQL_OAC_NONE #x0000) (defconstant $SQL_OAC_LEVEL1 #x0001) (defconstant $SQL_OAC_LEVEL2 #x0002 ;; SQL_ODBC_SAG_CLI_CONFORMANCE values ) (defconstant $SQL_OSCC_NOT_COMPLIANT #x0000) (defconstant $SQL_OSCC_COMPLIANT #x0001 ;; SQL_ODBC_SQL_CONFORMANCE values ) (defconstant $SQL_OSC_MINIMUM #x0000) (defconstant $SQL_OSC_CORE #x0001) (defconstant $SQL_OSC_EXTENDED #x0002 ;; SQL_CONCAT_NULL_BEHAVIOR values ) (defconstant $SQL_CB_NULL #x0000) (defconstant $SQL_CB_NON_NULL #x0001 ;; SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values ) (defconstant $SQL_CB_DELETE #x0000) (defconstant $SQL_CB_CLOSE #x0001) (defconstant $SQL_CB_PRESERVE #x0002 ;; SQL_IDENTIFIER_CASE values ) (defconstant $SQL_IC_UPPER #x0001) (defconstant $SQL_IC_LOWER #x0002) (defconstant $SQL_IC_SENSITIVE #x0003) (defconstant $SQL_IC_MIXED #x0004 ;; SQL_TXN_CAPABLE values |# (defconstant $SQL_TC_NONE 0) (defconstant $SQL_TC_DML 1) (defconstant $SQL_TC_ALL 2) (defconstant $SQL_TC_DDL_COMMIT 3) (defconstant $SQL_TC_DDL_IGNORE 4) ;; SQL_SCROLL_OPTIONS masks (defconstant $SQL_SO_FORWARD_ONLY #x00000001) (defconstant $SQL_SO_KEYSET_DRIVEN #x00000002) (defconstant $SQL_SO_DYNAMIC #x00000004) (defconstant $SQL_SO_MIXED #x00000008) (defconstant $SQL_SO_STATIC #x00000010) ;; SQL_SCROLL_CONCURRENCY masks (defconstant $SQL_SCCO_READ_ONLY #x00000001) (defconstant $SQL_SCCO_LOCK #x00000002) (defconstant $SQL_SCCO_OPT_ROWVER #x00000004) (defconstant $SQL_SCCO_OPT_VALUES #x00000008) ;; SQL_FETCH_DIRECTION masks (defconstant $SQL_FD_FETCH_NEXT #x00000001) (defconstant $SQL_FD_FETCH_FIRST #x00000002) (defconstant $SQL_FD_FETCH_LAST #x00000004) (defconstant $SQL_FD_FETCH_PRIOR #x00000008) (defconstant $SQL_FD_FETCH_ABSOLUTE #x00000010) (defconstant $SQL_FD_FETCH_RELATIVE #x00000020) (defconstant $SQL_FD_FETCH_RESUME #x00000040) (defconstant $SQL_FD_FETCH_BOOKMARK #x00000080) #| ;; SQL_TXN_ISOLATION_OPTION masks ) (defconstant $SQL_TXN_READ_UNCOMMITTED #x00000001L) (defconstant $SQL_TXN_READ_COMMITTED #x00000002L) (defconstant $SQL_TXN_REPEATABLE_READ #x00000004L) (defconstant $SQL_TXN_SERIALIZABLE #x00000008L) (defconstant $SQL_TXN_VERSIONING #x00000010L ;; SQL_CORRELATION_NAME values ) (defconstant $SQL_CN_NONE #x0000) (defconstant $SQL_CN_DIFFERENT #x0001) (defconstant $SQL_CN_ANY #x0002 ;; SQL_NON_NULLABLE_COLUMNS values ) (defconstant $SQL_NNC_NULL #x0000) (defconstant $SQL_NNC_NON_NULL #x0001 ;; SQL_NULL_COLLATION values ) (defconstant $SQL_NC_HIGH #x0000) (defconstant $SQL_NC_LOW #x0001) (defconstant $SQL_NC_START #x0002) (defconstant $SQL_NC_END #x0004 ;; SQL_FILE_USAGE values ) (defconstant $SQL_FILE_NOT_SUPPORTED #x0000) (defconstant $SQL_FILE_TABLE #x0001) (defconstant $SQL_FILE_QUALIFIER #x0002 ;; SQL_GETDATA_EXTENSIONS values ) (defconstant $SQL_GD_ANY_COLUMN #x00000001L) (defconstant $SQL_GD_ANY_ORDER #x00000002L) (defconstant $SQL_GD_BLOCK #x00000004L) (defconstant $SQL_GD_BOUND #x00000008L ;; SQL_ALTER_TABLE values ) (defconstant $SQL_AT_ADD_COLUMN #x00000001L) (defconstant $SQL_AT_DROP_COLUMN #x00000002L ;; SQL_POSITIONED_STATEMENTS masks ) (defconstant $SQL_PS_POSITIONED_DELETE #x00000001L) (defconstant $SQL_PS_POSITIONED_UPDATE #x00000002L) (defconstant $SQL_PS_SELECT_FOR_UPDATE #x00000004L ;; SQL_GROUP_BY values ) (defconstant $SQL_GB_NOT_SUPPORTED #x0000) (defconstant $SQL_GB_GROUP_BY_EQUALS_SELECT #x0001) (defconstant $SQL_GB_GROUP_BY_CONTAINS_SELECT #x0002) (defconstant $SQL_GB_NO_RELATION #x0003 ;; SQL_OWNER_USAGE masks ) (defconstant $SQL_OU_DML_STATEMENTS #x00000001L) (defconstant $SQL_OU_PROCEDURE_INVOCATION #x00000002L) (defconstant $SQL_OU_TABLE_DEFINITION #x00000004L) (defconstant $SQL_OU_INDEX_DEFINITION #x00000008L) (defconstant $SQL_OU_PRIVILEGE_DEFINITION #x00000010L ;; SQL_QUALIFIER_USAGE masks ) (defconstant $SQL_QU_DML_STATEMENTS #x00000001L) (defconstant $SQL_QU_PROCEDURE_INVOCATION #x00000002L) (defconstant $SQL_QU_TABLE_DEFINITION #x00000004L) (defconstant $SQL_QU_INDEX_DEFINITION #x00000008L) (defconstant $SQL_QU_PRIVILEGE_DEFINITION #x00000010L ;; SQL_SUBQUERIES masks ) (defconstant $SQL_SQ_COMPARISON #x00000001L) (defconstant $SQL_SQ_EXISTS #x00000002L) (defconstant $SQL_SQ_IN #x00000004L) (defconstant $SQL_SQ_QUANTIFIED #x00000008L) (defconstant $SQL_SQ_CORRELATED_SUBQUERIES #x00000010L ;; SQL_UNION masks ) (defconstant $SQL_U_UNION #x00000001L) (defconstant $SQL_U_UNION_ALL #x00000002L ;; SQL_BOOKMARK_PERSISTENCE values ) (defconstant $SQL_BP_CLOSE #x00000001L) (defconstant $SQL_BP_DELETE #x00000002L) (defconstant $SQL_BP_DROP #x00000004L) (defconstant $SQL_BP_TRANSACTION #x00000008L) (defconstant $SQL_BP_UPDATE #x00000010L) (defconstant $SQL_BP_OTHER_HSTMT #x00000020L) (defconstant $SQL_BP_SCROLL #x00000040L ;; SQL_STATIC_SENSITIVITY values ) (defconstant $SQL_SS_ADDITIONS #x00000001L) (defconstant $SQL_SS_DELETIONS #x00000002L) (defconstant $SQL_SS_UPDATES #x00000004L ;; SQL_LOCK_TYPESL masks ) (defconstant $SQL_LCK_NO_CHANGE #x00000001L) (defconstant $SQL_LCK_EXCLUSIVE #x00000002L) (defconstant $SQL_LCK_UNLOCK #x00000004L ;; SQL_POS_OPERATIONS masks |# (defconstant $SQL_POS_POSITION 1) ;; #x00000001L (defconstant $SQL_POS_REFRESH 2) ;; #x00000002L (defconstant $SQL_POS_UPDATE 4) ;; #x00000004L (defconstant $SQL_POS_DELETE 8) ;; #x00000008L (defconstant $SQL_POS_ADD 16) ;; #x00000010L #| ;; SQL_QUALIFIER_LOCATION values ) (defconstant $SQL_QL_START #x0001L) (defconstant $SQL_QL_END #x0002L ;; SQL_OJ_CAPABILITIES values (defconstant $SQL_OJ_LEFT #x00000001L) (defconstant $SQL_OJ_RIGHT #x00000002L) (defconstant $SQL_OJ_FULL #x00000004L) (defconstant $SQL_OJ_NESTED #x00000008L) (defconstant $SQL_OJ_NOT_ORDERED #x00000010L) (defconstant $SQL_OJ_INNER #x00000020L) (defconstant $SQL_OJ_ALL_COMPARISON_OPS #x00000040L ;; options for SQLGetStmtOption/SQLSetStmtOption) (defconstant $SQL_QUERY_TIMEOUT 0) (defconstant $SQL_MAX_ROWS 1) (defconstant $SQL_NOSCAN 2) (defconstant $SQL_MAX_LENGTH 3) (defconstant $SQL_ASYNC_ENABLE 4) (defconstant $SQL_BIND_TYPE 5 (defconstant $SQL_CURSOR_TYPE 6) (defconstant $SQL_CONCURRENCY 7) (defconstant $SQL_KEYSET_SIZE 8) (defconstant $SQL_ROWSET_SIZE 9) (defconstant $SQL_SIMULATE_CURSOR 10) (defconstant $SQL_RETRIEVE_DATA 11) (defconstant $SQL_USE_BOOKMARKS 12) (defconstant $SQL_GET_BOOKMARK 13 /* GetStmtOption Only) (defconstant $SQL_ROW_NUMBER 14 /* GetStmtOption Only) (defconstant $SQL_STMT_OPT_MAX SQL_ROW_NUMBER ) (defconstant $SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT ;; SQL_QUERY_TIMEOUT options) (defconstant $SQL_QUERY_TIMEOUT_DEFAULT 0UL ;; SQL_MAX_ROWS options) (defconstant $SQL_MAX_ROWS_DEFAULT 0UL ;; SQL_NOSCAN options) (defconstant $SQL_NOSCAN_OFF 0UL /* 1.0 FALSE) (defconstant $SQL_NOSCAN_ON 1UL /* 1.0 TRUE) (defconstant $SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF ;; SQL_MAX_LENGTH options) (defconstant $SQL_MAX_LENGTH_DEFAULT 0UL ;; SQL_ASYNC_ENABLE options) (defconstant $SQL_ASYNC_ENABLE_OFF 0UL) (defconstant $SQL_ASYNC_ENABLE_ON 1UL) (defconstant $SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF ;; SQL_BIND_TYPE options) (defconstant $SQL_BIND_BY_COLUMN 0UL) (defconstant $SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN ;; Default value ;; SQL_CONCURRENCY options) (defconstant $SQL_CONCUR_READ_ONLY 1) (defconstant $SQL_CONCUR_LOCK 2) (defconstant $SQL_CONCUR_ROWVER 3) (defconstant $SQL_CONCUR_VALUES 4) (defconstant $SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY ;; Default value ;; SQL_CURSOR_TYPE options) (defconstant $SQL_CURSOR_FORWARD_ONLY 0UL) (defconstant $SQL_CURSOR_KEYSET_DRIVEN 1UL) (defconstant $SQL_CURSOR_DYNAMIC 2UL) (defconstant $SQL_CURSOR_STATIC 3UL) (defconstant $SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY ;; Default value ;; SQL_ROWSET_SIZE options) (defconstant $SQL_ROWSET_SIZE_DEFAULT 1UL ;; SQL_KEYSET_SIZE options) (defconstant $SQL_KEYSET_SIZE_DEFAULT 0UL ;; SQL_SIMULATE_CURSOR options) (defconstant $SQL_SC_NON_UNIQUE 0UL) (defconstant $SQL_SC_TRY_UNIQUE 1UL) (defconstant $SQL_SC_UNIQUE 2UL ;; SQL_RETRIEVE_DATA options) (defconstant $SQL_RD_OFF 0UL) (defconstant $SQL_RD_ON 1UL) (defconstant $SQL_RD_DEFAULT SQL_RD_ON ;; SQL_USE_BOOKMARKS options) (defconstant $SQL_UB_OFF 0UL) (defconstant $SQL_UB_ON 1UL) (defconstant $SQL_UB_DEFAULT SQL_UB_OFF |# ;; options for SQLSetConnectOption/SQLGetConnectOption) (defconstant $SQL_ACCESS_MODE 101) (defconstant $SQL_AUTOCOMMIT 102) (defconstant $SQL_LOGIN_TIMEOUT 103) (defconstant $SQL_OPT_TRACE 104) (defconstant $SQL_OPT_TRACEFILE 105) (defconstant $SQL_TRANSLATE_DLL 106) (defconstant $SQL_TRANSLATE_OPTION 107) (defconstant $SQL_TXN_ISOLATION 108) (defconstant $SQL_CURRENT_QUALIFIER 109) (defconstant $SQL_ODBC_CURSORS 110) (defconstant $SQL_QUIET_MODE 111) (defconstant $SQL_PACKET_SIZE 112) (defconstant $SQL_CONN_OPT_MAX $SQL_PACKET_SIZE) (defconstant $SQL_CONNECT_OPT_DRVR_START 1000) ;;#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE ;; SQL_ACCESS_MODE options (defconstant $SQL_MODE_READ_WRITE 0) ; 0UL (defconstant $SQL_MODE_READ_ONLY 1) ; 1UL (defconstant $SQL_MODE_DEFAULT $SQL_MODE_READ_WRITE) ;; SQL_AUTOCOMMIT options) (defconstant $SQL_AUTOCOMMIT_OFF 0) ;0UL (defconstant $SQL_AUTOCOMMIT_ON 1) ;1UL (defconstant $SQL_AUTOCOMMIT_DEFAULT $SQL_AUTOCOMMIT_ON) ;; SQL_LOGIN_TIMEOUT options) (defconstant $SQL_LOGIN_TIMEOUT_DEFAULT 15) ; 15UL ;; SQL_OPT_TRACE options) (defconstant $SQL_OPT_TRACE_OFF 0) ; 0UL (defconstant $SQL_OPT_TRACE_ON 1) ; 1UL (defconstant $SQL_OPT_TRACE_DEFAULT $SQL_OPT_TRACE_OFF) ; #ifndef SQL_OPT_TRACE_FILE_DEFAULT ; (defconstant $SQL_OPT_TRACE_FILE_DEFAULT "\\SQL.LOG" ;; #endif (defconstant $SQL_CUR_USE_IF_NEEDED 0) ; 0UL (defconstant $SQL_CUR_USE_ODBC 1) ; 1UL (defconstant $SQL_CUR_USE_DRIVER 2) ; 2UL (defconstant $SQL_CUR_DEFAULT $SQL_CUR_USE_DRIVER) #| ;; Column types and scopes in SQLSpecialColumns. ) (defconstant $SQL_BEST_ROWID 1) (defconstant $SQL_ROWVER 2) ) (defconstant $SQL_SCOPE_CURROW 0) (defconstant $SQL_SCOPE_TRANSACTION 1) (defconstant $SQL_SCOPE_SESSION 2 ;; Defines for SQLSetPos) (defconstant $SQL_ENTIRE_ROWSET 0 |# ;; Operations in SQLSetPos (defconstant $SQL_POSITION 0) ;; 1.0 FALSE (defconstant $SQL_REFRESH 1) ;; 1.0 TRUE (defconstant $SQL_UPDATE 2) (defconstant $SQL_DELETE 3) (defconstant $SQL_ADD 4) ;; Lock options in SQLSetPos) (defconstant $SQL_LOCK_NO_CHANGE 0) ;; 1.0 FALSE (defconstant $SQL_LOCK_EXCLUSIVE 1) ;; 1.0 TRUE (defconstant $SQL_LOCK_UNLOCK 2) ;; SQLBindParameter extensions (defconstant $SQL_DEFAULT_PARAM -5) (defconstant $SQL_IGNORE -6) (defconstant $SQL_LEN_DATA_AT_EXEC_OFFSET -100) ;(defconstant $SQL_LEN_DATA_AT_EXEC(length) (-length+SQL_LEN_DATA_AT_EXEC_OFFSET) ;; Special return values for SQLGetData (defconstant $SQL_NO_TOTAL -4) #| ;; Macros for SQLSetPos) (defconstant $SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE)) (defconstant $SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock)) (defconstant $SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock)) (defconstant $SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE)) (defconstant $SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE)) (defconstant $SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) ; #ifndef RC_INVOKED /* This define is too large for RC) (defconstant $SQL_ODBC_KEYWORDS \ "ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ "ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ "BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ "CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ "COBOL,COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ "CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ "CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ "DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ "DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ "DISTINCT,DOMAIN,DOUBLE,DROP,"\ "ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ "EXISTS,EXTERNAL,EXTRACT,"\ "FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ "GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ "IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ "INPUT,INSENSITIVE,INSERT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ "JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ "MATCH,MAX,MIN,MINUTE,MODULE,MONTH,MUMPS,"\ "NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ "OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ "PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ "PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ "REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS,"\ "SCHEMA,SCROLL,SECOND,SECTION,SELECT,SEQUENCE,SESSION,SESSION_USER,SET,SIZE,"\ "SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ "SUBSTRING,SUM,SYSTEM_USER,"\ "TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ "TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ "UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ "VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,YEAR") |# (defconstant $SQL_PARAM_TYPE_UNKNOWN 0) (defconstant $SQL_PARAM_INPUT 1) (defconstant $SQL_PARAM_INPUT_OUTPUT 2) (defconstant $SQL_RESULT_COL 3) (defconstant $SQL_PARAM_OUTPUT 4) (defconstant $SQL_RETURN_VALUE 5) ;; Defines used by both Level 1 and Level 2 functions ;; generally useful constants (defconstant $SQL_MAX_OPTION_STRING_LENGTH 256) ;; Additional return codes) (defconstant $SQL_STILL_EXECUTING 2) (defconstant $SQL_NEED_DATA 99) ;; SQL extended datatypes) (defconstant $SQL_DATE 9) (defconstant $SQL_TIME 10) (defconstant $SQL_TIMESTAMP 11) (defconstant $SQL_LONGVARCHAR -1) (defconstant $SQL_BINARY -2) (defconstant $SQL_VARBINARY -3) (defconstant $SQL_LONGVARBINARY -4) (defconstant $SQL_BIGINT -5) (defconstant $SQL_TINYINT -6) (defconstant $SQL_BIT -7) ;; For ODBC3 (defconstant $SQL_TYPE_DATE 91) (defconstant $SQL_TYPE_TIME 92) (defconstant $SQL_TYPE_TIMESTAMP 93) (defconstant $SQL_INTERVAL_YEAR -80) (defconstant $SQL_INTERVAL_MONTH -81) (defconstant $SQL_INTERVAL_YEAR_TO_MONTH -82) (defconstant $SQL_INTERVAL_DAY -83) (defconstant $SQL_INTERVAL_HOUR -84) (defconstant $SQL_INTERVAL_MINUTE -85) (defconstant $SQL_INTERVAL_SECOND -86) (defconstant $SQL_INTERVAL_DAY_TO_HOUR -87) (defconstant $SQL_INTERVAL_DAY_TO_MINUTE -88) (defconstant $SQL_INTERVAL_DAY_TO_SECOND -89) (defconstant $SQL_INTERVAL_HOUR_TO_MINUTE -90) (defconstant $SQL_INTERVAL_HOUR_TO_SECOND -91) (defconstant $SQL_INTERVAL_MINUTE_TO_SECOND -92) (defconstant $SQL_UNICODE -95) (defconstant $SQL_TYPE_DRIVER_START $SQL_INTERVAL_YEAR) (defconstant $SQL_TYPE_DRIVER_END $SQL_UNICODE) (defconstant $SQL_SIGNED_OFFSET -20) (defconstant $SQL_UNSIGNED_OFFSET -22) ;; C datatype to SQL datatype mapping (defconstant $SQL_C_DATE $SQL_DATE) (defconstant $SQL_C_TIME $SQL_TIME) (defconstant $SQL_C_TIMESTAMP $SQL_TIMESTAMP) (defconstant $SQL_C_BINARY $SQL_BINARY) (defconstant $SQL_C_BIT $SQL_BIT) (defconstant $SQL_C_TINYINT $SQL_TINYINT) (defconstant $SQL_C_SBIGINT (+ $SQL_BIGINT $SQL_SIGNED_OFFSET)) (defconstant $SQL_C_SLONG (+ $SQL_C_LONG $SQL_SIGNED_OFFSET)) ;; SIGNED INTEGER (defconstant $SQL_C_SSHORT (+ $SQL_C_SHORT $SQL_SIGNED_OFFSET)) ;; SIGNED SMALLINT (defconstant $SQL_C_STINYINT (+ $SQL_TINYINT $SQL_SIGNED_OFFSET)) ;; SIGNED TINYINT (defconstant $SQL_C_ULONG (+ $SQL_C_LONG $SQL_UNSIGNED_OFFSET)) ;; UNSIGNED INTEGER (defconstant $SQL_C_USHORT (+ $SQL_C_SHORT $SQL_UNSIGNED_OFFSET)) ;; UNSIGNED SMALLINT (defconstant $SQL_C_UTINYINT (+ $SQL_TINYINT $SQL_UNSIGNED_OFFSET)) ;;UNSIGNED TINYINT (defconstant $SQL_C_BOOKMARK $SQL_C_ULONG) ;; BOOKMARK ;;; ODBC3 (defconstant $SQL_C_TYPE_DATE $SQL_TYPE_DATE) (defconstant $SQL_C_TYPE_TIME $SQL_TYPE_TIME) (defconstant $SQL_C_TYPE_TIMESTAMP $SQL_TYPE_TIMESTAMP) ;; Options for SQLDriverConnect (defconstant $SQL_DRIVER_NOPROMPT 0) (defconstant $SQL_DRIVER_COMPLETE 1) (defconstant $SQL_DRIVER_PROMPT 2) (defconstant $SQL_DRIVER_COMPLETE_REQUIRED 3) (defconstant $SQL_MAX_CONN_OUT 1024) ;; Level 2 Functions ;; SQLExtendedFetch "fFetchType" values (defconstant $SQL_FETCH_NEXT 1) (defconstant $SQL_FETCH_FIRST 2) (defconstant $SQL_FETCH_LAST 3) (defconstant $SQL_FETCH_PRIOR 4) (defconstant $SQL_FETCH_ABSOLUTE 5) (defconstant $SQL_FETCH_RELATIVE 6) (defconstant $SQL_FETCH_BOOKMARK 8) ;;; ODBC3 constants, added by KMR (defconstant $SQL_ATTR_ODBC_VERSION 200) (defconstant $SQL_OV_ODBC2 2) (defconstant $SQL_OV_ODBC3 3) (defconstant $SQL_INDEX_UNIQUE 0) (defconstant $SQL_INDEX_ALL 1) (defconstant $SQL_QUICK 0) (defconstant $SQL_ENSURE 1) cl-sql-6.7.2/db-odbc/odbc-api.lisp0000644000175000017500000012124611725170505015605 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Package: odbc -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-api.lisp ;;;; Purpose: Low-level ODBC API using UFFI ;;;; Authors: Kevin M. Rosenberg and Paul Meurer ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg ;;;; and Copyright (C) Paul Meurer 1999 - 2001. All rights reserved. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:odbc) (defvar *null* nil "Lisp representation of SQL Null value, default = nil. May be locally bound to something else if a certain type is necessary.") (defvar *binary-format* :unsigned-byte-vector) (defvar *time-format* (lambda (time) (clsql-sys:format-time nil time :format :iso)) "Bound to a function that converts from a clsql:wall-time to the desired representation of date/time/timestamp. By default, returns an iso-timestring.") (defvar +null-ptr+ (make-null-pointer :byte)) (defparameter +null-handle-ptr+ (make-null-pointer :void)) (defvar *info-output* nil "Stream to send SUCCESS_WITH_INFO messages.") (defmacro %put-str (ptr string &optional max-length) (let ((size (gensym))) `(let ((,size (length ,string))) (when (and ,max-length (> ,size ,max-length)) (error 'clsql:sql-database-data-error :message (format nil "string \"~a\" of length ~d is longer than max-length: ~d" ,string ,size ,max-length))) (with-cast-pointer (char-ptr ,ptr :byte) (dotimes (i ,size) (setf (deref-array char-ptr '(:array :byte) i) (char-code (char ,string i)))) (setf (deref-array char-ptr '(:array :byte) ,size) 0))))) (defmacro with-allocate-foreign-string ((var len) &body body) "Safely does uffi:allocate-foreign-string-- making sure we do the uffi:free-foreign-object" `(let ((,var)) (unwind-protect (progn (setf ,var (uffi:allocate-foreign-string ,len)) ,@body) (when ,var (uffi:free-foreign-object ,var))))) (defmacro with-allocate-foreign-strings (bindings &rest body) (if bindings `(with-allocate-foreign-string ,(car bindings) (with-allocate-foreign-strings ,(cdr bindings) ,@body)) `(progn ,@body))) (defun handle-error (henv hdbc hstmt) (with-allocate-foreign-strings ((sql-state 256) (error-message #.$SQL_MAX_MESSAGE_LENGTH)) (with-foreign-objects ((error-code #.$ODBC-LONG-TYPE) (msg-length :short)) (SQLError henv hdbc hstmt sql-state error-code error-message #.$SQL_MAX_MESSAGE_LENGTH msg-length) (values (convert-from-foreign-string error-message) (convert-from-foreign-string sql-state) (deref-pointer msg-length :short) (deref-pointer error-code #.$ODBC-LONG-TYPE))))) (defun sql-state (henv hdbc hstmt) (with-allocate-foreign-strings ((sql-state 256) (error-message #.$SQL_MAX_MESSAGE_LENGTH)) (with-foreign-objects ((error-code #.$ODBC-LONG-TYPE) (msg-length :short)) (SQLError henv hdbc hstmt sql-state error-code error-message #.$SQL_MAX_MESSAGE_LENGTH msg-length) (convert-from-foreign-string sql-state) ;; test this: return a keyword for efficiency ;;(%cstring-to-keyword state) ))) (defmacro with-error-handling ((&key henv hdbc hstmt (print-info t)) odbc-call &body body) (let ((result-code (gensym "RC-"))) `(let ((,result-code ,odbc-call)) ;; Check for allegro v7 & v8 bug with ODBC calls returning ;; 32-bit unsigned ints, not 16-bit signed ints #+(and allegro mswindows) (when (> ,result-code #xFFFF) (warn (format nil "16-bit return bug: result-code #x~X for expression ~S" ,result-code (quote ,odbc-call))) (setq ,result-code (logand ,result-code #xFFFF)) (when (> ,result-code #x7FFF) (setq ,result-code (- ,result-code #x10000)))) (case ,result-code (#.$SQL_SUCCESS (progn ,result-code ,@body)) (#.$SQL_SUCCESS_WITH_INFO (when ,print-info (multiple-value-bind (error-message sql-state) (handle-error (or ,henv +null-handle-ptr+) (or ,hdbc +null-handle-ptr+) (or ,hstmt +null-handle-ptr+)) (when *info-output* (format *info-output* "[ODBC info ~A] ~A state: ~A" ,result-code error-message sql-state)))) (progn ,result-code ,@body)) (#.$SQL_INVALID_HANDLE (error 'clsql-sys:sql-database-error :message "ODBC: Invalid handle")) (#.$SQL_STILL_EXECUTING (error 'clsql-sys:sql-temporary-error :message "ODBC: Still executing")) (#.$SQL_ERROR (multiple-value-bind (error-message sql-state) (handle-error (or ,henv +null-handle-ptr+) (or ,hdbc +null-handle-ptr+) (or ,hstmt +null-handle-ptr+)) (error 'clsql-sys:sql-database-error :message error-message :secondary-error-id sql-state))) (#.$SQL_NO_DATA_FOUND (progn ,result-code ,@body)) ;; work-around for Allegro 7.0beta AMD64 which returns negative numbers (otherwise (multiple-value-bind (error-message sql-state) (handle-error (or ,henv +null-handle-ptr+) (or ,hdbc +null-handle-ptr+) (or ,hstmt +null-handle-ptr+)) (error 'clsql-sys:sql-database-error :message error-message :secondary-error-id sql-state)) #+ignore (progn ,result-code ,@body)))))) (defun %new-environment-handle () (let ((henv (with-foreign-object (phenv 'sql-handle) (with-error-handling () (SQLAllocHandle $SQL_HANDLE_ENV +null-handle-ptr+ phenv) (deref-pointer phenv 'sql-handle))))) (%set-attr-odbc-version henv $SQL_OV_ODBC3) henv)) (defun %sql-free-environment (henv) (with-error-handling (:henv henv) (SQLFreeEnv henv))) (defun %new-db-connection-handle (henv) (with-foreign-object (phdbc 'sql-handle) (setf (deref-pointer phdbc 'sql-handle) +null-handle-ptr+) (with-error-handling (:henv henv) (SQLAllocHandle $SQL_HANDLE_DBC henv phdbc) (deref-pointer phdbc 'sql-handle)))) (defun %free-statement (hstmt option) (with-error-handling (:hstmt hstmt) (SQLFreeStmt hstmt (ecase option (:drop $SQL_DROP) (:close $SQL_CLOSE) (:unbind $SQL_UNBIND) (:reset $SQL_RESET_PARAMS))))) (defmacro with-statement-handle ((hstmt hdbc) &body body) `(let ((,hstmt (%new-statement-handle ,hdbc))) (unwind-protect (progn ,@body) (%free-statement ,hstmt :drop)))) ;; functional interface (defun %sql-connect (hdbc server uid pwd) (with-cstrings ((server-ptr server) (uid-ptr uid) (pwd-ptr pwd)) (with-error-handling (:hdbc hdbc) (SQLConnect hdbc server-ptr $SQL_NTS uid-ptr $SQL_NTS pwd-ptr $SQL_NTS)))) (defun %sql-driver-connect (hdbc connection-string completion window-handle) (with-cstring (connection-ptr connection-string) (with-allocate-foreign-string (completed-connection-string-ptr $SQL_MAX_CONN_OUT) (with-foreign-object (completed-connection-length :short) (with-error-handling (:hdbc hdbc) (SQLDriverConnect hdbc (or window-handle +null-handle-ptr+) connection-ptr $SQL_NTS completed-connection-string-ptr $SQL_MAX_CONN_OUT completed-connection-length completion)))))) (defun %disconnect (hdbc) (with-error-handling (:hdbc hdbc) (SQLDisconnect hdbc) (with-error-handling (:hdbc hdbc) (SQLFreeHandle $SQL_HANDLE_DBC hdbc)))) (defun %commit (henv hdbc) (with-error-handling (:henv henv :hdbc hdbc) (SQLTransact henv hdbc $SQL_COMMIT))) (defun %rollback (henv hdbc) (with-error-handling (:henv henv :hdbc hdbc) (SQLTransact henv hdbc $SQL_ROLLBACK))) ; col-nr is zero-based in Lisp but 1 based in sql ; col-nr = :bookmark retrieves a bookmark. (defun %bind-column (hstmt column-nr c-type data-ptr precision out-len-ptr) (with-error-handling (:hstmt hstmt) (SQLBindCol hstmt (if (eq column-nr :bookmark) 0 (1+ column-nr)) c-type data-ptr precision out-len-ptr))) ; parameter-nr is zero-based in Lisp (defun %sql-bind-parameter (hstmt parameter-nr parameter-type c-type sql-type precision scale data-ptr max-value out-len-ptr) (with-error-handling (:hstmt hstmt) (SQLBindParameter hstmt (1+ parameter-nr) parameter-type ;$SQL_PARAM_INPUT c-type ;$SQL_C_CHAR sql-type ;$SQL_VARCHAR precision ;(1- (length str)) scale ;0 data-ptr max-value out-len-ptr ;#.+null-ptr+ ))) (defun %sql-fetch (hstmt) (with-error-handling (:hstmt hstmt) (SQLFetch hstmt))) (defun %new-statement-handle (hdbc) (let ((statement-handle (with-foreign-object (phstmt 'sql-handle) (with-error-handling (:hdbc hdbc) (SQLAllocHandle $SQL_HANDLE_STMT hdbc phstmt) (deref-pointer phstmt 'sql-handle))))) (if (uffi:null-pointer-p statement-handle) (error 'clsql:sql-database-error :message "Received null statement handle.") statement-handle))) (defun %sql-get-info (hdbc info-type) (ecase info-type ;; those return string ((#.$SQL_ACCESSIBLE_PROCEDURES #.$SQL_ACCESSIBLE_TABLES #.$SQL_COLUMN_ALIAS #.$SQL_DATA_SOURCE_NAME #.$SQL_DATA_SOURCE_READ_ONLY #.$SQL_DBMS_NAME #.$SQL_DBMS_VER #.$SQL_DRIVER_NAME #.$SQL_DRIVER_ODBC_VER #.$SQL_DRIVER_VER #.$SQL_EXPRESSIONS_IN_ORDERBY #.$SQL_IDENTIFIER_QUOTE_CHAR #.$SQL_KEYWORDS #.$SQL_LIKE_ESCAPE_CLAUSE #.$SQL_MAX_ROW_SIZE_INCLUDES_LONG #.$SQL_MULT_RESULT_SETS #.$SQL_MULTIPLE_ACTIVE_TXN #.$SQL_NEED_LONG_DATA_LEN #.$SQL_ODBC_SQL_OPT_IEF #.$SQL_ODBC_VER #.$SQL_ORDER_BY_COLUMNS_IN_SELECT #.$SQL_OUTER_JOINS #.$SQL_OWNER_TERM #.$SQL_PROCEDURE_TERM #.$SQL_PROCEDURES #.$SQL_QUALIFIER_NAME_SEPARATOR #.$SQL_QUALIFIER_TERM #.$SQL_ROW_UPDATES #.$SQL_SEARCH_PATTERN_ESCAPE #.$SQL_SERVER_NAME #.$SQL_SPECIAL_CHARACTERS #.$SQL_TABLE_TERM #.$SQL_USER_NAME) (with-allocate-foreign-string (info-ptr 1024) (with-foreign-object (info-length-ptr :short) (with-error-handling (:hdbc hdbc) (SQLGetInfo hdbc info-type info-ptr 1023 info-length-ptr) (convert-from-foreign-string info-ptr))))) ;; those returning a word ((#.$SQL_ACTIVE_CONNECTIONS #.$SQL_ACTIVE_STATEMENTS #.$SQL_CONCAT_NULL_BEHAVIOR #.$SQL_CORRELATION_NAME #.$SQL_CURSOR_COMMIT_BEHAVIOR #.$SQL_CURSOR_ROLLBACK_BEHAVIOR #.$SQL_MAX_COLUMN_NAME_LEN #.$SQL_MAX_COLUMNS_IN_GROUP_BY #.$SQL_MAX_COLUMNS_IN_INDEX #.$SQL_MAX_COLUMNS_IN_ORDER_BY #.$SQL_MAX_COLUMNS_IN_SELECT #.$SQL_MAX_COLUMNS_IN_TABLE #.$SQL_MAX_CURSOR_NAME_LEN #.$SQL_MAX_OWNER_NAME_LEN #.$SQL_MAX_PROCEDURE_NAME_LEN #.$SQL_MAX_QUALIFIER_NAME_LEN #.$SQL_MAX_TABLE_NAME_LEN #.$SQL_MAX_TABLES_IN_SELECT #.$SQL_MAX_USER_NAME_LEN #.$SQL_NON_NULLABLE_COLUMNS #.$SQL_NULL_COLLATION #.$SQL_ODBC_API_CONFORMANCE #.$SQL_ODBC_SAG_CLI_CONFORMANCE #.$SQL_ODBC_SQL_CONFORMANCE #.$SQL_QUALIFIER_LOCATION #.$SQL_QUOTED_IDENTIFIER_CASE #.$SQL_TXN_CAPABLE) (with-foreign-objects ((info-ptr :short) (info-length-ptr :short)) (with-error-handling (:hdbc hdbc) (SQLGetInfo hdbc info-type info-ptr 255 info-length-ptr) (deref-pointer info-ptr :short))) ) ;; those returning a long bitmask ((#.$SQL_ALTER_TABLE #.$SQL_BOOKMARK_PERSISTENCE #.$SQL_CONVERT_BIGINT #.$SQL_CONVERT_BINARY #.$SQL_CONVERT_BIT #.$SQL_CONVERT_CHAR #.$SQL_CONVERT_DATE #.$SQL_CONVERT_DECIMAL #.$SQL_CONVERT_DOUBLE #.$SQL_CONVERT_FLOAT #.$SQL_CONVERT_INTEGER #.$SQL_CONVERT_LONGVARCHAR #.$SQL_CONVERT_NUMERIC #.$SQL_CONVERT_REAL #.$SQL_CONVERT_SMALLINT #.$SQL_CONVERT_TIME #.$SQL_CONVERT_TIMESTAMP #.$SQL_CONVERT_TINYINT #.$SQL_CONVERT_VARBINARY #.$SQL_CONVERT_VARCHAR #.$SQL_CONVERT_LONGVARBINARY #.$SQL_CONVERT_FUNCTIONS #.$SQL_FETCH_DIRECTION #.$SQL_FILE_USAGE #.$SQL_GETDATA_EXTENSIONS #.$SQL_LOCK_TYPES #.$SQL_MAX_INDEX_SIZE #.$SQL_MAX_ROW_SIZE #.$SQL_MAX_STATEMENT_LEN #.$SQL_NUMERIC_FUNCTIONS #.$SQL_OWNER_USAGE #.$SQL_POS_OPERATIONS #.$SQL_POSITIONED_STATEMENTS #.$SQL_QUALIFIER_USAGE #.$SQL_SCROLL_CONCURRENCY #.$SQL_SCROLL_OPTIONS #.$SQL_STATIC_SENSITIVITY #.$SQL_STRING_FUNCTIONS #.$SQL_SUBQUERIES #.$SQL_SYSTEM_FUNCTIONS #.$SQL_TIMEDATE_ADD_INTERVALS #.$SQL_TIMEDATE_DIFF_INTERVALS #.$SQL_TIMEDATE_FUNCTIONS #.$SQL_TXN_ISOLATION_OPTION #.$SQL_UNION) (with-foreign-objects ((info-ptr #.$ODBC-LONG-TYPE) (info-length-ptr :short)) (with-error-handling (:hdbc hdbc) (SQLGetInfo hdbc info-type info-ptr 255 info-length-ptr) (deref-pointer info-ptr #.$ODBC-LONG-TYPE))) ) ;; those returning a long integer ((#.$SQL_DEFAULT_TXN_ISOLATION #.$SQL_DRIVER_HDBC #.$SQL_DRIVER_HENV #.$SQL_DRIVER_HLIB #.$SQL_DRIVER_HSTMT #.$SQL_GROUP_BY #.$SQL_IDENTIFIER_CASE #.$SQL_MAX_BINARY_LITERAL_LEN #.$SQL_MAX_CHAR_LITERAL_LEN #.$SQL_ACTIVE_ENVIRONMENTS ) (with-foreign-objects ((info-ptr #.$ODBC-LONG-TYPE) (info-length-ptr :short)) (with-error-handling (:hdbc hdbc) (SQLGetInfo hdbc info-type info-ptr 255 info-length-ptr) (deref-pointer info-ptr #.$ODBC-LONG-TYPE)))))) (defun %sql-exec-direct (sql hstmt henv hdbc) (with-cstring (sql-ptr sql) (with-error-handling (:hstmt hstmt :henv henv :hdbc hdbc) (SQLExecDirect hstmt sql-ptr $SQL_NTS)))) (defun %sql-cancel (hstmt) (with-error-handling (:hstmt hstmt) (SQLCancel hstmt))) (defun %sql-execute (hstmt) (with-error-handling (:hstmt hstmt) (SQLExecute hstmt))) (defun result-columns-count (hstmt) (with-foreign-objects ((columns-nr-ptr :short)) (with-error-handling (:hstmt hstmt) (SQLNumResultCols hstmt columns-nr-ptr) (deref-pointer columns-nr-ptr :short)))) (defun result-rows-count (hstmt) (with-foreign-objects ((row-count-ptr #.$ODBC-LONG-TYPE)) (with-error-handling (:hstmt hstmt) (SQLRowCount hstmt row-count-ptr) (deref-pointer row-count-ptr #.$ODBC-LONG-TYPE)))) ;; column counting is 1-based (defun %describe-column (hstmt column-nr) (with-allocate-foreign-string (column-name-ptr 256) (with-foreign-objects ((column-name-length-ptr :short) (column-sql-type-ptr :short) (column-precision-ptr #.$ODBC-ULONG-TYPE) (column-scale-ptr :short) (column-nullable-p-ptr :short)) (with-error-handling (:hstmt hstmt) (SQLDescribeCol hstmt column-nr column-name-ptr 256 column-name-length-ptr column-sql-type-ptr column-precision-ptr column-scale-ptr column-nullable-p-ptr) (values (convert-from-foreign-string column-name-ptr) (deref-pointer column-sql-type-ptr :short) (deref-pointer column-precision-ptr #.$ODBC-ULONG-TYPE) (deref-pointer column-scale-ptr :short) (deref-pointer column-nullable-p-ptr :short)))))) ;; parameter counting is 1-based ;; this function isn't used, which is good because FreeTDS dosn't support it. (defun %describe-parameter (hstmt parameter-nr) (with-foreign-objects ((column-sql-type-ptr :short) (column-precision-ptr #.$ODBC-ULONG-TYPE) (column-scale-ptr :short) (column-nullable-p-ptr :short)) (with-error-handling (:hstmt hstmt) (SQLDescribeParam hstmt parameter-nr column-sql-type-ptr column-precision-ptr column-scale-ptr column-nullable-p-ptr) (values (deref-pointer column-sql-type-ptr :short) (deref-pointer column-precision-ptr #.$ODBC-ULONG-TYPE) (deref-pointer column-scale-ptr :short) (deref-pointer column-nullable-p-ptr :short))))) (defun %column-attributes (hstmt column-nr descriptor-type) (with-allocate-foreign-string (descriptor-info-ptr 256) (with-foreign-objects ((descriptor-length-ptr :short) (numeric-descriptor-ptr #.$ODBC-LONG-TYPE)) (with-error-handling (:hstmt hstmt) (SQLColAttributes hstmt column-nr descriptor-type descriptor-info-ptr 256 descriptor-length-ptr numeric-descriptor-ptr) (values (convert-from-foreign-string descriptor-info-ptr) (deref-pointer numeric-descriptor-ptr #.$ODBC-LONG-TYPE)))))) (defun %prepare-describe-columns (hstmt table-qualifier table-owner table-name column-name) (with-cstrings ((table-qualifier-ptr table-qualifier) (table-owner-ptr table-owner) (table-name-ptr table-name) (column-name-ptr column-name)) (with-error-handling (:hstmt hstmt) (SQLColumns hstmt table-qualifier-ptr (length table-qualifier) table-owner-ptr (length table-owner) table-name-ptr (length table-name) column-name-ptr (length column-name))))) (defun %describe-columns (hdbc table-qualifier table-owner table-name column-name) (with-statement-handle (hstmt hdbc) (%prepare-describe-columns hstmt table-qualifier table-owner table-name column-name) (fetch-all-rows hstmt))) (defun %sql-data-sources (henv &key (direction :first)) (with-allocate-foreign-strings ((name-ptr (1+ $SQL_MAX_DSN_LENGTH)) (description-ptr 1024)) (with-foreign-objects ((name-length-ptr :short) (description-length-ptr :short)) (let ((res (with-error-handling (:henv henv) (SQLDataSources henv (ecase direction (:first $SQL_FETCH_FIRST) (:next $SQL_FETCH_NEXT)) name-ptr (1+ $SQL_MAX_DSN_LENGTH) name-length-ptr description-ptr 1024 description-length-ptr)))) (when (= res $SQL_NO_DATA_FOUND) (values (convert-from-foreign-string name-ptr) (convert-from-foreign-string description-ptr))))))) (defun sql-to-c-type (sql-type) (ecase sql-type ;; Added -10 for MSSQL ntext type and -11 for nvarchar ((#.$SQL_CHAR #.$SQL_VARCHAR #.$SQL_LONGVARCHAR #.$SQL_NUMERIC #.$sql_decimal -8 -9 -10 -11) $SQL_C_CHAR) (#.$SQL_INTEGER $SQL_C_SLONG) (#.$SQL_BIGINT $SQL_C_SBIGINT) (#.$SQL_SMALLINT $SQL_C_SSHORT) (#.$SQL_DOUBLE $SQL_C_DOUBLE) (#.$SQL_FLOAT $SQL_C_DOUBLE) (#.$SQL_REAL $SQL_C_FLOAT) (#.$SQL_DATE $SQL_C_DATE) (#.$SQL_TIME $SQL_C_TIME) (#.$SQL_TIMESTAMP $SQL_C_TIMESTAMP) (#.$SQL_TYPE_DATE $SQL_C_TYPE_DATE) (#.$SQL_TYPE_TIME $SQL_C_TYPE_TIME) (#.$SQL_TYPE_TIMESTAMP $SQL_C_TYPE_TIMESTAMP) ((#.$SQL_BINARY #.$SQL_VARBINARY #.$SQL_LONGVARBINARY) $SQL_C_BINARY) (#.$SQL_TINYINT $SQL_C_STINYINT) (#.$SQL_BIT $SQL_C_BIT))) (def-type byte-pointer-type (* :byte)) (def-type short-pointer-type (* :short)) (def-type int-pointer-type (* :int)) (def-type long-pointer-type (* #.$ODBC-LONG-TYPE)) (def-type big-pointer-type (* #.$ODBC-BIG-TYPE)) (def-type float-pointer-type (* :float)) (def-type double-pointer-type (* :double)) (def-type string-pointer-type (* :unsigned-char)) (defun get-cast-byte (ptr) (locally (declare (type byte-pointer-type ptr)) (deref-pointer ptr :byte))) (defun get-cast-short (ptr) (locally (declare (type short-pointer-type ptr)) (deref-pointer ptr :short))) (defun get-cast-int (ptr) (locally (declare (type int-pointer-type ptr)) (deref-pointer ptr :int))) (defun get-cast-long (ptr) (locally (declare (type long-pointer-type ptr)) (deref-pointer ptr #.$ODBC-LONG-TYPE))) (defun get-cast-big (ptr) (locally (declare (type big-pointer-type ptr)) (deref-pointer ptr #.$ODBC-BIG-TYPE))) (defun get-cast-single-float (ptr) (locally (declare (type float-pointer-type ptr)) (deref-pointer ptr :float))) (defun get-cast-double-float (ptr) (locally (declare (type double-pointer-type ptr)) (deref-pointer ptr :double))) (defun get-cast-foreign-string (ptr) (locally (declare (type string-pointer-type ptr)) (convert-from-foreign-string ptr))) (defun get-cast-binary (ptr len format) "FORMAT is one of :unsigned-byte-vector, :bit-vector (:string, :hex-string)" (with-cast-pointer (casted ptr :unsigned-byte) (ecase format (:unsigned-byte-vector (let ((vector (make-array len :element-type '(unsigned-byte 8)))) (dotimes (i len) (setf (aref vector i) (deref-array casted '(:array :unsigned-byte) i))) vector)) (:bit-vector (let ((vector (make-array (ash len 3) :element-type 'bit))) (dotimes (i len) (let ((byte (deref-array casted '(:array :byte) i))) (dotimes (j 8) (setf (bit vector (+ (ash i 3) j)) (logand (ash byte (- j 7)) 1))))) vector))))) (defun read-data (data-ptr c-type sql-type out-len-ptr result-type) (declare (type long-ptr-type out-len-ptr)) (let* ((out-len (get-cast-long out-len-ptr)) (value (cond ((= out-len $SQL_NULL_DATA) *null*) (t (case sql-type ;; SQL extended datatypes (#.$SQL_TINYINT (get-cast-byte data-ptr)) (#.$SQL_C_STINYINT (get-cast-byte data-ptr)) ;; ? (#.$SQL_C_SSHORT (get-cast-short data-ptr)) ;; ? (#.$SQL_SMALLINT (get-cast-short data-ptr)) ;; ?? (#.$SQL_INTEGER (get-cast-int data-ptr)) (#.$SQL_BIGINT (get-cast-big data-ptr)) ;; TODO: Change this to read in rationals instead of doubles ((#.$SQL_DECIMAL #.$SQL_NUMERIC) (let* ((*read-base* 10) (*read-default-float-format* 'double-float) (str (get-cast-foreign-string data-ptr))) (read-from-string str))) (#.$SQL_BIT (get-cast-byte data-ptr)) (t (case c-type ((#.$SQL_C_DATE #.$SQL_C_TYPE_DATE) (funcall *time-format* (date-to-clsql-time data-ptr))) ((#.$SQL_C_TIME #.$SQL_C_TYPE_TIME) (funcall *time-format* (time-to-clsql-time data-ptr))) ((#.$SQL_C_TIMESTAMP #.$SQL_C_TYPE_TIMESTAMP) (funcall *time-format* (timestamp-to-clsql-time data-ptr))) (#.$SQL_INTEGER (get-cast-int data-ptr)) (#.$SQL_C_FLOAT (get-cast-single-float data-ptr)) (#.$SQL_C_DOUBLE (get-cast-double-float data-ptr)) (#.$SQL_C_SLONG (get-cast-long data-ptr)) #+lispworks (#.$SQL_C_BIT ; encountered only in Access (get-cast-byte data-ptr)) (#.$SQL_C_BINARY (get-cast-binary data-ptr out-len *binary-format*)) ((#.$SQL_C_SSHORT #.$SQL_C_STINYINT) ; LMH short ints (get-cast-short data-ptr)) ; LMH (#.$SQL_C_SBIGINT (get-cast-big data-ptr)) #+ignore (#.$SQL_C_CHAR (code-char (get-cast-short data-ptr))) (t (get-cast-foreign-string data-ptr))))))))) ;; FIXME: this could be better optimized for types which use READ-FROM-STRING above (if (and (or (eq result-type t) (eq result-type :string)) value (not (stringp value))) (write-to-string value) value))) ;; which value is appropriate? (defparameter +max-precision+ 4001) (defvar *break-on-unknown-data-type* t) ;; C. Stacy's idea to factor this out ;; "Make it easy to add new datatypes by making new subroutine %ALLOCATE-BINDINGS, ;; so that I don't have to remember to make changes in more than one place. ;; Just keep it in synch with READ-DATA." (defun %allocate-bindings (sql-type precision) (let* ((c-type (sql-to-c-type sql-type)) (size (if (zerop precision) +max-precision+ ;; if the precision cannot be determined (min precision +max-precision+))) (long-p (= size +max-precision+)) (data-ptr (case c-type ;; add more? (#.$SQL_C_SLONG (uffi:allocate-foreign-object #.$ODBC-LONG-TYPE)) ((#.$SQL_C_DATE #.$SQL_C_TYPE_DATE) (allocate-foreign-object 'sql-c-date)) ((#.$SQL_C_TIME #.$SQL_C_TYPE_TIME) (allocate-foreign-object 'sql-c-time)) ((#.$SQL_C_TIMESTAMP #.$SQL_C_TYPE_TIMESTAMP) (allocate-foreign-object 'sql-c-timestamp)) (#.$SQL_C_FLOAT (uffi:allocate-foreign-object :float)) (#.$SQL_C_DOUBLE (uffi:allocate-foreign-object :double)) (#.$SQL_C_BIT (uffi:allocate-foreign-object :byte)) (#.$SQL_C_STINYINT (uffi:allocate-foreign-object :byte)) (#.$SQL_C_SBIGINT (uffi:allocate-foreign-object #.$ODBC-BIG-TYPE)) (#.$SQL_C_SSHORT (uffi:allocate-foreign-object :short)) (#.$SQL_C_CHAR (uffi:allocate-foreign-string (1+ size))) (#.$SQL_C_BINARY (uffi:allocate-foreign-string (1+ (* 2 size)))) (t ;; Maybe should signal a restartable condition for this? (when *break-on-unknown-data-type* (break "SQL type is ~A, precision ~D, size ~D, C type is ~A" sql-type precision size c-type)) (uffi:allocate-foreign-object :byte (1+ size))))) (out-len-ptr (uffi:allocate-foreign-object #.$ODBC-LONG-TYPE))) (values c-type data-ptr out-len-ptr size long-p))) (defun fetch-all-rows (hstmt &key free-option flatp) (let ((column-count (result-columns-count hstmt))) (unless (zerop column-count) (let ((names (make-array column-count)) (sql-types (make-array column-count :element-type 'fixnum)) (c-types (make-array column-count :element-type 'fixnum)) (precisions (make-array column-count :element-type 'fixnum)) (data-ptrs (make-array column-count :initial-element nil)) (out-len-ptrs (make-array column-count :initial-element nil)) (scales (make-array column-count :element-type 'fixnum)) (nullables-p (make-array column-count :element-type 'fixnum))) (unwind-protect (values (progn (dotimes (col-nr column-count) ;; get column information (multiple-value-bind (name sql-type precision scale nullable-p) (%describe-column hstmt (1+ col-nr)) ;; allocate space to bind result rows to (multiple-value-bind (c-type data-ptr out-len-ptr) (%allocate-bindings sql-type precision) (%bind-column hstmt col-nr c-type data-ptr (1+ precision) out-len-ptr) (setf (svref names col-nr) name (aref sql-types col-nr) sql-type (aref c-types col-nr) (sql-to-c-type sql-type) (aref precisions col-nr) (if (zerop precision) 0 precision) (aref scales col-nr) scale (aref nullables-p col-nr) nullable-p (aref data-ptrs col-nr) data-ptr (aref out-len-ptrs col-nr) out-len-ptr)))) ;; the main loop (prog1 (cond (flatp (when (> column-count 1) (error 'clsql:sql-database-error :message "If more than one column is to be fetched, flatp has to be nil.")) (loop until (= (%sql-fetch hstmt) $SQL_NO_DATA_FOUND) collect (read-data (aref data-ptrs 0) (aref c-types 0) (aref sql-types 0) (aref out-len-ptrs 0) t))) (t (loop until (= (%sql-fetch hstmt) $SQL_NO_DATA_FOUND) collect (loop for col-nr from 0 to (1- column-count) collect (read-data (aref data-ptrs col-nr) (aref c-types col-nr) (aref sql-types col-nr) (aref out-len-ptrs col-nr) t))))))) names) ;; dispose of memory etc (when free-option (%free-statement hstmt free-option)) (dotimes (col-nr column-count) (let ((data-ptr (aref data-ptrs col-nr)) (out-len-ptr (aref out-len-ptrs col-nr))) (when data-ptr (free-foreign-object data-ptr)) ; we *did* allocate them (when out-len-ptr (free-foreign-object out-len-ptr))))))))) ;; to do: factor out common parts, put the sceleton (the obligatory macro part) ;; of %do-fetch into sql package (has been done) (defun %sql-prepare (hstmt sql) (with-cstring (sql-ptr sql) (with-error-handling (:hstmt hstmt) (SQLPrepare hstmt sql-ptr $SQL_NTS)))) ;; depending on option, we return a long int or a string; string not implemented (defun get-connection-option (hdbc option) (with-foreign-object (param-ptr #.$ODBC-LONG-TYPE) (with-error-handling (:hdbc hdbc) (SQLGetConnectOption hdbc option param-ptr) (deref-pointer param-ptr #.$ODBC-LONG-TYPE)))) (defun set-connection-option (hdbc option param) (with-error-handling (:hdbc hdbc) (SQLSetConnectOption hdbc option param))) (defun disable-autocommit (hdbc) (set-connection-option hdbc $SQL_AUTOCOMMIT $SQL_AUTOCOMMIT_OFF)) (defun enable-autocommit (hdbc) (set-connection-option hdbc $SQL_AUTOCOMMIT $SQL_AUTOCOMMIT_ON)) (defun %sql-set-pos (hstmt row option lock) (with-error-handling (:hstmt hstmt) (SQLSetPos hstmt row option lock))) (defun %sql-extended-fetch (hstmt fetch-type row) (with-foreign-objects ((row-count-ptr #.$ODBC-ULONG-TYPE) (row-status-ptr :short)) (with-error-handling (:hstmt hstmt) (SQLExtendedFetch hstmt fetch-type row row-count-ptr row-status-ptr) (values (deref-pointer row-count-ptr #.$ODBC-ULONG-TYPE) (deref-pointer row-status-ptr :short))))) ; column-nr is zero-based (defun %sql-get-data (hstmt column-nr c-type data-ptr precision out-len-ptr) (with-error-handling (:hstmt hstmt :print-info nil) (SQLGetData hstmt (if (eq column-nr :bookmark) 0 (1+ column-nr)) c-type data-ptr precision out-len-ptr))) (defun %sql-param-data (hstmt param-ptr) (with-error-handling (:hstmt hstmt :print-info t) ;; nil (SQLParamData hstmt param-ptr))) (defun %sql-put-data (hstmt data-ptr size) (with-error-handling (:hstmt hstmt :print-info t) ;; nil (SQLPutData hstmt data-ptr size))) (defconstant $sql-data-truncated (intern "01004" :keyword)) (defun read-data-in-chunks (hstmt column-nr data-ptr c-type sql-type out-len-ptr result-type) (declare (type long-ptr-type out-len-ptr) (ignore result-type)) (let* ((res (%sql-get-data hstmt column-nr c-type data-ptr +max-precision+ out-len-ptr)) (out-len (get-cast-long out-len-ptr)) (result (if (equal out-len #.$SQL_NULL_DATA) (return-from read-data-in-chunks *null*) ;;this isn't the most efficient way of doing it: ;;the foreign string gets copied to lisp, then ;;that is copied into the final string. However, ;;the previous impl that tried to copy one ;;character over at a time failed miserably on ;;multibyte characters. ;; ;;In the face of multibyte characters, the out-len ;;tells us the length in bytes but that doesn't ;;particularly help us here in allocating a lisp ;;array. So our best strategy is to just let the ;;foreign library that's already dealing with ;;encodings do its thing. (with-output-to-string (str) (loop do (if (= c-type #.$SQL_CHAR) (write-sequence (get-cast-foreign-string data-ptr) str) (error 'clsql:sql-database-error :message "wrong type. preliminary.")) while (and (= res $SQL_SUCCESS_WITH_INFO) (equal (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt) "01004")) do (setf res (%sql-get-data hstmt column-nr c-type data-ptr +max-precision+ out-len-ptr))))))) ;; reset the out length for the next row (setf (deref-pointer out-len-ptr #.$ODBC-LONG-TYPE) #.$SQL_NO_TOTAL) (if (= sql-type $SQL_DECIMAL) (let ((*read-base* 10)) (read-from-string result)) result))) (def-type c-timestamp-ptr-type (* (:struct sql-c-timestamp))) (def-type c-time-ptr-type (* (:struct sql-c-time))) (def-type c-date-ptr-type (* (:struct sql-c-date))) (defun timestamp-to-clsql-time (ptr) (declare (type c-timestamp-ptr-type ptr)) (clsql-sys:make-time :second (get-slot-value ptr 'sql-c-timestamp 'second) :minute (get-slot-value ptr 'sql-c-timestamp 'minute) :hour (get-slot-value ptr 'sql-c-timestamp 'hour) :day (get-slot-value ptr 'sql-c-timestamp 'day) :month (get-slot-value ptr 'sql-c-timestamp 'month) :year (get-slot-value ptr 'sql-c-timestamp 'year) :usec (let ((frac (get-slot-value ptr 'sql-c-timestamp 'fraction))) (if frac (/ frac 1000) 0)))) (defun universal-time-to-timestamp (time &optional (fraction 0)) "TODO: Dead function?" (multiple-value-bind (sec min hour day month year) (decode-universal-time time) (let ((ptr (allocate-foreign-object 'sql-c-timestamp))) (setf (get-slot-value ptr 'sql-c-timestamp 'second) sec (get-slot-value ptr 'sql-c-timestamp 'minute) min (get-slot-value ptr 'sql-c-timestamp 'hour) hour (get-slot-value ptr 'sql-c-timestamp 'day) day (get-slot-value ptr 'sql-c-timestamp 'month) month (get-slot-value ptr 'sql-c-timestamp 'year) year (get-slot-value ptr 'sql-c-timestamp 'fraction) fraction) ptr))) (defun %put-timestamp (ptr time &optional (fraction 0)) "TODO: Dead function?" (declare (type c-timestamp-ptr-type ptr)) (multiple-value-bind (sec min hour day month year) (decode-universal-time time) (setf (get-slot-value ptr 'sql-c-timestamp 'second) sec (get-slot-value ptr 'sql-c-timestamp 'minute) min (get-slot-value ptr 'sql-c-timestamp 'hour) hour (get-slot-value ptr 'sql-c-timestamp 'day) day (get-slot-value ptr 'sql-c-timestamp 'month) month (get-slot-value ptr 'sql-c-timestamp 'year) year (get-slot-value ptr 'sql-c-timestamp 'fraction) fraction) ptr)) (defun date-to-clsql-time (ptr) (declare (type c-date-ptr-type ptr)) (clsql-sys:make-time :second 0 :minute 0 :hour 0 :day (get-slot-value ptr 'sql-c-timestamp 'day) :month (get-slot-value ptr 'sql-c-timestamp 'month) :year (get-slot-value ptr 'sql-c-timestamp 'year))) (defun time-to-clsql-time (ptr) (declare (type c-time-ptr-type ptr)) (clsql-sys:make-time :second (get-slot-value ptr 'sql-c-timestamp 'second) :minute (get-slot-value ptr 'sql-c-timestamp 'minute) :hour (get-slot-value ptr 'sql-c-timestamp 'hour))) ;;; Added by KMR (defun %set-attr-odbc-version (henv version) (with-error-handling (:henv henv) ;;note that we are passing version as an integer that happens to be ;;stuffed into a pointer. ;;http://msdn.microsoft.com/en-us/library/ms709285%28v=VS.85%29.aspx (SQLSetEnvAttr henv $SQL_ATTR_ODBC_VERSION (make-pointer version :void) 0))) (defun %list-tables (hstmt) (with-error-handling (:hstmt hstmt) (SQLTables hstmt +null-ptr+ 0 +null-ptr+ 0 +null-ptr+ 0 +null-ptr+ 0))) (defun %table-statistics (table hstmt &key unique (ensure t) &aux (table (princ-to-string (clsql-sys::unescaped-database-identifier table)))) (with-cstrings ((table-cs table)) (with-error-handling (:hstmt hstmt) (SQLStatistics hstmt +null-ptr+ 0 +null-ptr+ 0 table-cs $SQL_NTS (if unique $SQL_INDEX_UNIQUE $SQL_INDEX_ALL) (if ensure $SQL_ENSURE $SQL_QUICK))))) (defun %list-data-sources (henv) (let ((results nil)) (with-foreign-strings ((dsn-ptr (1+ $SQL_MAX_DSN_LENGTH)) (desc-ptr 256)) (with-foreign-objects ((dsn-len :short) (desc-len :short)) (let ((res (with-error-handling (:henv henv) (SQLDataSources henv $SQL_FETCH_FIRST dsn-ptr (1+ $SQL_MAX_DSN_LENGTH) dsn-len desc-ptr 256 desc-len)))) (when (or (eql res $SQL_SUCCESS) (eql res $SQL_SUCCESS_WITH_INFO)) (push (convert-from-foreign-string dsn-ptr) results)) (do ((res (with-error-handling (:henv henv) (SQLDataSources henv $SQL_FETCH_NEXT dsn-ptr (1+ $SQL_MAX_DSN_LENGTH) dsn-len desc-ptr 256 desc-len)) (with-error-handling (:henv henv) (SQLDataSources henv $SQL_FETCH_NEXT dsn-ptr (1+ $SQL_MAX_DSN_LENGTH) dsn-len desc-ptr 256 desc-len)))) ((not (or (eql res $SQL_SUCCESS) (eql res $SQL_SUCCESS_WITH_INFO)))) (push (convert-from-foreign-string dsn-ptr) results))))) (nreverse results))) cl-sql-6.7.2/db-odbc/odbc-loader.lisp0000644000175000017500000000302011335067642016273 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-loader.sql ;;;; Purpose: ODBC library loader using UFFI ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: April 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:odbc) (defparameter *odbc-library-filenames* '("odbc32" "libodbc" "libiodbc")) (defvar *odbc-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the Odbc client library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *odbc-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :odbc))) *odbc-library-loaded*) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :odbc))) (clsql-uffi:find-and-load-foreign-library *odbc-library-filenames* :module "odbc") (setq *odbc-library-loaded* t)) (clsql-sys:database-type-load-foreign :odbc) cl-sql-6.7.2/db-odbc/Makefile0000644000175000017500000000126211335067642014675 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL SQL interface # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/db-odbc/odbc-package.lisp0000644000175000017500000000347111673670205016432 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: odbc-package.lisp ;;;; Purpose: Package definition for low-level ODBC interface ;;;; Author: Kevin M. Rosenberg ;;;; Created: April 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:odbc (:use #:cl #:uffi) (:export #:database-library-loaded #:*null* #:+null-ptr+ #:+max-precision+ #:*info-output* #:*time-format* #:get-cast-long #:%free-statement #:%disconnect #:%commit #:%rollback #:%sql-fetch #:%sql-cancel #:db-connect #:%new-db-connection-handle #:%new-environment-handle #:%sql-connect #:%sql-driver-connect #:disable-autocommit #:enable-autocommit #:%sql-free-environment #:%sql-data-sources #:%sql-get-info #:%sql-param-data #:%sql-execute #:%put-str #:%sql-bind-parameter #:%sql-prepare #:sqlfetch #:%bind-column #:%allocate-bindings #:%describe-column #:%describe-columns #:read-data #:read-data-in-chunks #:query-database #:%new-statement-handle #:%sql-exec-direct #:result-columns-count #:result-rows-count #:sql-to-c-type #:%list-tables #:%table-statistics #:%list-data-sources ) (:documentation "This is the low-level interface ODBC.")) cl-sql-6.7.2/examples/0000755000175000017500000000000010667176647013575 5ustar kevinkevincl-sql-6.7.2/examples/run-tests.sh0000744000175000017500000000355310667176647016104 0ustar kevinkevin#!/bin/bash REPORT_FILE=/tmp/clsql-test-report.txt SEXP_REPORT_FILE=/tmp/clsql-test-report.sexp LISP_CMD_FILE=/tmp/clsql-test.lisp CMD=" (setq *print-readably* nil) (let ((boot-file (merge-pathnames (parse-namestring #+allegro \".clinit.cl\" #+cmu \".cmucl-init.lisp\" #+lispworks \".lispworks\" #+openmcl \"openmcl-init.lisp\" #+sbcl \".sbclrc\" #+scl \".scl-init.lisp\" ) (user-homedir-pathname)))) (if (probe-file boot-file) (load boot-file) (warn \"Unable to load boot file ~A.\" boot-file))) (asdf:operate 'asdf:load-op 'clsql-tests) (clsql-tests:run-tests-append-report-file \"${REPORT_FILE}\") #+allegro (excl:exit) #+clisp (#+lisp=cl ext:quit #-lisp=cl lisp:quit) #+cmu (ext:quit) #+lispworks (lw:quit) #+openmcl (ccl:quit) #+sbcl (sb-ext:quit) #+scl (ext:quit)" SUMMARY_CMD=" (asdf:operate 'asdf:load-op 'clsql-tests) (clsql-tests:summarize-test-report \"${SEXP_REPORT_FILE}\") #+allegro (excl:exit :quiet t) #+clisp (#+lisp=cl ext:quit #-lisp=cl lisp:quit) #+cmu (ext:quit) #+lispworks (lw:quit) #+openmcl (ccl:quit) #+sbcl (sb-ext:quit)) #+scl (ext:quit)" rm -rf $REPORT_FILE $SEXP_REPORT_FILE $LISP_CMD_FILE echo $CMD > $LISP_CMD_FILE ALLEGRO=mlisp if [ "`which $ALLEGRO`" ]; then $ALLEGRO -q -L $LISP_CMD_FILE fi CMUCL=lisp if [ "`which $CMUCL`" ]; then $CMUCL -init $LISP_CMD_FILE fi LISPWORKS=lw-console #if [ "`which $LISPWORKS`" ]; then $LISPWORKS -init $LISP_CMD_FILE #fi OPENCML=openmcl #if [ "`which $OPENMCL`" ]; then $OPENMCL -init $LISP_CMD_FILE #fi SBCL=sbcl if [ "`which $SBCL`" ]; then $SBCL --noinform --disable-debugger --userinit $LISP_CMD_FILE fi if [ -s $SEXP_REPORT_FILE ]; then echo "$SUMMARY_CMD" | $SBCL fi #rm -rf $LISP_CMD_FILE cl-sql-6.7.2/examples/clsql-tutorial.lisp0000644000175000017500000001374410667176647017456 0ustar kevinkevin(asdf:operate 'asdf:load-op 'clsql) (in-package #:clsql-user) ;; You must set these variables to appropriate values. (defvar *tutorial-database-type* nil "Possible values are :postgresql :postgresql-socket, :mysql, :oracle, :odbc, :aodbc or :sqlite") (defvar *tutorial-database-name* "clsqltut" "The name of the database we will work in.") (defvar *tutorial-database-user* "" "The name of the database user we will work as.") (defvar *tutorial-database-server* "" "The name of the database server if required") (defvar *tutorial-database-password* "" "The password if required") (clsql:def-view-class employee () ((emplid :db-kind :key :db-constraints :not-null :type integer :initarg :emplid) (first-name :accessor first-name :type (string 30) :initarg :first-name) (last-name :accessor last-name :type (string 30) :initarg :last-name) (email :accessor employee-email :type (string 100) :initarg :email) (companyid :type integer :initarg :companyid) (company :accessor employee-company :db-kind :join :db-info (:join-class company :home-key companyid :foreign-key companyid :set nil)) (managerid :type integer :initarg :managerid) (manager :accessor employee-manager :db-kind :join :db-info (:join-class employee :home-key managerid :foreign-key emplid :set nil))) (:base-table employee)) (clsql:def-view-class company () ((companyid :db-kind :key :db-constraints :not-null :type integer :initarg :companyid) (name :type (string 100) :initarg :name) (presidentid :type integer :initarg :presidentid) (president :reader president :db-kind :join :db-info (:join-class employee :home-key presidentid :foreign-key emplid :set nil)) (employees :reader company-employees :db-kind :join :db-info (:join-class employee :home-key companyid :foreign-key companyid :set t))) (:base-table company)) ;; Connect to the database (see the CLSQL documentation for vendor ;; specific connection specs). (case *tutorial-database-type* ((:mysql :postgresql :postgresql-socket) (clsql:connect `(,*tutorial-database-server* ,*tutorial-database-name* ,*tutorial-database-user* ,*tutorial-database-password*) :database-type *tutorial-database-type*)) ((:odbc :aodbc :oracle) (clsql:connect `(,*tutorial-database-name* ,*tutorial-database-user* ,*tutorial-database-password*) :database-type *tutorial-database-type*)) (:sqlite (clsql:connect `(,*tutorial-database-name*) :database-type *tutorial-database-type*))) ;; Record the sql going out, helps us learn what is going ;; on behind the scenes (clsql:start-sql-recording) ;; Create the tables for our view classes ;; First we drop them, ignoring any errors (ignore-errors (clsql:drop-view-from-class 'employee) (clsql:drop-view-from-class 'company)) (clsql:create-view-from-class 'employee) (clsql:create-view-from-class 'company) ;; Create some instances of our view classes (defvar company1 (make-instance 'company :companyid 1 :name "Widgets Inc." ;; Lenin is president of Widgets Inc. :presidentid 1)) (defvar employee1 (make-instance 'employee :emplid 1 :first-name "Vladamir" :last-name "Lenin" :email "lenin@soviet.org" :companyid 1)) (defvar employee2 (make-instance 'employee :emplid 2 :first-name "Josef" :last-name "Stalin" :email "stalin@soviet.org" :companyid 1 ;; Lenin manages Stalin (for now) :managerid 1)) (clsql:update-records-from-instance employee1) (clsql:update-records-from-instance employee2) (clsql:update-records-from-instance company1) ;; lets use the functional sql interface (clsql:locally-enable-sql-reader-syntax) (format t "The email address of ~A ~A is ~A" (first-name employee1) (last-name employee1) (employee-email employee1)) (setf (employee-email employee1) "lenin-nospam@soviets.org") ;; Update the database (clsql:update-records-from-instance employee1) (let ((new-lenin (car (clsql:select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)))) (format t "His new email is ~A" (employee-email new-lenin))) ;; Some queries ;; all employees (clsql:select 'employee) ;; all companies (clsql:select 'company) ;; employees named Lenin (clsql:select 'employee :where [= [slot-value 'employee 'last-name] "Lenin"]) (clsql:select 'company :where [= [slot-value 'company 'name] "Widgets Inc."]) ;; Employees of Widget's Inc. (clsql:select 'employee :where [and [= [slot-value 'employee 'companyid] [slot-value 'company 'companyid]] [= [slot-value 'company 'name] "Widgets Inc."]]) ;; Same thing, except that we are using the employee ;; relation in the company view class to do the join for us, ;; saving us the work of writing out the SQL! (company-employees company1) ;; President of Widgets Inc. (president company1) ;; Manager of Josef Stalin (employee-manager employee2) cl-sql-6.7.2/examples/sqlite3/0000755000175000017500000000000010667176647015161 5ustar kevinkevincl-sql-6.7.2/examples/sqlite3/init-func/0000755000175000017500000000000012134025332017024 5ustar kevinkevincl-sql-6.7.2/examples/sqlite3/init-func/example.lisp0000644000175000017500000000562012134025332021353 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: example.lisp ;;;; Purpose: Sample code for SQLite 3 initialization functions ;;;; Authors: Aurelio Bignoli ;;;; Created: Oct 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* ;;;; Load CLSQL. (asdf:oos 'asdf:load-op :clsql-sqlite3) ;;;; Load sqlite3-utils.so library. See Makefile for library creation. (unless (uffi:load-foreign-library "/usr/lib/clsql/sqlite3-utils.so" :module "sqlite3-utils" :supporting-libraries '("c")) (error "Unable to load foreign library")) ;;;; Define the foreign function to be used as init function. (uffi:def-function ("create_iso_8859_15_ci_collation" create-coll) ((db sqlite3:sqlite3-db)) :returning :int :module "sqlite3-utils") ;;;; Create the DB using create-coll as init function. (defparameter db-name "init-func-test.db") (clsql:destroy-database (list db-name) :database-type :sqlite3) (clsql:connect (list db-name #'create-coll) :database-type :sqlite3) ;;;; Create a table. Field f2 uses the newly defined collating ;;;; sequence. (clsql:execute-command "CREATE TABLE t1 (f1 CHAR(1), f2 CHAR(1) COLLATE ISO_8859_15_CI)") ;;;; Populate the table. (clsql:execute-command "INSERT INTO t1 VALUES ('à', 'à')") (clsql:execute-command "INSERT INTO t1 VALUES ('a', 'a')") (clsql:execute-command "INSERT INTO t1 VALUES ('A', 'A')") (clsql:execute-command "INSERT INTO t1 VALUES ('é', 'é')") (clsql:execute-command "INSERT INTO t1 VALUES ('e', 'e')") (clsql:execute-command "INSERT INTO t1 VALUES ('E', 'E')") (clsql:execute-command "INSERT INTO t1 VALUES ('ì', 'ì')") (clsql:execute-command "INSERT INTO t1 VALUES ('i', 'i')") (clsql:execute-command "INSERT INTO t1 VALUES ('I', 'I')") (clsql:execute-command "INSERT INTO t1 VALUES ('ò', 'ò')") (clsql:execute-command "INSERT INTO t1 VALUES ('o', 'o')") (clsql:execute-command "INSERT INTO t1 VALUES ('O', 'O')") (clsql:execute-command "INSERT INTO t1 VALUES ('ù', 'ù')") (clsql:execute-command "INSERT INTO t1 VALUES ('u', 'u')") (clsql:execute-command "INSERT INTO t1 VALUES ('U', 'U')") ;;;; Perform some SELECTs. (format t "~&SELECT * FROM t1 ==> ~A~%"(clsql:query "SELECT * FROM t1")) (format t "~&SELECT * FROM t1 ORDER BY f1 ==> ~A~%" (clsql:query "SELECT * FROM t1 ORDER BY f1")) (format t "~&SELECT * FROM t1 ORDER BY f2 ==> ~A~%" (clsql:query "SELECT * FROM t1 ORDER BY f2")) ;;;; Disconnect from database. (clsql:disconnect) cl-sql-6.7.2/examples/sqlite3/init-func/iso-8859-15-coll.c0000644000175000017500000000675411335067642021577 0ustar kevinkevin/**************************************************************************** * FILE IDENTIFICATION * * Name: iso-8859-15-coll.c * Purpose: SQLite 3 initialization function for * ISO-8859-15 collating sequence. * Programmer: Aurelio Bignoli * Date Started: Oct 2004 * * This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli * * CLSQL users are granted the rights to distribute and use this software * as governed by the terms of the Lisp Lesser GNU Public License * (http://opensource.franz.com/preamble.html), also known as the LLGPL. ***************************************************************************/ /* Collating sequence name. CI = Case Insensitive */ #define ISO_8859_15_CI_NAME "ISO_8859_15_CI" /* Conversion table. */ const unsigned char iso_8859_15_ci [] = { /* 0 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 1 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* 2 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, /* 3 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, /* 4 */ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, /* 5 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, /* 6 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, /* 7 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, /* 8 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x73, 0x8B, 0x6F, 0x8D, 0x7A, 0x79, /* 9 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x73, 0x9B, 0x6F, 0x9D, 0x7A, 0x79, /* A */ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x73, 0xA7, 0x73, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, /* B */ 0xB0, 0xB1, 0xB2, 0xB3, 0x7A, 0xB5, 0xB6, 0xB7, 0x7A, 0xB9, 0xBA, 0xBB, 0x6F, 0xBD, 0x79, 0xBF, /* C */ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x65, 0x63, 0x65, 0x65, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69, /* D */ 0x64, 0x6E, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0xD7, 0x6F, 0x75, 0x75, 0x75, 0x75, 0x79, 0xDE, 0x73, /* E */ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x65, 0x63, 0x65, 0x65, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69, /* F */ 0x64, 0x6E, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0xF7, 0x6F, 0x75, 0x75, 0x75, 0x75, 0x79, 0xFE, 0x73 }; /* * A modified version of sqlite3StrNICmp in sqlite/src/util.c */ int iso_8859_15_ci_StrCmp(const char *zLeft, const char *zRight, int N){ register unsigned char *a, *b; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( N-- > 0 && *a!=0 && iso_8859_15_ci[*a]==iso_8859_15_ci[*b]){ a++; b++; } return N<0 ? 0 : iso_8859_15_ci[*a] - iso_8859_15_ci[*b]; } /* * A modified version of nocaseCollatinFunc in sqlite/src/main.c. */ int iso_8859_15_ci_CollatingFunc( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ int r = iso_8859_15_ci_StrCmp( (const char *)pKey1, (const char *)pKey2, (nKey1" :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL ODBC Driver" :long-description "cl-sql-odbc package provides a database driver to the ODBC database system." :depends-on (clsql clsql-uffi) :components ((:module :db-odbc :components ((:file "odbc-package") (:file "odbc-loader" :depends-on ("odbc-package")) (:file "odbc-constants" :depends-on ("odbc-loader")) (:file "odbc-ff-interface" :depends-on ("odbc-constants")) (:file "odbc-api" :depends-on ("odbc-ff-interface" "odbc-constants")) (:file "odbc-dbi" :depends-on ("odbc-api")) (:file "odbc-sql" :depends-on ("odbc-dbi")))))) cl-sql-6.7.2/db-aodbc/0000755000175000017500000000000014327126007013370 5ustar kevinkevincl-sql-6.7.2/db-aodbc/aodbc-package.lisp0000644000175000017500000000211311335067642016724 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: aodbc-package.cl ;;;; Purpose: Package definition for CLSQL AODBC backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) #+allegro (eval-when (:compile-toplevel :load-toplevel :execute) (require :aodbc-v2)) #-allegro (warn "This system requires Allegro's AODBC library to operate") (defpackage #:clsql-aodbc (:nicknames #:aodbc) (:use #:common-lisp #:clsql-sys) (:export #:aodbc-database) (:documentation "This is the CLSQL interface to Allegro's AODBC")) cl-sql-6.7.2/db-aodbc/aodbc-sql.lisp0000644000175000017500000000711211335067642016134 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: aodbc-sql.cl ;;;; Purpose: Low-level interface for CLSQL AODBC backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-aodbc) ;; interface foreign library loading routines (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :aodbc))) "T if foreign library was able to be loaded successfully. " (when (find-package :dbi) ;; finds Allegro's DBI (AODBC) package t)) (defmethod clsql-sys:database-type-load-foreign ((databae-type (eql :aodbc))) t) (when (find-package :dbi) (clsql-sys:database-type-load-foreign :aodbc)) ;; AODBC interface (defclass aodbc-database (generic-odbc-database) ((aodbc-db-type :accessor database-aodbc-db-type :initform :unknown))) (defmethod database-name-from-spec (connection-spec (database-type (eql :aodbc))) (check-connection-spec connection-spec database-type (dsn user password)) (destructuring-bind (dsn user password) connection-spec (declare (ignore password)) (concatenate 'string dsn "/" user))) (defmethod database-connect (connection-spec (database-type (eql :aodbc))) (check-connection-spec connection-spec database-type (dsn user password)) #+aodbc-v2 (destructuring-bind (dsn user password) connection-spec (handler-case (make-instance 'aodbc-database :name (database-name-from-spec connection-spec :aodbc) :database-type :aodbc :dbi-package (find-package '#:dbi) :odbc-conn (dbi:connect :user user :password password :data-source-name dsn)) (sql-error (e) (error e)) (error () ;; Init or Connect failed (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :message "Connection failed"))))) (defmethod database-query (query-expression (database aodbc-database) result-types field-names) #+aodbc-v2 (handler-case (dbi:sql query-expression :db (clsql-sys::odbc-conn database) :types result-types :column-names field-names) #+ignore (error () (error 'sql-database-data-error :database database :expression query-expression :message "Query failed")))) (defmethod database-create (connection-spec (type (eql :aodbc))) (warn "Not implemented.")) (defmethod database-destroy (connection-spec (type (eql :aodbc))) (warn "Not implemented.")) (defmethod database-probe (connection-spec (type (eql :aodbc))) (warn "Not implemented.")) ;;; Backend capabilities (defmethod database-underlying-type ((database aodbc-database)) (database-aodbc-db-type database)) (defmethod db-backend-has-create/destroy-db? ((db-type (eql :aodbc))) nil) (defmethod database-initialize-database-type ((database-type (eql :aodbc))) t) (when (clsql-sys:database-type-library-loaded :aodbc) (clsql-sys:initialize-database-type :database-type :aodbc)) cl-sql-6.7.2/db-aodbc/Makefile0000644000175000017500000000011510667176647015047 0ustar kevinkevinSUBDIRS := include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/db-oracle/0000755000175000017500000000000014327126007013565 5ustar kevinkevincl-sql-6.7.2/db-oracle/oracle-objects.lisp0000644000175000017500000001110711335067642017357 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: oracle-objects.lisp ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-oracle) (defmethod database-get-type-specifier (type args database (db-type (eql :oracle))) (declare (ignore type args database)) (format nil "VARCHAR2(~D)" *default-string-length*)) (defmethod database-get-type-specifier ((type (eql 'integer)) args database (db-type (eql :oracle))) (declare (ignore database)) (if args (format nil "NUMBER(~A,~A)" (or (first args) 38) (or (second args) 0)) "INTEGER")) (defmethod database-get-type-specifier ((type (eql 'bigint)) args database (db-type (eql :oracle))) (declare (ignore args database)) "CHAR(20)") (defmethod database-get-type-specifier ((type (eql 'universal-time)) args database (db-type (eql :oracle))) (declare (ignore args database)) "CHAR(20)") (defmethod database-get-type-specifier ((type (eql 'string)) args database (db-type (eql :oracle))) (declare (ignore database)) (if args (format nil "CHAR(~A)" (car args)) (format nil "VARCHAR2(~D)" *default-string-length*))) (defmethod database-get-type-specifier ((type (eql 'varchar)) args database (db-type (eql :oracle))) (declare (ignore database)) (if args (format nil "VARCHAR2(~A)" (car args)) (format nil "VARCHAR2(~D)" *default-string-length*))) (defmethod database-get-type-specifier ((type (eql 'float)) args database (db-type (eql :oracle))) (declare (ignore database)) (if args (format nil "NUMBER(~A,~A)" (or (first args) 38) (or (second args) 38)) "DOUBLE PRECISION")) (defmethod database-get-type-specifier ((type (eql 'long-float)) args database (db-type (eql :oracle))) (declare (ignore database)) (if args (format nil "NUMBER(~A,~A)" (or (first args) 38) (or (second args) 38)) "DOUBLE PRECISION")) (defmethod database-get-type-specifier ((type (eql 'boolean)) args database (db-type (eql :oracle))) (declare (ignore args database)) "CHAR(1)") (defmethod database-get-type-specifier ((type (eql 'generalized-boolean)) args database (db-type (eql :oracle))) (declare (ignore args database)) "CHAR(1)") (defmethod read-sql-value (val type database (db-type (eql :oracle))) ;;(format t "value is \"~A\" of type ~A~%" val (type-of val)) (declare (ignore type database)) (etypecase val (string (read-from-string val)) (symbol nil))) (defmethod read-sql-value (val (type (eql 'integer)) database (db-type (eql :oracle))) (declare (ignore database)) val) (defmethod read-sql-value (val (type (eql 'float)) database (db-type (eql :oracle))) (declare (ignore database)) val) (defmethod read-sql-value (val (type (eql 'boolean)) database (db-type (eql :oracle))) (declare (ignore database)) (when (char-equal #\t (schar val 0)) t)) (defmethod read-sql-value (val (type (eql 'generalized-boolean)) database (db-type (eql :oracle))) (declare (ignore database)) (when (char-equal #\t (schar val 0)) t)) (defmethod read-sql-value (val (type (eql 'bigint)) database (db-type (eql :oracle))) (declare (ignore database)) (parse-integer val)) (defmethod read-sql-value (val (type (eql 'universal-time)) database (db-type (eql :oracle))) (declare (ignore database)) (parse-integer val)) (defmethod database-get-type-specifier ((type (eql 'wall-time)) args database (db-type (eql :oracle))) (declare (ignore args database)) "DATE") (defmethod database-get-type-specifier ((type (eql 'duration)) args database (db-type (eql :oracle))) (declare (ignore args database)) "NUMBER(38)") cl-sql-6.7.2/db-oracle/oracle-sql.lisp0000644000175000017500000013216312506332747016535 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: oracle-sql.lisp ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-oracle) (defmethod database-initialize-database-type ((database-type (eql :oracle))) t) ;;;; arbitrary parameters, tunable for performance or other reasons (eval-when (:compile-toplevel :load-toplevel :execute) (defconstant +errbuf-len+ 512 "the number of characters that we allocate for an error message buffer") (defconstant +n-buf-rows+ 200 "the number of table rows that we buffer at once when reading a table. CMUCL has a compiled-in limit on how much C data can be allocated (through malloc() and friends) at any given time, typically 8 Mb. Setting this constant to a moderate value should make it less likely that we'll have to worry about the CMUCL limit.")) (uffi:def-type vp-type :pointer-void) (uffi:def-type vpp-type (* :pointer-void)) (defmacro deref-vp (foreign-object) `(the vp-type (uffi:deref-pointer (the vpp-type ,foreign-object) :pointer-void))) (uffi:def-pointer-var +unsigned-char-null-pointer+ (uffi:make-null-pointer :unsigned-char)) (uffi:def-pointer-var +unsigned-short-null-pointer+ (uffi:make-null-pointer :unsigned-short)) (uffi:def-pointer-var +unsigned-int-null-pointer+ (uffi:make-null-pointer :unsigned-int)) ;; constants - from OCI? (defconstant +var-not-in-list+ 1007) (defconstant +no-data-found+ 1403) (defconstant +null-value-returned+ 1405) (defconstant +field-truncated+ 1406) (eval-when (:compile-toplevel :load-toplevel :execute) (defconstant SQLT-NUMBER 2) (defconstant SQLT-INT 3) (defconstant SQLT-FLT 4) (defconstant SQLT-STR 5) (defconstant SQLT-DATE 12)) ;;; Note that despite the suggestive class name (and the way that the ;;; *DEFAULT-DATABASE* variable holds an object of this class), a DB ;;; object is not actually a database but is instead a connection to a ;;; database. Thus, there's no obstacle to having any number of DB ;;; objects referring to the same database. (uffi:def-type pointer-pointer-void (* :pointer-void)) (defclass oracle-database (database) ; was struct db ((envhp :reader envhp :initarg :envhp :type pointer-pointer-void :documentation "OCI environment handle") (errhp :reader errhp :initarg :errhp :type pointer-pointer-void :documentation "OCI error handle") (svchp :reader svchp :initarg :svchp :type pointer-pointer-void :documentation "OCI service context handle") (data-source-name :initarg :dsn :initform nil :documentation "optional data source name (used only for debugging/printing)") (user :initarg :user :reader user :type string :documentation "the \"user\" value given when data source connection was made") (date-format :initarg :date-format :reader date-format :initform "YYYY-MM-DD HH24:MI:SS\".0\"") (date-format-length :type number :documentation "Each database connection can be configured with its own date output format. In order to extract date strings from output buffers holding multiple date strings in fixed-width fields, we need to know the length of that format.") (server-version :type (or null string) :initarg :server-version :reader server-version :documentation "Version string of Oracle server.") (major-server-version :type (or null fixnum) :initarg :major-server-version :reader major-server-version :documentation "The major version number of the Oracle server, should be 8, 9, or 10"))) ;;; Handle a non-successful result from an OCI function. (defun handle-oci-result (result database nulls-ok) (case result (#.+oci-success+ +oci-success+) (#.+oci-error+ (handle-oci-error :database database :nulls-ok nulls-ok)) (#.+oci-no-data+ (error 'sql-database-error :message "OCI No Data Found")) (#.+oci-success-with-info+ (error 'sql-database-error :message "internal error: unexpected +oci-success-with-info")) (#.+oci-invalid-handle+ (error 'sql-database-error :message "OCI Invalid Handle")) (#.+oci-need-data+ (error 'sql-database-error :message "OCI Need Data")) (#.+oci-still-executing+ (error 'sql-temporary-error :message "OCI Still Executing")) (#.+oci-continue+ (error 'sql-database-error :message "OCI Continue")) (1804 (error 'sql-database-error :message "Check ORACLE_HOME and NLS settings.")) (t (error 'sql-database-error :message (format nil "OCI unknown error, code=~A" result))))) ;;; Handle the messy case of return code=+oci-error+, querying the ;;; system for subcodes and reporting them as appropriate. ERRHP and ;;; NULLS-OK are as in the OERR function. (defun handle-oci-error (&key database nulls-ok) (cond (database (with-slots (errhp) database (let ((errcode (uffi:allocate-foreign-object 'sb4)) (errbuf (uffi:allocate-foreign-string #.+errbuf-len+))) ;; ensure errbuf empty string (setf (uffi:deref-array errbuf '(:array :unsigned-char) 0) (uffi:ensure-char-storable (code-char 0))) (setf (uffi:deref-pointer errcode 'sb4) 0) (uffi:with-cstring (sqlstate nil) (oci-error-get (deref-vp errhp) 1 sqlstate errcode (uffi:char-array-to-pointer errbuf) +errbuf-len+ +oci-htype-error+)) (let ((subcode (uffi:deref-pointer errcode 'sb4)) (errstr (uffi:convert-from-foreign-string errbuf :encoding (when database (encoding database))))) (uffi:free-foreign-object errcode) (uffi:free-foreign-object errbuf) (unless (and nulls-ok (= subcode +null-value-returned+)) (error 'sql-database-error :database database :error-id subcode :message errstr)))))) (nulls-ok (error 'sql-database-error :database database :message "can't handle NULLS-OK without ERRHP")) (t (error 'sql-database-error :database database :message "OCI Error (and no ERRHP available to find subcode)")))) ;;; Require an OCI success code. ;;; ;;; (The ordinary OCI error reporting mechanisms uses a fair amount of ;;; machinery (environments and other handles). In order to get to ;;; where we can use these mechanisms, we have to be able to allocate ;;; the machinery. The functions for allocating the machinery can ;;; return errors (e.g. out of memory) but shouldn't. Wrapping this function ;;; around function calls to such have-to-succeed functions enforces ;;; this condition.) (defun osucc (code) (declare (type fixnum code)) (unless (= code +oci-success+) (error 'sql-database-error :message (format nil "unexpected OCI failure, code=~S" code)))) ;;; Enabling this can be handy for low-level debugging. #+nil (progn (trace #-oci7 oci-env-create oci-initialize oci-handle-alloc oci-logon oci-error-get oci-stmt-prepare oci-stmt-execute oci-param-get oci-logon oci-attr-get oci-define-by-pos oci-stmt-fetch) (setf debug::*debug-print-length* nil)) ;; Return the INDEXth string of the OCI array, represented as Lisp ;; SIMPLE-STRING. SIZE is the size of the fixed-width fields used by ;; Oracle to store strings within the array. (uffi:def-type string-pointer (* :unsigned-char)) (defun deref-oci-string (arrayptr string-index size encoding) (declare (type string-pointer arrayptr)) (declare (type (mod #.+n-buf-rows+) string-index)) (declare (type (and unsigned-byte fixnum) size)) (let ((str (uffi:convert-from-foreign-string (uffi:make-pointer (+ (uffi:pointer-address arrayptr) (* string-index size)) :unsigned-char) :encoding encoding))) (if (string-equal str "NULL") nil str))) ;; the OCI library, part Z: no-longer used logic to convert from ;; Oracle's binary date representation to Common Lisp's native date ;; representation #+nil (defvar +oci-date-bytes+ 7) ;;; Return the INDEXth date in the OCI array, represented as ;;; a Common Lisp "universal time" (i.e. seconds since 1900). #+nil (defun deref-oci-date (arrayptr index) (oci-date->universal-time (uffi:pointer-address (uffi:deref-array arrayptr '(:array :unsigned-char) (* index +oci-date-bytes+))))) #+nil (defun oci-date->universal-time (oci-date) (declare (type (alien (* :unsigned-char)) oci-date)) (flet (;; a character from OCI-DATE, interpreted as an unsigned byte (ub (i) (declare (type (mod #.+oci-date-bytes+) i)) (mod (uffi:deref-array oci-date string-array i) 256))) (let* ((century (* (- (ub 0) 100) 100)) (year (+ century (- (ub 1) 100))) (month (ub 2)) (day (ub 3)) (hour (1- (ub 4))) (minute (1- (ub 5))) (second (1- (ub 6)))) (encode-universal-time second minute hour day month year)))) (defmethod database-list-tables ((database oracle-database) &key owner) (let ((query (cond ((null owner) "select table_name from user_tables") ((eq owner :all) "select table_name from all_tables") (t (format nil "select user_tables.table_name from user_tables,all_tables where user_tables.table_name=all_tables.table_name and all_tables.owner='~:@(~A~)'" owner))))) (mapcar #'car (database-query query database nil nil)))) (defmethod database-list-views ((database oracle-database) &key owner) (let ((query (cond ((null owner) "select view_name from user_views") ((eq owner :all) "select view_name from all_views") (t (format nil "select user_views.view_name from user_views,all_views where user_views.view_name=all_views.view_name and all_views.owner='~:@(~A~)'" owner))))) (mapcar #'car (database-query query database nil nil)))) (defmethod database-list-indexes ((database oracle-database) &key (owner nil)) (let ((query (cond ((null owner) "select index_name from user_indexes") ((eq owner :all) "select index_name from all_indexes") (t (format nil "select user_indexes.index_name from user_indexes,all_indexes where user_indexes.index_name=all_indexes.index_name and all_indexes.owner='~:@(~A~)'" owner))))) (mapcar #'car (database-query query database nil nil)))) (defmethod database-list-table-indexes (table (database oracle-database) &key (owner nil)) (let ((query (cond ((null owner) (format nil "select index_name from user_indexes where table_name='~A'" table)) ((eq owner :all) (format nil "select index_name from all_indexes where table_name='~A'" table)) (t (format nil "select user_indexes.index_name from user_indexes,all_indexes where user_indexes.table_name='~A' and user_indexes.index_name=all_indexes.index_name and all_indexes.owner='~:@(~A~)'" table owner))))) (mapcar #'car (database-query query database nil nil)))) (defmethod database-list-attributes (table (database oracle-database) &key owner) (let ((query (cond ((null owner) (format nil "select column_name from user_tab_columns where table_name='~A'" table)) ((eq owner :all) (format nil "select column_name from all_tab_columns where table_name='~A'" table)) (t (format nil "select user_tab_columns.column_name from user_tab_columns,all_tables where user_tab_columns.table_name='~A' and all_tables.table_name=user_tab_columns.table_name and all_tables.owner='~:@(~A~)'" table owner))))) (mapcar #'car (database-query query database nil nil)))) (defmethod database-attribute-type (attribute (table string) (database oracle-database) &key (owner nil)) (let ((query (cond ((null owner) (format nil "select data_type,data_length,data_scale,nullable from user_tab_columns where table_name='~A' and column_name='~A'" table attribute)) ((eq owner :all) (format nil "select data_type,data_length,data_scale,nullable from all_tab_columns where table_name='~A' and column_name='~A'" table attribute)) (t (format nil "select data_type,data_length,data_scale,nullable from user_tab_columns,all_tables where user_tab_columns.table_name='~A' and column_name='~A' and all_tables.table_name=user_tab_columns.table_name and all_tables.owner='~:@(~A~)'" table attribute owner))))) (destructuring-bind (type length scale nullable) (car (database-query query database :auto nil)) (values (ensure-keyword type) length scale (if (char-equal #\Y (schar nullable 0)) 1 0))))) ;; Return one row of the table referred to by QC, represented as a ;; list; or if there are no more rows, signal an error if EOF-ERRORP, ;; or return EOF-VALUE otherwise. ;; KLUDGE: This CASE statement is a strong sign that the code would be ;; cleaner if CD were made into an abstract class, we made variant ;; classes for CD-for-column-of-strings, CD-for-column-of-floats, ;; etc., and defined virtual functions to handle operations like ;; get-an-element-from-column. (For a small special purpose module ;; like this, would arguably be overkill, so I'm not going to do it ;; now, but if this code ends up getting more complicated in ;; maintenance, it would become a really good idea.) ;; Arguably this would be a good place to signal END-OF-FILE, but ;; since the ANSI spec specifically says that END-OF-FILE means a ;; STREAM which has no more data, and QC is not a STREAM, we signal ;; DBI-ERROR instead. (uffi:def-type short-array (* :short)) (uffi:def-type int-array (* :int)) (uffi:def-type double-array (* :double)) (uffi:def-type int-pointer (* :int)) (uffi:def-type double-pointer (* :double)) ;;; the result of a database query: a cursor through a table (defstruct (oracle-result-set (:print-function print-query-cursor) (:conc-name qc-) (:constructor %make-query-cursor)) (db (error "missing DB") ; db conn. this table is associated with :type oracle-database :read-only t) (stmthp (error "missing STMTHP") ; the statement handle used to create ;; :type alien ; this table. owned by the QUERY-CURSOR :read-only t) ; object, deallocated on CLOSE-QUERY (cds) ; (error "missing CDS") ; column descriptors ; :type (simple-array cd 1) ; :read-only t) (n-from-oci 0 ; buffered rows: number of rows recv'd :type (integer 0 #.+n-buf-rows+)) ; from the database on the last read (n-to-dbi 0 ; number of buffered rows returned, i.e. :type (integer 0 #.+n-buf-rows+)) ; the index, within the buffered rows, ; of the next row which hasn't already ; been returned (total-n-from-oci 0 ; total number of bytes recv'd from OCI :type unsigned-byte) ; in all reads (oci-end-seen-p nil)) ; Have we seen the end of OCI ; data, i.e. OCI returning ; less data than we requested? ; OCI doesn't seem to like us ; to try to read more data ; from it after that.. (defun fetch-row (qc &optional (eof-errorp t) eof-value encoding) (declare (optimize (speed 3))) (cond ((zerop (qc-n-from-oci qc)) (if eof-errorp (error 'sql-database-error :message (format nil "no more rows available in ~S" qc)) eof-value)) ((>= (qc-n-to-dbi qc) (qc-n-from-oci qc)) (refill-qc-buffers qc) (fetch-row qc nil eof-value encoding)) (t (let ((cds (qc-cds qc)) (reversed-result nil) (irow (qc-n-to-dbi qc))) (dotimes (icd (length cds)) (let* ((cd (aref cds icd)) (b (foreign-resource-buffer (cd-buffer cd))) (value (let* ((arb (foreign-resource-buffer (cd-indicators cd))) (indicator (uffi:deref-array arb '(:array :short) irow))) (declare (type short-array arb)) (unless (= indicator -1) (ecase (cd-oci-data-type cd) (#.SQLT-STR (deref-oci-string b irow (cd-sizeof cd) encoding)) (#.SQLT-FLT (locally (declare (type double-array b)) (uffi:deref-array b '(:array :double) irow))) (#.SQLT-INT (ecase (cd-sizeof cd) (4 (locally (declare (type int-array b)) (uffi:deref-array b '(:array :int) irow))))) (#.SQLT-DATE (deref-oci-string b irow (cd-sizeof cd) encoding))))))) (when (and (eq :string (cd-result-type cd)) value (not (stringp value))) (setq value (write-to-string value))) (push value reversed-result))) (incf (qc-n-to-dbi qc)) (nreverse reversed-result))))) (defun refill-qc-buffers (qc) (with-slots (errhp) (qc-db qc) (setf (qc-n-to-dbi qc) 0) (cond ((qc-oci-end-seen-p qc) (setf (qc-n-from-oci qc) 0)) (t (let ((oci-code (%oci-stmt-fetch (deref-vp (qc-stmthp qc)) (deref-vp errhp) +n-buf-rows+ +oci-fetch-next+ +oci-default+))) (ecase oci-code (#.+oci-success+ (values)) (#.+oci-no-data+ (setf (qc-oci-end-seen-p qc) t) (values)) (#.+oci-error+ (handle-oci-error :database (qc-db qc) :nulls-ok t)))) (uffi:with-foreign-object (rowcount 'ub4) (oci-attr-get (deref-vp (qc-stmthp qc)) +oci-htype-stmt+ rowcount +unsigned-int-null-pointer+ +oci-attr-row-count+ (deref-vp errhp)) (setf (qc-n-from-oci qc) (- (uffi:deref-pointer rowcount 'ub4) (qc-total-n-from-oci qc))) (when (< (qc-n-from-oci qc) +n-buf-rows+) (setf (qc-oci-end-seen-p qc) t)) (setf (qc-total-n-from-oci qc) (uffi:deref-pointer rowcount 'ub4))))) (values))) ;; the guts of the SQL function ;; ;; (like the SQL function, but with the QUERY argument hardwired to T, so ;; that the return value is always a cursor instead of a list) ;; Is this a SELECT statement? SELECT statements are handled ;; specially by OCIStmtExecute(). (Non-SELECT statements absolutely ;; require a nonzero iteration count, while the ordinary choice for a ;; SELECT statement is a zero iteration count. ;; SELECT statements are the only statements which return tables. We ;; don't free STMTHP in this case, but instead give it to the new ;; QUERY-CURSOR, and the new QUERY-CURSOR becomes responsible for ;; freeing the STMTHP when it is no longer needed. (defun sql-stmt-exec (sql-stmt-string db result-types field-names) (with-slots (envhp svchp errhp) db (uffi:with-foreign-strings ((c-stmt-string sql-stmt-string)) (let ((stmthp (uffi:allocate-foreign-object :pointer-void)) select-p) (uffi:with-foreign-object (stmttype :unsigned-short) (unwind-protect (progn (oci-handle-alloc (deref-vp envhp) stmthp +oci-htype-stmt+ 0 +null-void-pointer-pointer+) (oci-stmt-prepare (deref-vp stmthp) (deref-vp errhp) c-stmt-string (uffi:foreign-string-length c-stmt-string) +oci-ntv-syntax+ +oci-default+ :database db) (oci-attr-get (deref-vp stmthp) +oci-htype-stmt+ stmttype +unsigned-int-null-pointer+ +oci-attr-stmt-type+ (deref-vp errhp) :database db) (setq select-p (= (uffi:deref-pointer stmttype :unsigned-short) 1)) (let ((iters (if select-p 0 1))) (oci-stmt-execute (deref-vp svchp) (deref-vp stmthp) (deref-vp errhp) iters 0 +null-void-pointer+ +null-void-pointer+ +oci-default+ :database db))) ;; free resources unless a query (unless select-p (oci-handle-free (deref-vp stmthp) +oci-htype-stmt+) (uffi:free-foreign-object stmthp)))) (cond (select-p (make-query-cursor db stmthp result-types field-names)) (t nil)))))) ;; Return a QUERY-CURSOR representing the table returned from the OCI ;; operation done through STMTHP. TYPES is the argument of the same ;; name from the external SQL function, controlling type conversion ;; of the returned arguments. (defun make-query-cursor (db stmthp result-types field-names) (let ((qc (%make-query-cursor :db db :stmthp stmthp :cds (make-query-cursor-cds db stmthp result-types field-names)))) (refill-qc-buffers qc) qc)) ;; the hairy part of MAKE-QUERY-CURSOR: Ask OCI for information ;; about table columns, translate the information into a Lisp ;; vector of column descriptors, and return it. ;; Allegro defines several flavors of type conversion, but this ;; implementation only supports the :AUTO flavor. ;; A note of explanation: OCI's internal number format uses 21 ;; bytes (42 decimal digits). 2 separate (?) one-byte fields, ;; scale and precision, are used to deduce the nature of these ;; 21 bytes. See pp. 3-10, 3-26, and 6-13 of OCI documentation ;; for more details. ;; Mac OS X Note: According to table 6-8 in the Oracle 9i OCI ;; documentation, PRECISION may actually be an sb2 instead of a ;; single byte if performing an "implicit describe". Using a ;; signed short instead of an unsigned byte fixes a Mac OS X bug ;; where PRECISION is always zero. -- JJB 20040713 ;; When calling OCI C code to handle the conversion, we have ;; only two numeric types available to pass the return value: ;; double-float and signed-long. It would be possible to ;; bypass the OCI conversion functions and write Lisp code ;; which reads the 21-byte field directly and decodes ;; it. However this is left as an exercise for the reader. :-) ;; The following table describes the mapping, based on the implicit ;; assumption that C's "signed long" type is a 32-bit integer. ;; ;; Internal Values SQL Type C Return Type ;; =============== ======== ============= ;; Precision > 0 SCALE = -127 FLOAT --> double-float ;; Precision > 0 && <=9 SCALE = 0 INTEGER --> signed-long ;; Precision = 0 || > 9 SCALE = 0 BIG INTEGER --> double-float ;; Precision > 0 SCALE > 0 DECIMAL --> double-float ;; (OCI uses 1-based indexing here.) ;; KLUDGE: This should work for all other data types except those ;; which don't actually fit in their fixed-width field (BLOBs and the ;; like). As Winton says, we (Cadabra) don't need to worry much about ;; those, since we can't reason with them, so we don't use them. But ;; for a more general application it'd be good to have a more ;; selective and rigorously correct test here for whether we can ;; actually handle the given DEREF-DTYPE value. -- WHN 20000106 ;; Note: The OCI documentation doesn't seem to say whether the COLNAME ;; value returned here is a newly-allocated copy which we're ;; responsible for freeing, or a pointer into some system copy which ;; will be freed when the system itself is shut down. But judging ;; from the way that the result is used in the cdemodsa.c example ;; program, it looks like the latter: we should make our own copy of ;; the value, but not try to free it. ;; WORKAROUND: OCI seems to return ub2 values for the ;; +oci-attr-data-size+ attribute even though its documentation claims ;; that it returns a ub4, and even though the associated "sizep" value ;; is 4, not 2. In order to make the code here work reliably, without ;; having to patch it later if OCI is ever fixed to match its ;; documentation, we pre-zero COLSIZE before making the call into OCI. ;; To exercise the weird OCI behavior (thereby blowing up the code ;; below, beware!) try setting this value into COLSIZE, calling OCI, ;; then looking at the value in COLSIZE. (setf colsize #x12345678) ;; debugging only ;; Mac OS X Note: This workaround fails on a bigendian platform so ;; I've changed the data type of COLNAME to :unsigned-short as per ;; the Oracle 9i OCI documentation. -- JJB 20040713 (uffi:def-type byte-pointer (* :byte)) (uffi:def-type void-pointer-pointer (* :void-pointer)) (defun make-query-cursor-cds (database stmthp result-types field-names) (declare (optimize (safety 3) #+nil (speed 3)) (type oracle-database database) (type pointer-pointer-void stmthp)) (with-slots (errhp) database (uffi:with-foreign-objects ((dtype-foreign :unsigned-short) (parmdp :pointer-void) (precision :short) (scale :byte) (colname '(* :unsigned-char)) (colnamelen 'ub4) (colsize 'ub2) (defnp ':pointer-void)) (let ((buffer nil) (sizeof nil)) (do ((icolumn 0 (1+ icolumn)) (cds-as-reversed-list nil)) ((not (eql (oci-param-get (deref-vp stmthp) +oci-htype-stmt+ (deref-vp errhp) parmdp (1+ icolumn) :database database) +oci-success+)) (coerce (reverse cds-as-reversed-list) 'simple-vector)) ;; Decode type of ICOLUMNth column into a type we're prepared to ;; handle in Lisp. (oci-attr-get (deref-vp parmdp) +oci-dtype-param+ dtype-foreign +unsigned-int-null-pointer+ +oci-attr-data-type+ (deref-vp errhp)) (let ((dtype (uffi:deref-pointer dtype-foreign :unsigned-short))) (declare (fixnum dtype)) (case dtype (#.SQLT-DATE (setf buffer (acquire-foreign-resource :unsigned-char (* 32 +n-buf-rows+))) (setf sizeof 32 dtype #.SQLT-STR)) (#.SQLT-NUMBER (oci-attr-get (deref-vp parmdp) +oci-dtype-param+ precision +unsigned-int-null-pointer+ +oci-attr-precision+ (deref-vp errhp)) (oci-attr-get (deref-vp parmdp) +oci-dtype-param+ scale +unsigned-int-null-pointer+ +oci-attr-scale+ (deref-vp errhp)) (let ((*scale (uffi:deref-pointer scale :byte)) (*precision (uffi:deref-pointer precision :short))) ;;(format t "scale=~d, precision=~d~%" *scale *precision) (cond ((or (and (minusp *scale) (zerop *precision)) (and (zerop *scale) (plusp *precision))) (setf buffer (acquire-foreign-resource :int +n-buf-rows+) sizeof 4 ;; sizeof(int) dtype #.SQLT-INT)) (t (setf buffer (acquire-foreign-resource :double +n-buf-rows+) sizeof 8 ;; sizeof(double) dtype #.SQLT-FLT))))) ;; Default to SQL-STR (t (setf (uffi:deref-pointer colsize :unsigned-short) 0) (setf dtype #.SQLT-STR) (oci-attr-get (deref-vp parmdp) +oci-dtype-param+ colsize +unsigned-int-null-pointer+ +oci-attr-data-size+ (deref-vp errhp)) (let ((colsize-including-null (1+ (uffi:deref-pointer colsize :unsigned-short)))) (setf buffer (acquire-foreign-resource :unsigned-char (* +n-buf-rows+ colsize-including-null))) (setf sizeof colsize-including-null)))) (let ((retcodes (acquire-foreign-resource :unsigned-short +n-buf-rows+)) (indicators (acquire-foreign-resource :short +n-buf-rows+)) (colname-string "")) (when field-names (oci-attr-get (deref-vp parmdp) +oci-dtype-param+ colname colnamelen +oci-attr-name+ (deref-vp errhp)) (setq colname-string (uffi:convert-from-foreign-string (uffi:deref-pointer colname '(* :unsigned-char)) :length (uffi:deref-pointer colnamelen 'ub4) :encoding (encoding database)))) (push (make-cd :name colname-string :sizeof sizeof :buffer buffer :oci-data-type dtype :retcodes retcodes :indicators indicators :result-type (cond ((consp result-types) (nth icolumn result-types)) ((null result-types) :string) (t result-types))) cds-as-reversed-list) (oci-define-by-pos (deref-vp stmthp) defnp (deref-vp errhp) (1+ icolumn) ; OCI 1-based indexing again (foreign-resource-buffer buffer) sizeof dtype (foreign-resource-buffer indicators) +unsigned-short-null-pointer+ (foreign-resource-buffer retcodes) +oci-default+)))))))) ;; Release the resources associated with a QUERY-CURSOR. (defun close-query (qc) (oci-handle-free (deref-vp (qc-stmthp qc)) +oci-htype-stmt+) (uffi:free-foreign-object (qc-stmthp qc)) (let ((cds (qc-cds qc))) (dotimes (i (length cds)) (release-cd-resources (aref cds i)))) (values)) ;; Release the resources associated with a column description. (defun release-cd-resources (cd) (free-foreign-resource (cd-buffer cd)) (free-foreign-resource (cd-retcodes cd)) (free-foreign-resource (cd-indicators cd)) (values)) (defmethod database-name-from-spec (connection-spec (database-type (eql :oracle))) (check-connection-spec connection-spec database-type (dsn user password)) (destructuring-bind (dsn user password) connection-spec (declare (ignore password)) (concatenate 'string dsn "/" user))) (defmethod database-connect (connection-spec (database-type (eql :oracle))) (check-connection-spec connection-spec database-type (dsn user password)) (destructuring-bind (data-source-name user password) connection-spec (let ((envhp (uffi:allocate-foreign-object :pointer-void)) (errhp (uffi:allocate-foreign-object :pointer-void)) (svchp (uffi:allocate-foreign-object :pointer-void)) (srvhp (uffi:allocate-foreign-object :pointer-void))) ;; Requests to allocate environments and handles should never ;; fail in normal operation, and they're done too early to ;; handle errors very gracefully (since they're part of the ;; error-handling mechanism themselves) so we just assert they ;; work. (setf (deref-vp envhp) +null-void-pointer+) #-oci7 (oci-env-create envhp +oci-default+ +null-void-pointer+ +null-void-pointer+ +null-void-pointer+ +null-void-pointer+ 0 +null-void-pointer-pointer+) #+oci7 (progn (oci-initialize +oci-object+ +null-void-pointer+ +null-void-pointer+ +null-void-pointer+ +null-void-pointer-pointer+) (ignore-errors (oci-handle-alloc +null-void-pointer+ envhp +oci-htype-env+ 0 +null-void-pointer-pointer+)) ;no testing return (oci-env-init envhp +oci-default+ 0 +null-void-pointer-pointer+)) (oci-handle-alloc (deref-vp envhp) errhp +oci-htype-error+ 0 +null-void-pointer-pointer+) (oci-handle-alloc (deref-vp envhp) srvhp +oci-htype-server+ 0 +null-void-pointer-pointer+) (let ((db (make-instance 'oracle-database :name (database-name-from-spec connection-spec database-type) :connection-spec connection-spec :envhp envhp :errhp errhp :database-type :oracle :svchp svchp :dsn data-source-name :user user))) (uffi:with-foreign-strings ((c-user user) (c-password password) (c-data-source-name data-source-name)) (oci-logon (deref-vp envhp) (deref-vp errhp) svchp c-user (length user) c-password (length password) c-data-source-name (length data-source-name) :database db)) ;; :date-format-length (1+ (length date-format))))) (setf (slot-value db 'clsql-sys::state) :open) (database-execute-command (format nil "ALTER SESSION SET NLS_DATE_FORMAT='~A'" (date-format db)) db) (let ((server-version (caar (database-query "SELECT BANNER FROM V$VERSION WHERE BANNER LIKE '%Oracle%'" db nil nil)))) (setf (slot-value db 'server-version) server-version (slot-value db 'major-server-version) (major-client-version-from-string server-version))) db)))) (defun major-client-version-from-string (str) (cond ((search " 10g " str) 10) ((search "Oracle9i " str) 9) ((search "Oracle8" str) 8))) (defun major-server-version-from-string (str) (when (> (length str) 2) (cond ((string= "10." (subseq str 0 3)) 10) ((string= "9." (subseq str 0 2)) 9) ((string= "8." (subseq str 0 2)) 8)))) ;; Close a database connection. (defmethod database-disconnect ((database oracle-database)) (osucc (oci-logoff (deref-vp (svchp database)) (deref-vp (errhp database)))) (osucc (oci-handle-free (deref-vp (envhp database)) +oci-htype-env+)) ;; Note: It's neither required nor allowed to explicitly deallocate the ;; ERRHP handle here, since it's owned by the ENVHP deallocated above, ;; and was therefore automatically deallocated at the same time. t) ;;; Do the database operation described in SQL-STMT-STRING on database ;;; DB and, if the command is a SELECT, return a representation of the ;;; resulting table. The representation of the table is controlled by the ;;; QUERY argument: ;;; * If QUERY is NIL, the table is returned as a list of rows, with ;;; each row represented by a list. ;;; * If QUERY is non-NIL, the result is returned as a QUERY-CURSOR ;;; suitable for FETCH-ROW and CLOSE-QUERY ;;; The TYPES argument controls the type conversion method used ;;; to construct the table. The Allegro version supports several possible ;;; values for this argument, but we only support :AUTO. (defmethod database-query (query-expression (database oracle-database) result-types field-names) (let ((cursor (sql-stmt-exec query-expression database result-types field-names))) ;; (declare (type (or query-cursor null) cursor)) (if (null cursor) ; No table was returned. (values) (do ((reversed-result nil)) (nil) (let* ((eof-value :eof) (row (fetch-row cursor nil eof-value (encoding database)))) (when (eq row eof-value) (close-query cursor) (if field-names (return (values (nreverse reversed-result) (loop for cd across (qc-cds cursor) collect (cd-name cd)))) (return (nreverse reversed-result)))) (push row reversed-result)))))) (defmethod database-create-sequence (sequence-name (database oracle-database)) (execute-command (concatenate 'string "CREATE SEQUENCE " (sql-escape sequence-name)) :database database)) (defmethod database-drop-sequence (sequence-name (database oracle-database)) (execute-command (concatenate 'string "DROP SEQUENCE " (sql-escape sequence-name)) :database database)) (defmethod database-sequence-next (sequence-name (database oracle-database)) (caar (database-query (concatenate 'string "SELECT " (sql-escape sequence-name) ".NEXTVAL FROM dual") database :auto nil))) (defmethod database-sequence-last (sequence-name (database oracle-database)) (caar (database-query (concatenate 'string "SELECT " (sql-escape sequence-name) ".CURRVAL FROM dual") database :auto nil))) (defmethod database-set-sequence-position (name position (database oracle-database)) (without-interrupts (let* ((next (database-sequence-next name database)) (incr (- position next))) (unless (zerop incr) (database-execute-command (format nil "ALTER SEQUENCE ~A INCREMENT BY ~D" name incr) database)) (database-sequence-next name database) (database-execute-command (format nil "ALTER SEQUENCE ~A INCREMENT BY 1" name) database)))) (defmethod database-list-sequences ((database oracle-database) &key owner) (let ((query (cond ((null owner) "select sequence_name from user_sequences") ((eq owner :all) "select sequence_name from all_sequences") (t (format nil "select user_sequences.sequence_name from user_sequences,all_sequences where user_sequences.sequence_name=all_sequences.sequence_name and all_sequences.sequence_owner='~:@(~A~)'" owner))))) (mapcar #'car (database-query query database nil nil)))) (defmethod database-execute-command (sql-expression (database oracle-database)) (database-query sql-expression database nil nil) (when (database-autocommit database) (oracle-commit database)) t) (defstruct (cd (:constructor make-cd) (:print-function print-cd)) "a column descriptor: metadata about the data in a table" ;; name of this column (name (error "missing NAME") :type simple-string :read-only t) ;; the size in bytes of a single element (sizeof (error "missing SIZE") :type fixnum :read-only t) ;; an array of +N-BUF-ROWS+ elements in C representation (buffer (error "Missing BUFFER") :type foreign-resource :read-only t) ;; an array of +N-BUF-ROWS+ OCI return codes in C representation. ;; (There must be one return code for every element of every ;; row in order to be able to represent nullness.) (retcodes (error "Missing RETCODES") :type foreign-resource :read-only t) (indicators (error "Missing INDICATORS") :type foreign-resource :read-only t) ;; the OCI code for the data type of a single element (oci-data-type (error "missing OCI-DATA-TYPE") :type fixnum :read-only t) (result-type (error "missing RESULT-TYPE") :read-only t)) (defun print-cd (cd stream depth) (declare (ignore depth)) (print-unreadable-object (cd stream :type t) (format stream ":NAME ~S :OCI-DATA-TYPE ~S :OCI-DATA-SIZE ~S" (cd-name cd) (cd-oci-data-type cd) (cd-sizeof cd)))) (defun print-query-cursor (qc stream depth) (declare (ignore depth)) (print-unreadable-object (qc stream :type t :identity t) (prin1 (qc-db qc) stream))) (defmethod database-query-result-set ((query-expression string) (database oracle-database) &key full-set result-types) (let ((cursor (sql-stmt-exec query-expression database result-types nil))) (if full-set (values cursor (length (qc-cds cursor)) nil) (values cursor (length (qc-cds cursor)))))) (defmethod database-dump-result-set (result-set (database oracle-database)) (close-query result-set)) (defmethod database-store-next-row (result-set (database oracle-database) list) (let* ((eof-value :eof) (row (fetch-row result-set nil eof-value (encoding database)))) (unless (eq eof-value row) (loop for i from 0 below (length row) do (setf (nth i list) (nth i row))) list))) (defmethod database-start-transaction ((database oracle-database)) (call-next-method) ;; Not needed with simple transaction #+ignore (with-slots (svchp errhp) database (oci-trans-start (deref-vp svchp) (deref-vp errhp) 60 +oci-trans-new+)) t) (defun oracle-commit (database) (with-slots (svchp errhp) database (osucc (oci-trans-commit (deref-vp svchp) (deref-vp errhp) 0)))) (defmethod database-commit-transaction ((database oracle-database)) (call-next-method) (oracle-commit database) t) (defmethod database-abort-transaction ((database oracle-database)) (call-next-method) (osucc (oci-trans-rollback (deref-vp (svchp database)) (deref-vp (errhp database)) 0)) t) ;; Specifications (defmethod db-type-has-bigint? ((type (eql :oracle))) nil) (defmethod db-type-has-fancy-math? ((db-type (eql :oracle))) t) (defmethod db-type-has-boolean-where? ((db-type (eql :oracle))) nil) (when (clsql-sys:database-type-library-loaded :oracle) (clsql-sys:initialize-database-type :database-type :oracle)) cl-sql-6.7.2/db-oracle/foreign-resources.lisp0000644000175000017500000000346611335067642020135 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-oracle) (defparameter *foreign-resource-hash* (make-hash-table :test #'equal)) (defstruct (foreign-resource) (type (error "Missing TYPE.") :read-only t) (sizeof (error "Missing SIZEOF.") :read-only t) (buffer (error "Missing BUFFER.") :read-only t) (in-use nil :type boolean)) (defun %get-resource (type sizeof) (let ((resources (gethash type *foreign-resource-hash*))) (car (member-if #'(lambda (res) (and (= (foreign-resource-sizeof res) sizeof) (not (foreign-resource-in-use res)))) resources)))) (defun %insert-foreign-resource (type res) (let ((resource (gethash type *foreign-resource-hash*))) (setf (gethash type *foreign-resource-hash*) (cons res resource)))) (defmacro acquire-foreign-resource (type &optional size) `(let ((res (%get-resource ,type ,size))) (unless res (setf res (make-foreign-resource :type ,type :sizeof ,size :buffer (uffi:allocate-foreign-object ,type ,size))) (%insert-foreign-resource ',type res)) (claim-foreign-resource res))) (defun free-foreign-resource (ares) (setf (foreign-resource-in-use ares) nil) ares) (defun claim-foreign-resource (ares) (setf (foreign-resource-in-use ares) t) ares) cl-sql-6.7.2/db-oracle/oracle-api.lisp0000644000175000017500000002615511335067642016510 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: oracle.lisp ;;;; Purpose: Package definition for CLSQL Oracle interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-oracle) ;; ;; OCI integer types ;; (uffi:def-foreign-type ub2 :unsigned-short) (uffi:def-foreign-type sb2 :short) (uffi:def-foreign-type ub4 :unsigned-int) (uffi:def-foreign-type sb4 :int) (uffi:def-foreign-type size_t :unsigned-long) ;; ;; Opaque pointer types ;; (uffi:def-foreign-type void-pointer :pointer-void) (uffi:def-foreign-type oci-env :pointer-void) (uffi:def-foreign-type oci-server :pointer-void) (uffi:def-foreign-type oci-error :pointer-void) (uffi:def-foreign-type oci-svc-ctx :pointer-void) (uffi:def-foreign-type oci-stmt :pointer-void) (uffi:def-pointer-var +null-void-pointer+ (uffi:make-null-pointer :void)) (uffi:def-pointer-var +null-void-pointer-pointer+ (uffi:make-null-pointer :pointer-void)) ;;; Check an OCI return code for erroricity and signal a reasonably ;;; informative condition if so. ;;; ;;; ERRHP provides an error handle which can be used to find ;;; subconditions; if it's not provided, subcodes won't be checked. ;;; ;;; NULLS-OK says that a NULL-VALUE-RETURNED subcondition condition is ;;; normal and needn't cause any signal. An error handle is required ;;; to detect this subcondition, so it doesn't make sense to set ERRHP ;;; unless NULLS-OK is set. (defmacro def-oci-routine ((c-oci-symbol lisp-oci-fn) c-return &rest c-parms) (let ((ll (mapcar (lambda (x) (declare (ignore x)) (gensym)) c-parms)) (c-oci-fn (intern (concatenate 'string "%" (symbol-name lisp-oci-fn))))) `(progn (declaim (inline ,c-oci-fn ,lisp-oci-fn)) (uffi:def-function (,c-oci-symbol ,c-oci-fn) ,c-parms :returning ,c-return) (defun ,lisp-oci-fn (,@ll &key database nulls-ok) (let ((result (,c-oci-fn ,@ll))) (if (= result #.+oci-success+) +oci-success+ (handle-oci-result result database nulls-ok))))))) (defmacro def-raw-oci-routine ((c-oci-symbol lisp-oci-fn) c-return &rest c-parms) (let ((ll (mapcar (lambda (x) (declare (ignore x)) (gensym)) c-parms))) `(let ((%lisp-oci-fn (uffi:def-function (,c-oci-symbol ,(intern (concatenate 'string "%" (symbol-name lisp-oci-fn)))) ,c-parms :returning ,c-return))) (defun ,lisp-oci-fn (,@ll &key database nulls-ok) (declare (ignore database nulls-ok)) (funcall %lisp-oci-fn ,@ll))))) (def-oci-routine ("OCIInitialize" oci-initialize) :int (mode ub4) ; ub4 (ctxp :pointer-void) ; dvoid * (malocfp :pointer-void) ; dvoid *(*) (ralocfp :pointer-void) ; dvoid *(*) (mfreefp (* :pointer-void))) ; void *(*) (def-oci-routine ("OCIEnvInit" oci-env-init) :int (envpp :pointer-void) ; OCIEnv ** (mode ub4) ; ub4 (xtramem-sz size_t) ; size_t (usermempp (* :pointer-void))) ; dvoid ** #-oci7 (def-oci-routine ("OCIEnvCreate" oci-env-create) :int (envhpp (* :pointer-void)) (mode ub4) (ctxp :pointer-void) (malocfp :pointer-void) (ralocfp :pointer-void) (mfreefp :pointer-void) (xtramemsz size_t) (usrmempp (* :pointer-void))) (def-oci-routine ("OCIHandleAlloc" oci-handle-alloc) :int (parenth :pointer-void) ; const dvoid * (hndlpp (* :pointer-void)) ; dvoid ** (type ub4) ; ub4 (xtramem_sz size_t) ; size_t (usrmempp (* :pointer-void))) ; dvoid ** (def-oci-routine ("OCIServerAttach" oci-server-attach) :int (srvhp :pointer-void) ; oci-server (errhp :pointer-void) ; oci-error (dblink :cstring) ; :in (dblink-len sb4) ; sb4 (mode ub4)) ; ub4 (def-oci-routine ("OCIHandleFree" oci-handle-free) :int (p0 :pointer-void) ;; handle (p1 ub4)) ;;type (def-oci-routine ("OCILogon" oci-logon) :int (envhp :pointer-void) ; env (errhp :pointer-void) ; err (svchpp (* :pointer-void)) ; svc (username (* :unsigned-char)) ; username (uname-len ub4) ; (passwd (* :unsigned-char)) ; passwd (password-len ub4) ; (dsn (* :unsigned-char)) ; datasource (dsn-len ub4)) ; (def-oci-routine ("OCILogoff" oci-logoff) :int (p0 :pointer-void) ; svc (p1 :pointer-void)) ; err (declaim (inline oci-error-get)) (uffi:def-function ("OCIErrorGet" oci-error-get) ((handlp :pointer-void) (recordno ub4) (sqlstate :cstring) (errcodep (* sb4)) (bufp (* :unsigned-char)) (bufsize ub4) (type ub4)) :returning :void) (def-oci-routine ("OCIStmtPrepare" oci-stmt-prepare) :int (stmtp :pointer-void) (errhp :pointer-void) (stmt (* :unsigned-char)) (stmt_len ub4) (language ub4) (mode ub4)) (def-oci-routine ("OCIStmtExecute" oci-stmt-execute) :int (svchp :pointer-void) (stmtp1 :pointer-void) (errhp :pointer-void) (iters ub4) (rowoff ub4) (snap_in :pointer-void) (snap_out :pointer-void) (mode ub4)) (def-raw-oci-routine ("OCIParamGet" oci-param-get) :int (hndlp :pointer-void) (htype ub4) (errhp :pointer-void) (parmdpp (* :pointer-void)) (pos ub4)) (def-oci-routine ("OCIAttrGet" oci-attr-get) :int (trgthndlp :pointer-void) (trghndltyp ub4) (attributep :pointer-void) (sizep (* ub4)) (attrtype ub4) (errhp :pointer-void)) (def-oci-routine ("OCIAttrSet" oci-attr-set) :int (trgthndlp :pointer-void) (trgthndltyp ub4 :in) (attributep :pointer-void) (size ub4) (attrtype ub4) (errhp oci-error)) (def-oci-routine ("OCIDefineByPos" oci-define-by-pos) :int (stmtp :pointer-void) (defnpp (* :pointer-void)) (errhp :pointer-void) (position ub4) (valuep :pointer-void) (value_sz sb4) (dty ub2) (indp (* sb2)) (rlenp (* ub2)) (rcodep (* ub2)) (mode ub4)) (def-oci-routine ("OCIStmtFetch" oci-stmt-fetch) :int (stmthp :pointer-void) (errhp :pointer-void) (p2 ub4) (p3 ub2) (p4 ub4)) (def-oci-routine ("OCITransStart" oci-trans-start) :int (svchp :pointer-void) (errhp :pointer-void) (p2 :unsigned-short) (p3 :unsigned-short)) (def-oci-routine ("OCITransCommit" oci-trans-commit) :int (svchp :pointer-void) (errhp :pointer-void) (p2 :unsigned-short)) (def-oci-routine ("OCITransRollback" oci-trans-rollback) :int (svchp :pointer-void) (errhp :pointer-void) (p2 :unsigned-short)) (def-oci-routine ("OCIServerVersion" oci-server-version) :int (handlp :pointer-void) (errhp :pointer-void) (bufp (* :unsigned-char)) (bufsz :int) (hndltype :short)) ;;; Low-level routines that don't do error checking. They are used ;;; for setting up global environment. (uffi:def-function "OCIInitialize" ((mode ub4) ; ub4 (ctxp :pointer-void) ; dvoid * (malocfp :pointer-void) ; dvoid *(*) (ralocfp :pointer-void) ; dvoid *(*) (mfreefp (* :pointer-void))) :returning :int) (uffi:def-function "OCIEnvInit" ((envpp :pointer-void) ; OCIEnv ** (mode ub4) ; ub4 (xtramem-sz size_t) ; size_t (usermempp (* :pointer-void))) :returning :int) (uffi:def-function "OCIHandleAlloc" ((parenth :pointer-void) ; const dvoid * (hndlpp (* :pointer-void)) ; dvoid ** (type ub4) ; ub4 (xtramem_sz size_t) ; size_t (usrmempp (* :pointer-void))) :returning :int) (defstruct oci-handle (type :unknown) (pointer (uffi:allocate-foreign-object :pointer-void))) (defvar *oci-initialized* nil) (defvar *oci-env* nil) (defvar *oci-handle-types* '(:error ; error report handle (OCIError) :service-context ; service context handle (OCISvcCtx) :statement ; statement (application request) handle (OCIStmt) :describe ; select list description handle (OCIDescribe) :server ; server context handle (OCIServer) :session ; user session handle (OCISession) :transaction ; transaction context handle (OCITrans) :complex-object ; complex object retrieval handle (OCIComplexObject) :security)) ; security handle (OCISecurity) (defun oci-init (&key (mode +oci-default+)) (let ((x (OCIInitialize mode +null-void-pointer+ +null-void-pointer+ +null-void-pointer+ +null-void-pointer-pointer+))) (if (= x 0) (let ((env (uffi:allocate-foreign-object :pointer-void))) (setq *oci-initialized* mode) (let ((x (OCIEnvInit env +oci-default+ 0 +null-void-pointer+))) (format t ";; OEI: returned ~d~%" x) (setq *oci-env* env)))))) (defun oci-check-return (value) (when (= value +oci-invalid-handle+) (error 'sql-database-error :message "Invalid Handle"))) (defun oci-get-handle (&key type) (if (null *oci-initialized*) (oci-init)) (case type (:error (let ((ptr (uffi:allocate-foreign-object :pointer-void))) (let ((x (OCIHandleAlloc (uffi:deref-pointer *oci-env* void-pointer) ptr +oci-default+ 0 +null-void-pointer-pointer+))) (oci-check-return x) ptr))) (:service-context "OCISvcCtx") (:statement "OCIStmt") (:describe "OCIDescribe") (:server "OCIServer") (:session "OCISession") (:transaction "OCITrans") (:complex-object "OCIComplexObject") (:security "OCISecurity") (t (error 'sql-database-error :message (format nil "'~s' is not a valid OCI handle type" type))))) (defun oci-environment () (let ((envhp (oci-get-handle :type :env))) (oci-env-init envhp 0 0 +null-void-pointer+) envhp)) cl-sql-6.7.2/db-oracle/oracle-package.lisp0000644000175000017500000000162011335067642017320 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: oracle-package.cl ;;;; Purpose: Package definition for CLSQL Oracle interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-oracle (:use #:common-lisp #:clsql-sys #:clsql-uffi) (:export #:oracle-database #:*oracle-server-version* #:*oracle-so-load-path* #:*oracle-so-libraries*) (:documentation "This is the CLSQL interface to Oracle.")) cl-sql-6.7.2/db-oracle/oracle-loader.lisp0000644000175000017500000000413411335067642017176 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: oracle-loader.lisp ;;;; Purpose: Foreign library loader for CLSQL Oracle interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-oracle) (defparameter *oracle-home* (let ((oracle-home (getenv "ORACLE_HOME"))) (when oracle-home (parse-namestring (concatenate 'string oracle-home "/")))) "Pathname of ORACLE_HOME as set in user environment.") (defparameter *oracle-client-library-filenames* (list "libclntsh" "oci")) (defvar *oracle-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the Oracle client library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *oracle-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :oracle))) *oracle-library-loaded*) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :oracle))) (when *oracle-home* (dolist (dir-name '("lib" "bin")) (dolist (lib-name '("libclntsh" "oci")) (clsql:push-library-path (make-pathname :name lib-name :directory (append (pathname-directory *oracle-home*) (list dir-name))))))) (clsql-uffi:find-and-load-foreign-library *oracle-client-library-filenames* :module "clsql-oracle" :supporting-libraries *oracle-supporting-libraries*) (setq *oracle-library-loaded* t)) (clsql-sys:database-type-load-foreign :oracle) cl-sql-6.7.2/db-oracle/oracle-constants.lisp0000644000175000017500000006553611335067642017761 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: oracle-constants.lisp ;;;; Purpose: Constants for CLSQL Oracle interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-oracle) (defconstant +oci-default+ #x00) ; default value for parameters and attributes (defconstant +oci-threaded+ #x01) ; application is in threaded environment (defconstant +oci-object+ #x02) ; the application is in object environment (defconstant +oci-non-blocking+ #x04) ; non blocking mode of operation (defconstant +oci-env-no-mutex+ #x08) ; the environment handle will not be protected by a mutex internally ;; Handle types (defconstant +oci-htype-env+ 1) ; environment handle (defconstant +oci-htype-error+ 2) ; error handle (defconstant +oci-htype-svcctx+ 3) ; service handle (defconstant +oci-htype-stmt+ 4) ; statement handle (defconstant +oci-htype-bind+ 5) ; bind handle (defconstant +oci-htype-define+ 6) ; define handle (defconstant +oci-htype-describe+ 7) ; describe handle (defconstant +oci-htype-server+ 8) ; server handle (defconstant +oci-htype-session+ 9) ; authentication handle (defconstant +oci-htype-trans+ 10) ; transaction handle (defconstant +oci-htype-complexobject+ 11) ; complex object retrieval handle (defconstant +oci-htype-security+ 12) ; security handle ;; Descriptor types (defconstant +oci-dtype-lob+ 50) ; lob locator (defconstant +oci-dtype-snap+ 51) ; snapshot (defconstant +oci-dtype-rset+ 52) ; result set (defconstant +oci-dtype-param+ 53) ; parameter descriptor obtained from ocigparm (defconstant +oci-dtype-rowid+ 54) ; rowid (defconstant +oci-dtype-complexobjectcomp+ 55) ; complex object retrieval descriptor (defconstant +oci-dtype-file+ 56) ; File Lob locator (defconstant +oci-dtype-aqenq-options+ 57) ; enqueue options (defconstant +oci-dtype-aqdeq-options+ 58) ; dequeue options (defconstant +oci-dtype-aqmsg-properties+ 59) ; message properties (defconstant +oci-dtype-aqagent+ 60) ; aq agent ;; Objectr pointer types (defconstant +oci-otype-name+ 1) ; object name (defconstant +oci-otype-ref+ 2) ; REF to TDO (defconstant +oci-otype-ptr+ 3) ; PTR to TDO ;; Attribute types (defconstant +oci-attr-fncode+ 1) ; the OCI function code (defconstant +oci-attr-object+ 2) ; is the environment initialized in object mode (defconstant +oci-attr-nonblocking-mode+ 3) ; non blocking mode (defconstant +oci-attr-sqlcode+ 4) ; the SQL verb (defconstant +oci-attr-env+ 5) ; the environment handle (defconstant +oci-attr-server+ 6) ; the server handle (defconstant +oci-attr-session+ 7) ; the user session handle (defconstant +oci-attr-trans+ 8) ; the transaction handle (defconstant +oci-attr-row-count+ 9) ; the rows processed so far (defconstant +oci-attr-sqlfncode+ 10) ; the SQL verb of the statement (defconstant +oci-attr-prefetch-rows+ 11) ; sets the number of rows to prefetch (defconstant +oci-attr-nested-prefetch-rows+ 12) ; the prefetch rows of nested table (defconstant +oci-attr-prefetch-memory+ 13) ; memory limit for rows fetched (defconstant +oci-attr-nested-prefetch-memory+ 14) ; memory limit for nested rows (defconstant +oci-attr-char-count+ 15) ; this specifies the bind and define size in characters (defconstant +oci-attr-pdscl+ 16) ; packed decimal scale (defconstant +oci-attr-pdfmt+ 17) ; packed decimal format (defconstant +oci-attr-param-count+ 18) ; number of column in the select list (defconstant +oci-attr-rowid+ 19) ; the rowid (defconstant +oci-attr-charset+ 20) ; the character set value (defconstant +oci-attr-nchar+ 21) ; NCHAR type (defconstant +oci-attr-username+ 22) ; username attribute (defconstant +oci-attr-password+ 23) ; password attribute (defconstant +oci-attr-stmt-type+ 24) ; statement type (defconstant +oci-attr-internal-name+ 25) ; user friendly global name (defconstant +oci-attr-external-name+ 26) ; the internal name for global txn (defconstant +oci-attr-xid+ 27) ; XOPEN defined global transaction id (defconstant +oci-attr-trans-lock+ 28) ; (defconstant +oci-attr-trans-name+ 29) ; string to identify a global transaction (defconstant +oci-attr-heapalloc+ 30) ; memory allocated on the heap (defconstant +oci-attr-charset-id+ 31) ; Character Set ID (defconstant +oci-attr-charset-form+ 32) ; Character Set Form (defconstant +oci-attr-maxdata-size+ 33) ; Maximumsize of data on the server (defconstant +oci-attr-cache-opt-size+ 34) ; object cache optimal size (defconstant +oci-attr-cache-max-size+ 35) ; object cache maximum size percentage (defconstant +oci-attr-pinoption+ 36) ; object cache default pin option (defconstant +oci-attr-alloc-duration+ 37) ; object cache default allocation duration (defconstant +oci-attr-pin-duration+ 38) ; object cache default pin duration (defconstant +oci-attr-fdo+ 39) ; Format Descriptor object attribute (defconstant +oci-attr-postprocessing-callback+ 40) ; Callback to process outbind data (defconstant +oci-attr-postprocessing-context+ 41) ; Callback context to process outbind data (defconstant +oci-attr-rows-returned+ 42) ; Number of rows returned in current iter - for Bind handles (defconstant +oci-attr-focbk+ 43) ; Failover Callback attribute (defconstant +oci-attr-in-v8-mode+ 44) ; is the server/service context in V8 mode (defconstant +oci-attr-lobempty+ 45) ; empty lob ? (defconstant +oci-attr-sesslang+ 46) ; session language handle ;; AQ Attribute Types ;; Enqueue Options (defconstant +oci-attr-visibility+ 47) ; visibility (defconstant +oci-attr-relative-msgid+ 48) ; relative message id (defconstant +oci-attr-sequence-deviation+ 49) ; sequence deviation ; - Dequeue Options - ; consumer name ;#define OCI-ATTR-DEQ-MODE 50 ;(defconstant +OCI-ATTR-CONSUMER-NAME 50 + 51) ; dequeue mode ;#define OCI-ATTR-NAVIGATION 52 ; navigation ;#define OCI-ATTR-WAIT 53 ; wait ;#define OCI-ATTR-DEQ-MSGID 54 ; dequeue message id ; - Message Properties - (defconstant +OCI-ATTR-PRIORITY+ 55) ; priority (defconstant +OCI-ATTR-DELAY+ 56) ; delay (defconstant +OCI-ATTR-EXPIRATION+ 57) ; expiration (defconstant +OCI-ATTR-CORRELATION+ 58) ; correlation id (defconstant +OCI-ATTR-ATTEMPTS+ 59) ; # of attempts (defconstant +OCI-ATTR-RECIPIENT-LIST+ 60) ; recipient list (defconstant +OCI-ATTR-EXCEPTION-QUEUE+ 61) ; exception queue name (defconstant +OCI-ATTR-ENQ-TIME+ 62) ; enqueue time (only OCIAttrGet) (defconstant +OCI-ATTR-MSG-STATE+ 63) ; message state (only OCIAttrGet) ;; AQ Agent (defconstant +OCI-ATTR-AGENT-NAME+ 64) ; agent name (defconstant +OCI-ATTR-AGENT-ADDRESS+ 65) ; agent address (defconstant +OCI-ATTR-AGENT-PROTOCOL+ 66) ; agent protocol ;- Server handle - (defconstant +OCI-ATTR-NATIVE-FDES+ 67) ; native cncxn file desc ;-Parameter Attribute Types- (defconstant +OCI-ATTR-UNK+ 101) ; unknown attribute (defconstant +OCI-ATTR-NUM-COLS+ 102) ; number of columns (defconstant +OCI-ATTR-LIST-COLUMNS+ 103) ; parameter of the column list (defconstant +OCI-ATTR-RDBA+ 104) ; DBA of the segment header (defconstant +OCI-ATTR-CLUSTERED+ 105) ; whether the table is clustered (defconstant +OCI-ATTR-PARTITIONED+ 106) ; whether the table is partitioned (defconstant +OCI-ATTR-INDEX-ONLY+ 107) ; whether the table is index only (defconstant +OCI-ATTR-LIST-ARGUMENTS+ 108) ; parameter of the argument list (defconstant +OCI-ATTR-LIST-SUBPROGRAMS+ 109) ; parameter of the subprogram list (defconstant +OCI-ATTR-REF-TDO+ 110) ; REF to the type descriptor (defconstant +OCI-ATTR-LINK+ 111) ; the database link name (defconstant +OCI-ATTR-MIN+ 112) ; minimum value (defconstant +OCI-ATTR-MAX+ 113) ; maximum value (defconstant +OCI-ATTR-INCR+ 114) ; increment value (defconstant +OCI-ATTR-CACHE+ 115) ; number of sequence numbers cached (defconstant +OCI-ATTR-ORDER+ 116) ; whether the sequence is ordered (defconstant +OCI-ATTR-HW-MARK+ 117) ; high-water mark (defconstant +OCI-ATTR-TYPE-SCHEMA+ 118) ; type's schema name (defconstant +OCI-ATTR-TIMESTAMP+ 119) ; timestamp of the object (defconstant +OCI-ATTR-NUM-ATTRS+ 120) ; number of sttributes (defconstant +OCI-ATTR-NUM-PARAMS+ 121) ; number of parameters (defconstant +OCI-ATTR-OBJID+ 122) ; object id for a table or view (defconstant +OCI-ATTR-PTYPE+ 123) ; type of info described by (defconstant +OCI-ATTR-PARAM+ 124) ; parameter descriptor (defconstant +OCI-ATTR-OVERLOAD-ID+ 125) ; overload ID for funcs and procs (defconstant +OCI-ATTR-TABLESPACE+ 126) ; table name space (defconstant +OCI-ATTR-TDO+ 127) ; TDO of a type (defconstant +OCI-ATTR-PARSE-ERROR-OFFSET+ 128) ; Parse Error offset ;-Credential Types- (defconstant +OCI-CRED-RDBMS+ 1) ; database username/password (defconstant +OCI-CRED-EXT+ 2) ; externally provided credentials ;; Error Return Values- (defconstant +oci-continue+ -24200) ; Continue with the body of the OCI function (defconstant +oci-still-executing+ -3123) ; OCI would block error (defconstant +oci-invalid-handle+ -2) ; maps to SQL-INVALID-HANDLE (defconstant +oci-error+ -1) ; maps to SQL-ERROR (defconstant +oci-success+ 0) ; maps to SQL-SUCCESS of SAG CLI (defconstant +oci-success-with-info+ 1) ; maps to SQL-SUCCESS-WITH-INFO (defconstant +oci-need-data+ 99) ; maps to SQL-NEED-DATA (defconstant +oci-no-data+ 100) ; maps to SQL-NO-DATA ;; Parsing Syntax Types- (defconstant +oci-ntv-syntax+ 1) ; Use what so ever is the native lang of server (defconstant +oci-v7-syntax+ 2) ; V7 language (defconstant +oci-v8-syntax+ 3) ; V8 language ;-Scrollable Cursor Options- (defconstant +oci-fetch-next+ #x02) ; next row (defconstant +oci-fetch-first+ #x04) ; first row of the result set (defconstant +oci-fetch-last+ #x08) ; the last row of the result set (defconstant +oci-fetch-prior+ #x10) ; the previous row relative to current (defconstant +oci-fetch-absolute+ #x20) ; absolute offset from first (defconstant +oci-fetch-relative+ #x40) ; offset relative to current ;-Bind and Define Options- (defconstant +OCI-SB2-IND-PTR+ #x01) ; unused (defconstant +OCI-DATA-AT-EXEC+ #x02) ; data at execute time (defconstant +OCI-DYNAMIC-FETCH+ #x02) ; fetch dynamically (defconstant +OCI-PIECEWISE+ #x04) ; piecewise DMLs or fetch ;- ;-Execution Modes- (defconstant +OCI-BATCH-MODE+ #x01) ; batch the oci statement for execution (defconstant +OCI-EXACT-FETCH+ #x02) ; fetch the exact rows specified (defconstant +OCI-KEEP-FETCH-STATE+ #x04) ; unused (defconstant +OCI-SCROLLABLE-CURSOR+ #x08) ; cursor scrollable (defconstant +OCI-DESCRIBE-ONLY+ #x10) ; only describe the statement (defconstant +OCI-COMMIT-ON-SUCCESS+ #x20) ; commit, if successful execution ;- ;-Authentication Modes- (defconstant +OCI-MIGRATE+ #x0001) ; migratable auth context (defconstant +OCI-SYSDBA+ #x0002) ; for SYSDBA authorization (defconstant +OCI-SYSOPER+ #x0004) ; for SYSOPER authorization (defconstant +OCI-PRELIM-AUTH+ #x0008) ; for preliminary authorization ;- ;-Piece Information- (defconstant +OCI-PARAM-IN+ #x01) ; in parameter (defconstant +OCI-PARAM-OUT+ #x02) ; out parameter ;- ;- Transaction Start Flags - ; NOTE: OCI-TRANS-JOIN and OCI-TRANS-NOMIGRATE not supported in 8.0.X (defconstant +OCI-TRANS-NEW+ #x00000001) ; starts a new transaction branch (defconstant +OCI-TRANS-JOIN+ #x00000002) ; join an existing transaction (defconstant +OCI-TRANS-RESUME+ #x00000004) ; resume this transaction (defconstant +OCI-TRANS-STARTMASK+ #x000000ff) (defconstant +OCI-TRANS-READONLY+ #x00000100) ; starts a readonly transaction (defconstant +OCI-TRANS-READWRITE+ #x00000200) ; starts a read-write transaction (defconstant +OCI-TRANS-SERIALIZABLE+ #x00000400) ; starts a serializable transaction (defconstant +OCI-TRANS-ISOLMASK+ #x0000ff00) (defconstant +OCI-TRANS-LOOSE+ #x00010000) ; a loosely coupled branch (defconstant +OCI-TRANS-TIGHT+ #x00020000) ; a tightly coupled branch (defconstant +OCI-TRANS-TYPEMASK+ #x000f0000) ; (defconstant +OCI-TRANS-NOMIGRATE+ #x00100000) ; non migratable transaction ;- ;- Transaction End Flags - (defconstant +OCI-TRANS-TWOPHASE+ #x01000000) ; use two phase commit ;- ;; AQ Constants ;; NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ;; The following constants must match the PL/SQL dbms-aq constants ;; NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ; - Visibility flags - (defconstant +OCI-ENQ-IMMEDIATE+ 1) ; enqueue is an independent transaction (defconstant +OCI-ENQ-ON-COMMIT+ 2) ; enqueue is part of current transaction ; - Dequeue mode flags - (defconstant +OCI-DEQ-BROWSE+ 1) ; read message without acquiring a lock (defconstant +OCI-DEQ-LOCKED+ 2) ; read and obtain write lock on message (defconstant +OCI-DEQ-REMOVE+ 3) ; read the message and delete it ; - Dequeue navigation flags - (defconstant +OCI-DEQ-FIRST-MSG+ 1) ; get first message at head of queue (defconstant +OCI-DEQ-NEXT-MSG+ 3) ; next message that is available (defconstant +OCI-DEQ-NEXT-TRANSACTION+ 2) ; get first message of next txn group ; - Message states - (defconstant +OCI-MSG-WAITING+ 1) ; the message delay has not yet completed (defconstant +OCI-MSG-READY+ 0) ; the message is ready to be processed (defconstant +OCI-MSG-PROCESSED+ 2) ; the message has been processed (defconstant +OCI-MSG-EXPIRED+ 3) ; message has moved to exception queue ; - Sequence deviation - (defconstant +OCI-ENQ-BEFORE+ 2) ; enqueue message before another message (defconstant +OCI-ENQ-TOP+ 3) ; enqueue message before all messages ; - Visibility flags - (defconstant +OCI-DEQ-IMMEDIATE+ 1) ; dequeue is an independent transaction (defconstant +OCI-DEQ-ON-COMMIT+ 2) ; dequeue is part of current transaction ; - Wait - (defconstant +OCI-DEQ-WAIT-FOREVER+ -1) ; wait forever if no message available (defconstant +OCI-DEQ-NO-WAIT+ 0) ; do not wait if no message is available ; - Delay - (defconstant +OCI-MSG-NO-DELAY+ 0) ; message is available immediately ;; Expiration (defconstant +OCI-MSG-NO-EXPIRATION+ -1) ; message will never expire ;; Describe Handle Parameter Attributes ;; Attributes common to Columns and Stored Procs (defconstant +oci-attr-data-size+ 1) ; maximum size of the data (defconstant +oci-attr-data-type+ 2) ; the sql type of the column/argument (defconstant +oci-attr-disp-size+ 3) ; the display size (defconstant +oci-attr-name+ 4) ; the name of the column/argument (defconstant +oci-attr-precision+ 5) ; precision if number type (defconstant +oci-attr-scale+ 6) ; scale if number type (defconstant +oci-attr-is-null+ 7) ; is it null ? (defconstant +oci-attr-type-name+ 8) ;; name of the named data type or a package name for package private types (defconstant +OCI-ATTR-SCHEMA-NAME+ 9) ; the schema name (defconstant +OCI-ATTR-SUB-NAME+ 10) ; type name if package private type (defconstant +OCI-ATTR-POSITION+ 11) ; relative position of col/arg in the list of cols/args ; complex object retrieval parameter attributes (defconstant +OCI-ATTR-COMPLEXOBJECTCOMP-TYPE+ 50) ; (defconstant +OCI-ATTR-COMPLEXOBJECTCOMP-TYPE-LEVEL+ 51) ; (defconstant +OCI-ATTR-COMPLEXOBJECT-LEVEL+ 52) ; (defconstant +OCI-ATTR-COMPLEXOBJECT-COLL-OUTOFLINE+ 53) ; ; Only Columns (defconstant +OCI-ATTR-DISP-NAME+ 100) ; the display name ;; stored procs (defconstant +OCI-ATTR-OVERLOAD+ 210) ; is this position overloaded (defconstant +OCI-ATTR-LEVEL+ 211) ; level for structured types (defconstant +OCI-ATTR-HAS-DEFAULT+ 212) ; has a default value (defconstant +OCI-ATTR-IOMODE+ 213) ; in, out inout (defconstant +OCI-ATTR-RADIX+ 214) ; returns a radix (defconstant +OCI-ATTR-NUM-ARGS+ 215) ; total number of arguments ;; named type attributes (defconstant +oci-attr-typecode+ 216) ; lobject or collection (defconstant +oci-attr-collection-typecode+ 217) ; varray or nested table (defconstant +oci-attr-version+ 218) ; user assigned version (defconstant +oci-attr-is-incomplete-type+ 219) ; is this an incomplete type (defconstant +oci-attr-is-system-type+ 220) ; a system type (defconstant +oci-attr-is-predefined-type+ 221) ; a predefined type (defconstant +oci-attr-is-transient-type+ 222) ; a transient type (defconstant +oci-attr-is-system-generated-type+ 223) ; system generated type (defconstant +oci-attr-has-nested-table+ 224) ; contains nested table attr (defconstant +oci-attr-has-lob+ 225) ; has a lob attribute (defconstant +oci-attr-has-file+ 226) ; has a file attribute (defconstant +oci-attr-collection-element+ 227) ; has a collection attribute (defconstant +oci-attr-num-type-attrs+ 228) ; number of attribute types (defconstant +oci-attr-list-type-attrs+ 229) ; list of type attributes (defconstant +oci-attr-num-type-methods+ 230) ; number of type methods (defconstant +oci-attr-list-type-methods+ 231) ; list of type methods (defconstant +oci-attr-map-method+ 232) ; map method of type (defconstant +oci-attr-order-method+ 233) ; order method of type ; only collection element (defconstant +OCI-ATTR-NUM-ELEMS+ 234) ; number of elements ; only type methods (defconstant +OCI-ATTR-ENCAPSULATION+ 235) ; encapsulation level (defconstant +OCI-ATTR-IS-SELFISH+ 236) ; method selfish (defconstant +OCI-ATTR-IS-VIRTUAL+ 237) ; virtual (defconstant +OCI-ATTR-IS-INLINE+ 238) ; inline (defconstant +OCI-ATTR-IS-CONSTANT+ 239) ; constant (defconstant +OCI-ATTR-HAS-RESULT+ 240) ; has result (defconstant +OCI-ATTR-IS-CONSTRUCTOR+ 241) ; constructor (defconstant +OCI-ATTR-IS-DESTRUCTOR+ 242) ; destructor (defconstant +OCI-ATTR-IS-OPERATOR+ 243) ; operator (defconstant +OCI-ATTR-IS-MAP+ 244) ; a map method (defconstant +OCI-ATTR-IS-ORDER+ 245) ; order method (defconstant +OCI-ATTR-IS-RNDS+ 246) ; read no data state method (defconstant +OCI-ATTR-IS-RNPS+ 247) ; read no process state (defconstant +OCI-ATTR-IS-WNDS+ 248) ; write no data state method (defconstant +OCI-ATTR-IS-WNPS+ 249) ; write no process state ; describing public objects (defconstant +OCI-ATTR-DESC-PUBLIC+ 250) ; public object ;- ;-OCIPasswordChange- (defconstant +OCI-AUTH+ #x08) ; Change the password but do not login ;-Other Constants- (defconstant +OCI-MAX-FNS+ 100) ; max number of OCI Functions (defconstant +OCI-SQLSTATE-SIZE+ 5) ; (defconstant +OCI-ERROR-MAXMSG-SIZE+ 1024) ; max size of an error message ;; (defconstant +OCI-LOBMAXSIZE+ 4MAXVAL) ; maximum lob data size (defconstant +OCI-ROWID-LEN+ 23) ; ;- ;- Fail Over Events - (defconstant +OCI-FO-END+ #x00000001) ; (defconstant +OCI-FO-ABORT+ #x00000002) ; (defconstant +OCI-FO-REAUTH+ #x00000004) ; (defconstant +OCI-FO-BEGIN+ #x00000008) ; (defconstant +OCI-FO-ERROR+ #x00000010) ; ;- ;- Fail Over Types - (defconstant +OCI-FO-NONE+ #x00000001) ; (defconstant +OCI-FO-SESSION+ #x00000002) ; (defconstant +OCI-FO-SELECT+ #x00000004) ; (defconstant +OCI-FO-TXNAL+ #x00000008) ; ;- ;-Function Codes- (defconstant +OCI-FNCODE-INITIALIZE+ 1) ; OCIInitialize (defconstant +OCI-FNCODE-HANDLEALLOC+ 2) ; OCIHandleAlloc (defconstant +OCI-FNCODE-HANDLEFREE+ 3) ; OCIHandleFree (defconstant +OCI-FNCODE-DESCRIPTORALLOC+ 4) ; OCIDescriptorAlloc (defconstant +OCI-FNCODE-DESCRIPTORFREE+ 5) ; OCIDescriptorFree (defconstant +OCI-FNCODE-ENVINIT+ 6) ; OCIEnvInit (defconstant +OCI-FNCODE-SERVERATTACH+ 7) ; OCIServerAttach (defconstant +OCI-FNCODE-SERVERDETACH+ 8) ; OCIServerDetach ; unused 9 (defconstant +OCI-FNCODE-SESSIONBEGIN+ 10) ; OCISessionBegin (defconstant +OCI-FNCODE-SESSIONEND+ 11) ; OCISessionEnd (defconstant +OCI-FNCODE-PASSWORDCHANGE+ 12) ; OCIPasswordChange (defconstant +OCI-FNCODE-STMTPREPARE+ 13) ; OCIStmtPrepare ; unused 14- 16 (defconstant +OCI-FNCODE-BINDDYNAMIC+ 17) ; OCIBindDynamic (defconstant +OCI-FNCODE-BINDOBJECT+ 18) ; OCIBindObject ; 19 unused (defconstant +OCI-FNCODE-BINDARRAYOFSTRUCT+ 20) ; OCIBindArrayOfStruct (defconstant +OCI-FNCODE-STMTEXECUTE+ 21) ; OCIStmtExecute ; unused 22-24 (defconstant +OCI-FNCODE-DEFINEOBJECT+ 25) ; OCIDefineObject (defconstant +OCI-FNCODE-DEFINEDYNAMIC+ 26) ; OCIDefineDynamic (defconstant +OCI-FNCODE-DEFINEARRAYOFSTRUCT+ 27) ; OCIDefineArrayOfStruct (defconstant +OCI-FNCODE-STMTFETCH+ 28) ; OCIStmtFetch (defconstant +OCI-FNCODE-STMTGETBIND+ 29) ; OCIStmtGetBindInfo ; 30, 31 unused (defconstant +OCI-FNCODE-DESCRIBEANY+ 32) ; OCIDescribeAny (defconstant +OCI-FNCODE-TRANSSTART+ 33) ; OCITransStart (defconstant +OCI-FNCODE-TRANSDETACH+ 34) ; OCITransDetach (defconstant +OCI-FNCODE-TRANSCOMMIT+ 35) ; OCITransCommit ; 36 unused (defconstant +OCI-FNCODE-ERRORGET+ 37) ; OCIErrorGet (defconstant +OCI-FNCODE-LOBOPENFILE+ 38) ; OCILobFileOpen (defconstant +OCI-FNCODE-LOBCLOSEFILE+ 39) ; OCILobFileClose ; 40 was LOBCREATEFILE, unused ; 41 was OCILobFileDelete, unused (defconstant +OCI-FNCODE-LOBCOPY+ 42) ; OCILobCopy (defconstant +OCI-FNCODE-LOBAPPEND+ 43) ; OCILobAppend (defconstant +OCI-FNCODE-LOBERASE+ 44) ; OCILobErase (defconstant +OCI-FNCODE-LOBLENGTH+ 45) ; OCILobGetLength (defconstant +OCI-FNCODE-LOBTRIM+ 46) ; OCILobTrim (defconstant +OCI-FNCODE-LOBREAD+ 47) ; OCILobRead (defconstant +OCI-FNCODE-LOBWRITE+ 48) ; OCILobWrite ; 49 unused (defconstant +OCI-FNCODE-SVCCTXBREAK+ 50) ; OCIBreak (defconstant +OCI-FNCODE-SERVERVERSION+ 51) ; OCIServerVersion ; unused 52, 53 (defconstant +OCI-FNCODE-ATTRGET+ 54) ; OCIAttrGet (defconstant +OCI-FNCODE-ATTRSET+ 55) ; OCIAttrSet (defconstant +OCI-FNCODE-PARAMSET+ 56) ; OCIParamSet (defconstant +OCI-FNCODE-PARAMGET+ 57) ; OCIParamGet (defconstant +OCI-FNCODE-STMTGETPIECEINFO+ 58) ; OCIStmtGetPieceInfo (defconstant +OCI-FNCODE-LDATOSVCCTX+ 59) ; OCILdaToSvcCtx ; 60 unused (defconstant +OCI-FNCODE-STMTSETPIECEINFO+ 61) ; OCIStmtSetPieceInfo (defconstant +OCI-FNCODE-TRANSFORGET+ 62) ; OCITransForget (defconstant +OCI-FNCODE-TRANSPREPARE+ 63) ; OCITransPrepare (defconstant +OCI-FNCODE-TRANSROLLBACK+ 64) ; OCITransRollback (defconstant +OCI-FNCODE-DEFINEBYPOS+ 65) ; OCIDefineByPos (defconstant +OCI-FNCODE-BINDBYPOS+ 66) ; OCIBindByPos (defconstant +OCI-FNCODE-BINDBYNAME+ 67) ; OCIBindByName (defconstant +OCI-FNCODE-LOBASSIGN+ 68) ; OCILobAssign (defconstant +OCI-FNCODE-LOBISEQUAL+ 69) ; OCILobIsEqual (defconstant +OCI-FNCODE-LOBISINIT+ 70) ; OCILobLocatorIsInit ; 71 was lob locator size in beta2 (defconstant +OCI-FNCODE-LOBENABLEBUFFERING+ 71) ; OCILobEnableBuffering (defconstant +OCI-FNCODE-LOBCHARSETID+ 72) ; OCILobCharSetID (defconstant +OCI-FNCODE-LOBCHARSETFORM+ 73) ; OCILobCharSetForm (defconstant +OCI-FNCODE-LOBFILESETNAME+ 74) ; OCILobFileSetName (defconstant +OCI-FNCODE-LOBFILEGETNAME+ 75) ; OCILobFileGetName (defconstant +OCI-FNCODE-LOGON+ 76) ; OCILogon (defconstant +OCI-FNCODE-LOGOFF+ 77) ; OCILogoff (defconstant +OCI-FNCODE-LOBDISABLEBUFFERING+ 78) ; OCILobDisableBuffering (defconstant +OCI-FNCODE-LOBFLUSHBUFFER+ 79) ; OCILobFlushBuffer (defconstant +OCI-FNCODE-LOBLOADFROMFILE+ 80) ; OCILobLoadFromFile ;- ;- FILE open modes - (defconstant +OCI-FILE-READONLY+ 1) ; readonly mode open for FILE types ;- ;- LOB Buffering Flush Flags - (defconstant +OCI-LOB-BUFFER-FREE+ 1) ; (defconstant +OCI-LOB-BUFFER-NOFREE+ 2) ; ;- ;- OCI Statement Types - (defconstant +oci-stmt-select+ 1) ; select statement (defconstant +oci-stmt-update+ 2) ; update statement (defconstant +oci-stmt-delete+ 3) ; delete statement (defconstant +oci-stmt-insert+ 4) ; insert statement (defconstant +oci-stmt-create+ 5) ; create statement (defconstant +oci-stmt-drop+ 6) ; drop statement (defconstant +oci-stmt-alter+ 7) ; alter statement (defconstant +oci-stmt-begin+ 8) ; begin ... (pl/sql statement) (defconstant +oci-stmt-declare+ 9) ; declare .. (pl/sql statement ) ;- ;- OCI Parameter Types - (defconstant +OCI-PTYPE-UNK+ 0) ; unknown (defconstant +OCI-PTYPE-TABLE+ 1) ; table (defconstant +OCI-PTYPE-VIEW+ 2) ; view (defconstant +OCI-PTYPE-PROC+ 3) ; procedure (defconstant +OCI-PTYPE-FUNC+ 4) ; function (defconstant +OCI-PTYPE-PKG+ 5) ; package (defconstant +OCI-PTYPE-TYPE+ 6) ; user-defined type (defconstant +OCI-PTYPE-SYN+ 7) ; synonym (defconstant +OCI-PTYPE-SEQ+ 8) ; sequence (defconstant +OCI-PTYPE-COL+ 9) ; column (defconstant +OCI-PTYPE-ARG+ 10) ; argument (defconstant +OCI-PTYPE-LIST+ 11) ; list (defconstant +OCI-PTYPE-TYPE-ATTR+ 12) ; user-defined type's attribute (defconstant +OCI-PTYPE-TYPE-COLL+ 13) ; collection type's element (defconstant +OCI-PTYPE-TYPE-METHOD+ 14) ; user-defined type's method (defconstant +OCI-PTYPE-TYPE-ARG+ 15) ; user-defined type method's argument (defconstant +OCI-PTYPE-TYPE-RESULT+ 16) ; user-defined type method's result ;- ;- OCI List Types - (defconstant +OCI-LTYPE-UNK+ 0) ; unknown (defconstant +OCI-LTYPE-COLUMN+ 1) ; column list (defconstant +OCI-LTYPE-ARG-PROC+ 2) ; procedure argument list (defconstant +OCI-LTYPE-ARG-FUNC+ 3) ; function argument list (defconstant +OCI-LTYPE-SUBPRG+ 4) ; subprogram list (defconstant +OCI-LTYPE-TYPE-ATTR+ 5) ; type attribute (defconstant +OCI-LTYPE-TYPE-METHOD+ 6) ; type method (defconstant +OCI-LTYPE-TYPE-ARG-PROC+ 7) ; type method w/o result argument list (defconstant +OCI-LTYPE-TYPE-ARG-FUNC+ 8) ; type method w/result argument list ;; typecodes cl-sql-6.7.2/db-oracle/Makefile0000644000175000017500000000124011335067642015227 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL Oracle interface # Author: Kevin M. Rosenberg # Created: May 2004 # # This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/db-oracle/README0000644000175000017500000000225610667176647014474 0ustar kevinkevinThis is the header of the cadabra source file. ;;;; The original version of this code was copyright (c) 1999-2000 Cadabra Inc. ;;;; It was placed in the public domain by Cadabra in January 2000. ;;;; ;;;; The implementors of the original version were Winton Davies ;;;; and William Newman . ;;;; known issues: ;;;; * The code will leak C resources if errors occur in the the wrong ;;;; places, since it doesn't wrap its allocation/deallocation ;;;; logic in the necessary EVAL-WHENs to prevent this. (This could be ;;;; easily be an issue for long-running processes which recover from ;;;; database errors instead of simply terminating when they occur. It's ;;;; not an issue for programs which consider database errors so abnormal ;;;; that they die immediately when they encounter one.) ;;;; * Instead of reading Oracle header files automatically, this code ;;;; uses constants, types, and function signatures manually transcribed ;;;; from the Oracle header files. Thus, changes in the header files ;;;; may require manual maintenance of the code. (This version was written ;;;; for Oracle 8.1.5.) cl-sql-6.7.2/db-db2/0000755000175000017500000000000014327126007012767 5ustar kevinkevincl-sql-6.7.2/db-db2/db2-package.lisp0000644000175000017500000000157011335067642015730 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db2-package.cl ;;;; Purpose: Package definition for CLSQL Db2 interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-db2 (:use #:common-lisp #:clsql-sys #:clsql-uffi) (:export #:db2-database #:*db2-server-version* #:*db2-so-load-path* #:*db2-so-libraries*) (:documentation "This is the CLSQL interface to Db2.")) cl-sql-6.7.2/db-db2/db2-loader.lisp0000644000175000017500000000366611335067642015613 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db2-loader.lisp ;;;; Purpose: Foreign library loader for CLSQL Db2 interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-db2) (defparameter *db2-lib-path* (let ((db2-home (getenv "DB2_HOME"))) (when db2-home (make-pathname :directory (append (pathname-directory (parse-namestring (concatenate 'string db2-home "/"))) (list "lib")))))) (defparameter *db2-library-filenames* (if *db2-lib-path* (list (merge-pathnames "libdb2" *db2-lib-path*) "libdb2") "libdb2")) (defvar *db2-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the Db2 client library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *db2-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :db2))) *db2-library-loaded*) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :db2))) (clsql-uffi:find-and-load-foreign-library *db2-library-filenames* :module "clsql-db2" :supporting-libraries *db2-supporting-libraries*) (setq *db2-library-loaded* t)) (clsql-sys:database-type-load-foreign :db2) cl-sql-6.7.2/db-db2/foreign-resources.lisp0000644000175000017500000000346311335067642017334 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-db2) (defparameter *foreign-resource-hash* (make-hash-table :test #'equal)) (defstruct (foreign-resource) (type (error "Missing TYPE.") :read-only t) (sizeof (error "Missing SIZEOF.") :read-only t) (buffer (error "Missing BUFFER.") :read-only t) (in-use nil :type boolean)) (defun %get-resource (type sizeof) (let ((resources (gethash type *foreign-resource-hash*))) (car (member-if #'(lambda (res) (and (= (foreign-resource-sizeof res) sizeof) (not (foreign-resource-in-use res)))) resources)))) (defun %insert-foreign-resource (type res) (let ((resource (gethash type *foreign-resource-hash*))) (setf (gethash type *foreign-resource-hash*) (cons res resource)))) (defmacro acquire-foreign-resource (type &optional size) `(let ((res (%get-resource ,type ,size))) (unless res (setf res (make-foreign-resource :type ,type :sizeof ,size :buffer (uffi:allocate-foreign-object ,type ,size))) (%insert-foreign-resource ',type res)) (claim-foreign-resource res))) (defun free-foreign-resource (ares) (setf (foreign-resource-in-use ares) nil) ares) (defun claim-foreign-resource (ares) (setf (foreign-resource-in-use ares) t) ares) cl-sql-6.7.2/db-db2/db2-api.lisp0000644000175000017500000000727511335067642015116 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db2.lisp ;;;; Purpose: Package definition for CLSQL Db2 interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-db2) ;; ;; Opaque pointer types ;; (uffi:def-foreign-type cli-handle :pointer-void) (uffi:def-foreign-type cli-pointer :pointer-void) (uffi:def-foreign-type cli-char :byte) (uffi:def-foreign-type cli-ulen :unsigned-int) (uffi:def-foreign-type cli-len :int) (uffi:def-foreign-type cli-smallint :short) (uffi:def-foreign-type cli-usmallint :unsigned-short) (defvar +null-void-pointer+ (uffi:make-null-pointer :void)) (defvar +null-void-pointer-pointer+ (uffi:make-null-pointer :pointer-void)) ;;; Check an CLI return code for erroricity and signal a reasonably ;;; informative condition if so. ;;; ;;; ERRHP provides an error handle which can be used to find ;;; subconditions; if it's not provided, subcodes won't be checked. ;;; ;;; NULLS-OK says that a NULL-VALUE-RETURNED subcondition condition is ;;; normal and needn't cause any signal. An error handle is required ;;; to detect this subcondition, so it doesn't make sense to set ERRHP ;;; unless NULLS-OK is set. (defmacro def-cli-routine ((c-cli-symbol lisp-cli-fn) c-return &rest c-parms) (let ((ll (mapcar (lambda (x) (declare (ignore x)) (gensym)) c-parms))) `(let ((%lisp-cli-fn (uffi:def-function (,c-cli-symbol ,(intern (concatenate 'string "%" (symbol-name lisp-cli-fn)))) ,c-parms :returning ,c-return))) (defun ,lisp-cli-fn (,@ll &key database nulls-ok) (let ((result (funcall %lisp-cli-fn ,@ll))) (case result (#.SQL_SUCCESS SQL_SUCCESS) (#.SQL_SUCCESS_WITH_INFO (format *standard-output* "sucess with info") SQL_SUCCESS) (#.SQL_ERROR (error 'sql-database-error :error-id result :message (format nil "DB2 error" result))) (t (error 'sql-database-error :message (format nil "DB2 unknown error, code=~A" result))))))))) (defmacro def-raw-cli-routine ((c-cli-symbol lisp-cli-fn) c-return &rest c-parms) (let ((ll (mapcar (lambda (x) (declare (ignore x)) (gensym)) c-parms))) `(let ((%lisp-cli-fn (uffi:def-function (,c-cli-symbol ,(intern (concatenate 'string "%" (symbol-name lisp-cli-fn)))) ,c-parms :returning ,c-return))) (defun ,lisp-cli-fn (,@ll &key database nulls-ok) (funcall %lisp-cli-fn ,@ll))))) (def-cli-routine ("SQLAllocHandle" sql-alloc-handle) :int (fHandleType cli-smallint) (hInput cli-handle) (phOuput (* cli-handle))) (def-cli-routine ("SQLConnect" sql-connect) :int (hDb cli-handle) (server :cstring) (server-len cli-smallint) (user :cstring) (user-len cli-smallint) (password :cstring) (passwd-len cli-smallint)) ;;; CLI Functions needed ;;; SQLBindParameter ;;; SQLExecDirect ;;; SQLNumResultCols ;;; SQLDescribeCol ;;; SQLColAttribute ;;; SQLRowCount ;;; SQLBindCol ;;; SQLFetch ;;; SQLGetData ;;; SQLEndTran ;;; SQLFreeHandle ;;; SQLDisconnect ;;; SQLSetConnectAttr cl-sql-6.7.2/db-db2/db2-objects.lisp0000644000175000017500000000106511335067642015765 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db2-objects.lisp ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-db2) cl-sql-6.7.2/db-db2/db2-constants.lisp0000644000175000017500000000155611335067642016355 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db2-constants.lisp ;;;; Purpose: Constants for CLSQL Db2 interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-db2) (defconstant SQL_NULL_HANDLE nil) (defconstant SQL_HANDLE_ENV 1) (defconstant SQL_HANDLE_DBC 2) (defconstant SQL_HANDLE_STMT 3) (defconstant SQL_NTS -3) (defconstant SQL_ERROR -1) (defconstant SQL_SUCCESS 0) (defconstant SQL_SUCCESS_WITH_INFO 1) cl-sql-6.7.2/db-db2/db2-sql.lisp0000644000175000017500000000524711335067642015141 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db2-sql.lisp ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-db2) (defmethod database-initialize-database-type ((database-type (eql :db2))) t) (defclass db2-database (database) ((henv :initform nil :allocation :class :initarg :henv :accessor henv) (hdbc :initform nil :initarg :hdbc :accessor hdbc))) (defmethod database-name-from-spec (connection-spec (database-type (eql :db2))) (check-connection-spec connection-spec database-type (dsn user password)) (destructuring-bind (dsn user password) connection-spec (declare (ignore password)) (concatenate 'string dsn "/" user))) (defmethod database-connect (connection-spec (database-type (eql :db2))) (check-connection-spec connection-spec database-type (dsn user password)) (destructuring-bind (server user password) connection-spec (handler-case (let ((db (make-instance 'db2-database :name (database-name-from-spec connection-spec :db2) :database-type :db2))) (db2-connect db server user password) db) (error () ;; Init or Connect failed (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :message "Connection failed"))))) ;; API Functions (uffi:def-type handle-type cli-handle) (uffi:def-type handle-ptr-type (* cli-handle)) (defmacro deref-vp (foreign-object) `(the handle-type (uffi:deref-pointer (the handle-ptr-type ,foreign-object) cli-handle))) (defun db2-connect (db server user password) (let ((henv (uffi:allocate-foreign-object 'cli-handle)) (hdbc (uffi:allocate-foreign-object 'cli-handle))) (sql-alloc-handle SQL_HANDLE_ENV SQL_NULL_HANDLE henv) (setf (slot-value db 'henv) henv) (setf (slot-value db 'hdbc) hdbc) (sql-alloc-handle SQL_HANDLE_DBC (deref-vp henv) hdbc) (uffi:with-cstrings ((native-server server) (native-user user) (native-password password)) (sql-connect (deref-vp hdbc) native-server SQL_NTS native-user SQL_NTS native-password SQL_NTS))) db) cl-sql-6.7.2/db-db2/Makefile0000644000175000017500000000123511335067642014435 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL Db2 interface # Author: Kevin M. Rosenberg # Created: May 2004 # # This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/db-mysql/0000755000175000017500000000000014327126007013465 5ustar kevinkevincl-sql-6.7.2/db-mysql/Makefile.msvc0000744000175000017500000000222111335067642016077 0ustar kevinkevin# -*- Mode: Makefile -*- ########################################################################### # FILE IDENTIFICATION # # Name: Makefile.msvc # Purpose: Makefile for the CLSQL UFFI helper package (MSVC) # Author: Kevin M. Rosenberg # Created: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################### BASE=clsql_mysql # Set to the directory where you have installed mysql's library MYSQL_DIR=c:/Program Files/MySQL/MySQL Server 5.1/ MYSQL_LIB_FILE=$(MYSQL_DIR)lib\opt\mysqlclient.lib MYSQL_INCLUDE=$(MYSQL_DIR)include # Nothing to configure beyond here SRC=$(BASE).c OBJ=$(BASE).obj DLL=$(BASE).dll LIB=$(BASE).lib $(DLL): $(SRC) $(MYSQL_LIB_FILE) echo "LD" echo $(MYSQL_LIB_FILE) cl /MD /LD -D_MT /DWIN32=1 /D__LCC__=1 /I"$(MYSQL_INCLUDE)" $(SRC) $(MYSQL_LIB_FILE) del $(OBJ) $(BASE).exp clean: del /q $(DLL) cl-sql-6.7.2/db-mysql/mysql-package.lisp0000644000175000017500000001014212473715066017123 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: mysql-package.cl ;;;; Purpose: Package definition for low-level MySQL interface ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:mysql (:use #:common-lisp #:clsql-uffi) (:export #:database-library-loaded #:mysql-socket #:mysql-book #:mysql-byte #:mysql-net-type #:mysql-net-type#tcp-ip #:mysql-net-type#socket #:mysql-net-type#named-pipe #:mysql-net #:mysql-used-mem #:mysql-mem-root #:mysql-field-types #:mysql-field-types#decimal #:mysql-field-types#tiny #:mysql-field-types#short #:mysql-field-types#long #:mysql-field-types#float #:mysql-field-types#double #:mysql-field-types#null #:mysql-field-types#timestamp #:mysql-field-types#longlong #:mysql-field-types#int24 #:mysql-field-types#date #:mysql-field-types#time #:mysql-field-types#datetime #:mysql-field-types#year #:mysql-field-types#newdate #:mysql-field-types#enum #:mysql-field-types#tiny-blob #:mysql-field-types#medium-blob #:mysql-field-types#long-blob #:mysql-field-types#blob #:mysql-field-types#var-string #:mysql-field-types#string #:mysql-field #:mysql-row #:mysql-field-offset #:mysql-row-offset #:mysql-field-vector #:mysql-data #:mysql-options #:mysql-mysql-option #:mysql-mysql-option#connect-timeout #:mysql-mysql-option#compress #:mysql-mysql-option#named-pipe #:mysql-mysql-option#init-command #:mysql-mysql-option#read-default-file #:mysql-mysql-option#read-default-group #:mysql-status #:mysql-status#ready #:mysql-status#get-ready #:mysql-status#use-result #:mysql-mysql #:mysql-mysql-res ;; functions #:mysql-init #:mysql-connect #:mysql-real-connect #:mysql-close #:mysql-select-db #:mysql-query #:mysql-real-query #:mysql-create-db #:mysql-drop-db #:mysql-shutdown #:mysql-dump-debug-info #:mysql-refresh #:mysql-kill #:mysql-ping #:mysql-stat #:mysql-get-server-info #:mysql-get-client-info #:mysql-get-host-info #:mysql-get-proto-info #:mysql-list-dbs #:mysql-list-tables #:mysql-list-fields #:mysql-list-processes #:mysql-store-result #:mysql-use-result #:mysql-options #:mysql-free-result #:mysql-next-result #:mysql-row-seek #:mysql-field-seek #:mysql-fetch-row #:mysql-fetch-lengths #:mysql-fetch-field #:mysql-fetch-fields #:mysql-fetch-field-direct #:mysql-escape-string #:mysql-debug #:mysql-num-rows #:mysql-num-fields #:mysql-affected-rows #:mysql-insert-id #:mysql-eof #:mysql-error #:mysql-error-string #:mysql-errno #:mysql-info #:mysql-info-string #:mysql-data-seek #:mysql-time #:mysql-bind #:mysql-stmt-param-count #:mysql-stmt-prepare #:mysql-stmt-execute #:mysql-stmt-store-result #:mysql-stmt-init #:mysql-stmt-close-result #:mysql-stmt-free-result #:mysql-stmt #:mysql-stmt-result-metadata #:mysql-stmt-fetch #:mysql-stmt-bind-param #:mysql-stmt-bind-result #:mysql-stmt-close #:mysql-stmt-errno #:mysql-stmt-error #:make-64-bit-integer #:clsql-mysql-field-name #:clsql-mysql-field-type #:clsql-mysql-field-flags #:+mysql-option-parameter-map+ ) (:documentation "This is the low-level interface MySQL.")) cl-sql-6.7.2/db-mysql/mysql-sql.lisp0000644000175000017500000011101612473715066016331 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: mysql-sql.lisp ;;;; Purpose: High-level MySQL interface using UFFI ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-mysql (:use #:common-lisp #:clsql-sys #:mysql #:clsql-uffi) (:export #:mysql-database) (:import-from :clsql-sys :escaped :unescaped :combine-database-identifiers :escaped-database-identifier :unescaped-database-identifier :database-identifier :%sequence-name-to-table :%table-name-to-sequence-name) (:documentation "This is the CLSQL interface to MySQL.")) (in-package #:clsql-mysql) ;;; Field conversion functions (defun result-field-names (res-ptr) (let ((names '())) (mysql-field-seek res-ptr 0) (loop (let ((field (mysql-fetch-field res-ptr))) (when (uffi:null-pointer-p field) (return)) (push (uffi:convert-from-cstring (clsql-mysql-field-name field)) names))) (nreverse names))) (defun make-type-list-for-auto (res-ptr) (let ((new-types '())) (mysql-field-seek res-ptr 0) (loop (let ((field (mysql-fetch-field res-ptr))) (when (uffi:null-pointer-p field) (return)) (let* ((flags (clsql-mysql-field-flags field)) (unsigned (plusp (logand flags 32))) (type (clsql-mysql-field-type field))) (push (case type ((#.mysql-field-types#tiny #.mysql-field-types#short #.mysql-field-types#int24) (if unsigned :uint32 :int32)) (#.mysql-field-types#long (if unsigned :uint :int)) (#.mysql-field-types#longlong (if unsigned :uint64 :int64)) ((#.mysql-field-types#double #.mysql-field-types#float #.mysql-field-types#decimal) :double) (otherwise t)) new-types)))) (nreverse new-types))) (defun canonicalize-types (types res-ptr) (when types (let ((auto-list (make-type-list-for-auto res-ptr))) (cond ((listp types) (canonicalize-type-list types auto-list)) ((eq types :auto) auto-list) (t nil))))) (defmethod database-initialize-database-type ((database-type (eql :mysql))) t) ;;(uffi:def-type mysql-mysql-ptr-def (* mysql-mysql)) ;;(uffi:def-type mysql-mysql-res-ptr-def (* mysql-mysql-res)) (uffi:def-type mysql-mysql-ptr-def mysql-mysql) (uffi:def-type mysql-mysql-res-ptr-def mysql-mysql-res) (uffi:def-type mysql-row-def mysql-row) (defclass mysql-database (database) ((mysql-ptr :accessor database-mysql-ptr :initarg :mysql-ptr :type mysql-mysql-ptr-def) (server-info :accessor database-server-info :initarg :server-info :type string))) (defmethod database-type ((database mysql-database)) :mysql) (defmethod database-name-from-spec (connection-spec (database-type (eql :mysql))) (check-connection-spec connection-spec database-type (host db user password &optional port options)) (destructuring-bind (host db user password &optional port options) connection-spec (declare (ignore password options)) (concatenate 'string (etypecase host (null "localhost") (pathname (namestring host)) (string host)) (if port (concatenate 'string ":" (etypecase port (integer (write-to-string port)) (string port))) "") "/" db "/" user))) (defun lookup-option-code (option) (if (assoc option +mysql-option-parameter-map+) (symbol-value (intern (concatenate 'string (symbol-name-default-case "mysql-option#") (symbol-name option)) (symbol-name '#:mysql))) (progn (warn "Unknown mysql option name ~A - ignoring.~%" option) nil))) (defun set-mysql-options (mysql-ptr options) (flet ((lookup-option-type (option) (cdr (assoc option +mysql-option-parameter-map+)))) (dolist (option options) (if (atom option) (let ((option-code (lookup-option-code option))) (when option-code (mysql-options mysql-ptr option-code uffi:+null-cstring-pointer+))) (destructuring-bind (name . value) option (let ((option-code (lookup-option-code name))) (when option-code (case (lookup-option-type name) (:none (mysql-options mysql-ptr option-code uffi:+null-cstring-pointer+)) (:char-ptr (if (stringp value) (uffi:with-foreign-string (fs value) (mysql-options mysql-ptr option-code fs)) (warn "Expecting string argument for mysql option ~A, got ~A ~ - ignoring.~%" name value))) (:uint-ptr (if (integerp value) (uffi:with-foreign-object (fo :unsigned-int) (setf (uffi:deref-pointer fo :unsigned-int) value) (mysql-options mysql-ptr option-code fo)) (warn "Expecting integer argument for mysql option ~A, got ~A ~ - ignoring.~%" name value))) (:boolean-ptr (uffi:with-foreign-object (fo :byte) (setf (uffi:deref-pointer fo :byte) (case value ((nil 0) 0) (t 1))) (mysql-options mysql-ptr option-code fo))))))))))) (defmethod database-connect (connection-spec (database-type (eql :mysql))) (check-connection-spec connection-spec database-type (host db user password &optional port options)) (destructuring-bind (host db user password &optional port options) connection-spec (let ((mysql-ptr (mysql-init (uffi:make-null-pointer 'mysql-mysql))) (socket nil)) (if (uffi:null-pointer-p mysql-ptr) (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr)) (uffi:with-cstrings ((host-native host) (user-native user) (password-native password) (db-native db) (socket-native socket)) (when options (set-mysql-options mysql-ptr options)) (let ((error-occurred nil)) (unwind-protect (if (uffi:null-pointer-p (mysql-real-connect mysql-ptr host-native user-native password-native db-native (etypecase port (null 0) (integer port) (string (parse-integer port))) socket-native 0)) (progn (setq error-occurred t) (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr))) (let* ((db (make-instance 'mysql-database :name (database-name-from-spec connection-spec database-type) :database-type :mysql :connection-spec connection-spec :server-info (uffi:convert-from-cstring (mysql:mysql-get-server-info mysql-ptr)) :mysql-ptr mysql-ptr)) (cmd "SET SESSION sql_mode='ANSI'")) (uffi:with-cstring (cmd-cs cmd) (if (zerop (mysql-real-query mysql-ptr cmd-cs (uffi:foreign-encoded-octet-count cmd :encoding (encoding db)))) db (progn (warn "Error setting ANSI mode for MySQL.") db))))) (when error-occurred (mysql-close mysql-ptr))))))))) (defmethod database-disconnect ((database mysql-database)) (mysql-close (database-mysql-ptr database)) (setf (database-mysql-ptr database) nil) t) (defmethod database-execute-command (sql-expression (database mysql-database)) (uffi:with-cstring (sql-native sql-expression) (let ((mysql-ptr (database-mysql-ptr database))) (declare (type mysql-mysql-ptr-def mysql-ptr)) (if (zerop (mysql-real-query mysql-ptr sql-native (uffi:foreign-encoded-octet-count sql-expression :encoding (encoding database)))) t (error 'sql-database-data-error :database database :expression sql-expression :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr)))))) (defmethod database-query (query-expression (database mysql-database) result-types field-names) (declare (optimize (speed 3))) (let ((mysql-ptr (database-mysql-ptr database)) (results nil) ;; all the results and column-names in reverse-order (res-ptr nil) (num-fields 0)) (declare (type mysql-mysql-ptr-def mysql-ptr) (type (or null mysql-mysql-res-ptr-def) res-ptr) (fixnum num-fields)) (when (database-execute-command query-expression database) (labels ((get-row (row lengths) "Pull a single row value from the results" (loop for i from 0 below num-fields collect (convert-raw-field (uffi:deref-array row '(:array (* :unsigned-char)) (the fixnum i)) (nth i result-types) :length (uffi:deref-array lengths '(:array :unsigned-long) (the fixnum i)) :encoding (encoding database)))) (get-result-rows () "get all the rows out of the now valid results set" (loop for row = (mysql-fetch-row res-ptr) for lengths = (mysql-fetch-lengths res-ptr) until (uffi:null-pointer-p row) collect (get-row row lengths))) (do-result-set () "for a mysql-ptr, grab and return a results set" (setf res-ptr (mysql-use-result mysql-ptr)) (cond ((or (null res-ptr) (uffi:null-pointer-p res-ptr)) (unless (zerop (mysql-errno mysql-ptr)) ;;from http://dev.mysql.com/doc/refman/5.0/en/mysql-field-count.html ;; if mysql_use_result or mysql_store_result return a null ptr, ;; we use a mysql_errno check to see if it had a problem or just ;; was a query without a result. If no error, just return nil. (error 'sql-database-data-error :database database :expression query-expression :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr)))) (t (unwind-protect (progn (setf num-fields (mysql-num-fields res-ptr) result-types (canonicalize-types result-types res-ptr)) (push (get-result-rows) results) (push (when field-names (result-field-names res-ptr)) results)) (mysql-free-result res-ptr)))))) (loop do (do-result-set) while (let ((next (mysql-next-result mysql-ptr))) (case next (0 t) ;Successful and there are more results (-1 nil) ;Successful and there are no more results (t nil) ;errors ))) (values-list (nreverse results)))))) (defstruct mysql-result-set (res-ptr (uffi:make-null-pointer 'mysql-mysql-res) :type mysql-mysql-res-ptr-def) (types nil :type list) (num-fields 0 :type fixnum) (full-set nil :type boolean)) (defmethod database-query-result-set ((query-expression string) (database mysql-database) &key full-set result-types) ;; TODO: REFACTOR THIS IN TERMS OF database-query or vice-versa ;; This doesnt seem to free database results reliably, dont think ;; that we should allow that particularly, OTOH, dont know how ;; we support cursoring without it (let ((mysql-ptr (database-mysql-ptr database))) (declare (type mysql-mysql-ptr-def mysql-ptr)) (when (database-execute-command query-expression database) (let ((res-ptr (if full-set (mysql-store-result mysql-ptr) (mysql-use-result mysql-ptr)))) (declare (type mysql-mysql-res-ptr-def res-ptr)) (if (not (uffi:null-pointer-p res-ptr)) (let* ((num-fields (mysql-num-fields res-ptr)) (result-set (make-mysql-result-set :res-ptr res-ptr :num-fields num-fields :full-set full-set :types (canonicalize-types result-types res-ptr)))) (if full-set (values result-set num-fields (mysql-num-rows res-ptr)) (values result-set num-fields))) (error 'sql-database-data-error :database database :expression query-expression :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr)))) ))) (defmethod database-dump-result-set (result-set (database mysql-database)) (mysql-free-result (mysql-result-set-res-ptr result-set)) t) (defmethod database-store-next-row (result-set (database mysql-database) list) (let* ((res-ptr (mysql-result-set-res-ptr result-set)) (row (mysql-fetch-row res-ptr)) (lengths (mysql-fetch-lengths res-ptr)) (types (mysql-result-set-types result-set))) (declare (type mysql-mysql-res-ptr-def res-ptr) (type mysql-row-def row)) (unless (uffi:null-pointer-p row) (loop for i from 0 below (mysql-result-set-num-fields result-set) for rest on list do (setf (car rest) (convert-raw-field (uffi:deref-array row '(:array (* :unsigned-char)) i) (nth i types) :length (uffi:deref-array lengths '(:array :unsigned-long) i) :encoding (encoding database)))) list))) ;; Table and attribute introspection (defmethod database-list-tables ((database mysql-database) &key (owner nil)) (declare (ignore owner)) (cond ((eql #\5 (char (database-server-info database) 0)) (loop for (name type) in (database-query "SHOW FULL TABLES" database nil nil) when (and (string-equal type "base table") (not (and (>= (length name) 11) (string-equal (subseq name 0 11) "_CLSQL_SEQ_")))) collect name)) (t (remove-if #'(lambda (s) (and (>= (length s) 11) (string-equal (subseq s 0 11) "_CLSQL_SEQ_"))) (mapcar #'car (database-query "SHOW TABLES" database nil nil)))))) (defmethod database-list-views ((database mysql-database) &key (owner nil)) (declare (ignore owner)) (cond ((eql #\5 (char (database-server-info database) 0)) (loop for (name type) in (database-query "SHOW FULL TABLES" database nil nil) when (string-equal type "view") collect name)) (t nil))) (defmethod database-list-indexes ((database mysql-database) &key (owner nil)) (let ((result '())) (dolist (table (database-list-tables database :owner owner) result) (setq result (append (database-list-table-indexes table database :owner owner) result))))) (defmethod database-list-table-indexes (table (database mysql-database) &key (owner nil)) (declare (ignore owner)) (do ((results nil) (rows (database-query (format nil "SHOW INDEX FROM ~A" (escaped-database-identifier table database)) database nil nil) (cdr rows))) ((null rows) (nreverse results)) (let ((col (nth 2 (car rows)))) (unless (find col results :test #'string-equal) (push col results))))) (defmethod database-list-attributes ((table clsql-sys::%database-identifier) (database mysql-database) &key (owner nil) &aux (table (unescaped-database-identifier table))) (declare (ignore owner)) (mapcar #'car (database-query (format nil "SHOW COLUMNS FROM ~A" (escaped-database-identifier table database)) database nil nil))) (defmethod database-attribute-type ((attribute clsql-sys::%database-identifier) (table clsql-sys::%database-identifier) (database mysql-database) &key (owner nil) &aux (table (unescaped-database-identifier table)) (attribute (unescaped-database-identifier attribute))) (declare (ignore owner)) (let ((row (car (database-query (format nil "SHOW COLUMNS FROM ~A LIKE '~A'" (escaped-database-identifier table database) (unescaped-database-identifier attribute database)) database nil nil)))) (let* ((raw-type (second row)) (null (third row)) (start-length (position #\( raw-type)) (type (if start-length (subseq raw-type 0 start-length) raw-type)) (length (when start-length (parse-integer (subseq raw-type (1+ start-length)) :junk-allowed t)))) (when type (values (ensure-keyword type) length nil (if (string-equal null "YES") 1 0)))))) ;;; Sequence functions (defmethod database-create-sequence (sequence-name (database mysql-database)) (let ((table-name (%sequence-name-to-table sequence-name database))) (database-execute-command (concatenate 'string "CREATE TABLE " table-name " (id int NOT NULL PRIMARY KEY AUTO_INCREMENT)") database) (database-execute-command (concatenate 'string "INSERT INTO " table-name " VALUES (-1)") database))) (defmethod database-drop-sequence (sequence-name (database mysql-database)) (database-execute-command (concatenate 'string "DROP TABLE " (%sequence-name-to-table sequence-name database)) database)) (defmethod database-list-sequences ((database mysql-database) &key (owner nil)) (declare (ignore owner)) (mapcan #'(lambda (s) (let ((sn (%table-name-to-sequence-name (car s)))) (and sn (list (car s) sn)))) (database-query "SHOW TABLES" database nil nil))) (defmethod database-set-sequence-position (sequence-name (position integer) (database mysql-database)) (database-execute-command (format nil "UPDATE ~A SET id=~A" (%sequence-name-to-table sequence-name database) position) database) (mysql:mysql-insert-id (clsql-mysql::database-mysql-ptr database))) (defmethod database-sequence-next (sequence-name (database mysql-database)) (without-interrupts (database-execute-command (concatenate 'string "UPDATE " (%sequence-name-to-table sequence-name database) " SET id=LAST_INSERT_ID(id+1)") database) (mysql:mysql-insert-id (clsql-mysql::database-mysql-ptr database)))) (defmethod database-sequence-last (sequence-name (database mysql-database)) (without-interrupts (caar (database-query (concatenate 'string "SELECT id from " (%sequence-name-to-table sequence-name database)) database :auto nil)))) (defmethod database-last-auto-increment-id ((database mysql-database) table column) (declare (ignore table column)) (car (query "SELECT LAST_INSERT_ID();" :flatp t :field-names nil :database database))) (defmethod database-create (connection-spec (type (eql :mysql))) (destructuring-bind (host name user password) connection-spec (let ((database (database-connect (list host "" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "create database ~A" name) database) (database-disconnect database))))) (defmethod database-destroy (connection-spec (type (eql :mysql))) (destructuring-bind (host name user password) connection-spec (let ((database (database-connect (list host "" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "drop database ~A" name) database) (database-disconnect database))))) (defmethod database-probe (connection-spec (type (eql :mysql))) (when (find (second connection-spec) (database-list connection-spec type) :test #'string-equal) t)) (defmethod database-list (connection-spec (type (eql :mysql))) (destructuring-bind (host name user password &optional port options) connection-spec (declare (ignore options)) (let ((database (database-connect (list host (or name "mysql") user password port) type))) (unwind-protect (progn (setf (slot-value database 'clsql-sys::state) :open) (mapcar #'car (database-query "show databases" database :auto nil))) (progn (database-disconnect database) (setf (slot-value database 'clsql-sys::state) :closed)))))) ;;; Prepared statements (defclass mysql-stmt () ((database :initarg :database :reader database) (stmt :initarg :stmt :accessor stmt) (input-bind :initarg :input-bind :reader input-bind) (output-bind :initarg :output-bind :reader output-bind) (types :initarg :types :reader types) (result-set :initarg :result-set :reader result-set) (num-fields :initarg :num-fields :reader num-fields) (field-names :initarg :field-names :accessor stmt-field-names) (length-ptr :initarg :length-ptr :reader length-ptr) (is-null-ptr :initarg :is-null-ptr :reader is-null-ptr) (result-types :initarg :result-types :reader result-types))) (defun clsql-type->mysql-type (type) (cond ((in type :null) mysql-field-types#null) ((in type :int :integer) mysql-field-types#long) ((in type :short) mysql-field-types#short) ((in type :bigint) mysql-field-types#longlong) ((in type :float :double :number) mysql-field-types#double) ((and (consp type) (in (car type) :char :string :varchar)) mysql-field-types#var-string) ((or (eq type :blob) (and (consp type) (in (car type) :blob))) mysql-field-types#var-string) (t (error 'sql-user-error :message (format nil "Unknown clsql type ~A." type))))) #+mysql-client-v4.1 (defmethod database-prepare (sql-stmt types (database mysql-database) result-types field-names) (let* ((mysql-ptr (database-mysql-ptr database)) (stmt (mysql-stmt-init mysql-ptr))) (when (uffi:null-pointer-p stmt) (error 'sql-database-error :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr))) (uffi:with-cstring (native-query sql-stmt) (unless (zerop (mysql-stmt-prepare stmt native-query (uffi:foreign-encoded-octet-count sql-stmt :encoding (encoding database)))) (mysql-stmt-close stmt) (error 'sql-database-error :error-id (mysql-errno mysql-ptr) :message (mysql-error-string mysql-ptr)))) (unless (= (mysql-stmt-param-count stmt) (length types)) (mysql-stmt-close stmt) (error 'sql-database-error :message (format nil "Mysql param count (~D) does not match number of types (~D)" (mysql-stmt-param-count stmt) (length types)))) (let ((rs (mysql-stmt-result-metadata stmt))) (when (uffi:null-pointer-p rs) (warn "mysql_stmt_result_metadata returned NULL") #+nil (mysql-stmt-close stmt) #+nil (error 'sql-database-error :message "mysql_stmt_result_metadata returned NULL")) (let ((input-bind (uffi:allocate-foreign-object 'mysql-bind (length types))) (mysql-types (mapcar 'clsql-type->mysql-type types)) field-vec num-fields is-null-ptr output-bind length-ptr) (print 'a) (dotimes (i (length types)) (let* ((binding (uffi:deref-array input-bind '(:array mysql-bind) i))) (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer-type) (nth i mysql-types)) (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer-length) 0))) (print 'b) (unless (uffi:null-pointer-p rs) (setq field-vec (mysql-fetch-fields rs) num-fields (mysql-num-fields rs) is-null-ptr (uffi:allocate-foreign-object :byte num-fields) output-bind (uffi:allocate-foreign-object 'mysql-bind num-fields) length-ptr (uffi:allocate-foreign-object :unsigned-long num-fields)) (dotimes (i num-fields) (declare (fixnum i)) (let* ((field (uffi:deref-array field-vec '(:array mysql-field) i)) (type (uffi:get-slot-value field 'mysql-field 'type)) (binding (uffi:deref-array output-bind '(:array mysql-bind) i))) (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer-type) type) (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer-length) 0) #+need-to-allocate-foreign-object-for-this (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::is-null) (+ i (uffi:pointer-address is-null-ptr))) #+need-to-allocate-foreign-object-for-this (setf (uffi:get-slot-value binding 'mysql-bind 'length) (+ (* i 8) (uffi:pointer-address length-ptr))) (case type ((#.mysql-field-types#var-string #.mysql-field-types#string #.mysql-field-types#tiny-blob #.mysql-field-types#blob #.mysql-field-types#medium-blob #.mysql-field-types#long-blob) (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer-length) 1024) (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) (uffi:allocate-foreign-object :unsigned-char 1024))) (#.mysql-field-types#tiny (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) (uffi:allocate-foreign-object :byte))) (#.mysql-field-types#short (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) (uffi:allocate-foreign-object :short))) (#.mysql-field-types#long (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) ;; segfaults if supply :int on amd64 (uffi:allocate-foreign-object :long))) #+64bit (#.mysql-field-types#longlong (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) (uffi:allocate-foreign-object :long))) (#.mysql-field-types#float (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) (uffi:allocate-foreign-object :float))) (#.mysql-field-types#double (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) (uffi:allocate-foreign-object :double))) ((#.mysql-field-types#time #.mysql-field-types#date #.mysql-field-types#datetime #.mysql-field-types#timestamp) (uffi:allocate-foreign-object 'mysql-time)) (t (error "mysql type ~D not supported." type))))) (unless (zerop (mysql-stmt-bind-result stmt output-bind)) (mysql-stmt-close stmt) (error 'sql-database-error :error-id (mysql-stmt-errno stmt) :message (uffi:convert-from-cstring (mysql-stmt-error stmt))))) (make-instance 'mysql-stmt :database database :stmt stmt :num-fields num-fields :input-bind input-bind :output-bind output-bind :result-set rs :result-types result-types :length-ptr length-ptr :is-null-ptr is-null-ptr :types mysql-types :field-names field-names))))) #+mysql-client-v4.1 (defmethod database-bind-parameter ((stmt mysql-stmt) position value) ;; FIXME: will need to allocate bind structure. This should probably be ;; done in C since the API is not mature and may change (let ((binding (uffi:deref-array (input-bind stmt) '(:array mysql-bind) (1- position))) (type (nth (1- position) (types stmt)))) (setf (uffi:get-slot-value binding 'mysql-bind 'length) 0) (cond ((null value) (when (is-null-ptr stmt) (setf (uffi:deref-array (is-null-ptr stmt) '(:array :byte) (1- position)) 1))) (t (when (is-null-ptr stmt) (setf (uffi:deref-array (is-null-ptr stmt) '(:array :byte) (1- position)) 0)) (case type (#.mysql-field-types#long (setf (uffi:get-slot-value binding 'mysql-bind 'mysql::buffer) value)) (t (warn "Unknown input bind type ~D." type)) ))))) #+mysql-client-v4.1 (defmethod database-run-prepared ((stmt mysql-stmt)) (print 'a1) (when (input-bind stmt) (unless (zerop (mysql-stmt-bind-param (stmt stmt) (input-bind stmt))) (error 'sql-database-error :error-id (mysql-stmt-errno (stmt stmt)) :message (uffi:convert-from-cstring (mysql-stmt-error (stmt stmt)))))) (print 'a2) (unless (zerop (mysql-stmt-execute (stmt stmt))) (error 'sql-database-error :error-id (mysql-stmt-errno (stmt stmt)) :message (uffi:convert-from-cstring (mysql-stmt-error (stmt stmt))))) (print 'a3) (unless (zerop (mysql-stmt-store-result (stmt stmt))) (error 'sql-database-error :error-id (mysql-stmt-errno (stmt stmt)) :message (uffi:convert-from-cstring (mysql-stmt-error (stmt stmt))))) (database-fetch-prepared-rows stmt)) #+mysql-client-v4.1 (defun database-fetch-prepared-rows (stmt) (do ((rc (mysql-stmt-fetch (stmt stmt)) (mysql-stmt-fetch (stmt stmt))) (num-fields (num-fields stmt)) (rows '())) ((not (zerop rc)) (nreverse rows)) (push (loop for i from 0 below num-fields collect (let ((is-null (not (zerop (uffi:ensure-char-integer (uffi:deref-array (is-null-ptr stmt) '(:array :byte) i)))))) (unless is-null (let* ((bind (uffi:deref-array (output-bind stmt) '(:array mysql-bind) i)) (type (uffi:get-slot-value bind 'mysql-bind 'mysql::buffer-type)) (buffer (uffi:get-slot-value bind 'mysql-bind 'mysql::buffer))) (case type ((#.mysql-field-types#var-string #.mysql-field-types#string #.mysql-field-types#tiny-blob #.mysql-field-types#blob #.mysql-field-types#medium-blob #.mysql-field-types#long-blob) (uffi:convert-from-foreign-string buffer :encoding (encoding (database stmt)))) (#.mysql-field-types#tiny (uffi:ensure-char-integer (uffi:deref-pointer buffer :byte))) (#.mysql-field-types#short (uffi:deref-pointer buffer :short)) (#.mysql-field-types#long (uffi:deref-pointer buffer :int)) #+64bit (#.mysql-field-types#longlong (uffi:deref-pointer buffer :long)) (#.mysql-field-types#float (uffi:deref-pointer buffer :float)) (#.mysql-field-types#double (uffi:deref-pointer buffer :double)) ((#.mysql-field-types#time #.mysql-field-types#date #.mysql-field-types#datetime #.mysql-field-types#timestamp) (let ((year (uffi:get-slot-value buffer 'mysql-time 'mysql::year)) (month (uffi:get-slot-value buffer 'mysql-time 'mysql::month)) (day (uffi:get-slot-value buffer 'mysql-time 'mysql::day)) (hour (uffi:get-slot-value buffer 'mysql-time 'mysql::hour)) (minute (uffi:get-slot-value buffer 'mysql-time 'mysql::minute)) (second (uffi:get-slot-value buffer 'mysql-time 'mysql::second))) (db-timestring (make-time :year year :month month :day day :hour hour :minute minute :second second)))) (t (list type))))))) rows))) #+mysql-client-v4.1 (defmethod database-free-prepared ((stmt mysql-stmt)) (with-slots (stmt) stmt (mysql-stmt-close stmt)) ) ;;; Database capabilities (defmethod db-type-use-column-on-drop-index? ((db-type (eql :mysql))) t) (defmethod db-type-has-views? ((db-type (eql :mysql))) #+mysql-client-v5 t #-mysql-client-v5 nil) (defmethod db-type-has-subqueries? ((db-type (eql :mysql))) #+(or mysql-client-v4.1 mysql-client-v5) t #-(or mysql-client-v4.1 mysql-client-v5) nil) (defmethod db-type-has-boolean-where? ((db-type (eql :mysql))) #+(or mysql-client-v4.1 mysql-client-v5) t #-(or mysql-client-v4.1 mysql-client-v5) nil) (defmethod db-type-has-union? ((db-type (eql :mysql))) (not (eql (schar mysql::*mysql-client-info* 0) #\3))) (defmethod db-type-transaction-capable? ((db-type (eql :mysql)) database) (let ((tuple (car (database-query "SHOW VARIABLES LIKE 'HAVE_INNODB'" database :auto nil)))) (and tuple (string-equal "YES" (second tuple))))) (defmethod db-type-has-prepared-stmt? ((db-type (eql :mysql))) #+(or mysql-client-v4.1 mysql-client-v5) t #-(or mysql-client-v4.1 mysql-client-v5) nil) (defmethod db-type-has-auto-increment? ((db-type (eql :mysql))) t) (when (clsql-sys:database-type-library-loaded :mysql) (clsql-sys:initialize-database-type :database-type :mysql)) cl-sql-6.7.2/db-mysql/clsql_mysql.c0000644000175000017500000000676511335067642016217 0ustar kevinkevin/**************************************************************************** * FILE IDENTIFICATION * * Name: clsql-mysql.c * Purpose: Helper functions for mysql.cl to handle 64-bit parts of API * Programmer: Kevin M. Rosenberg * Date Started: Mar 2002 * * This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg * * CLSQL users are granted the rights to distribute and use this software * as governed by the terms of the Lisp Lesser GNU Public License * (http://opensource.franz.com/preamble.html), also known as the LLGPL. ***************************************************************************/ #if defined(WIN32)||defined(WIN64) #include BOOL WINAPI DllEntryPoint(HINSTANCE hinstdll, DWORD fdwReason, LPVOID lpvReserved) { return 1; } #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT #endif #include /* Need to assemble a 64-bit integer to send to MySQL */ DLLEXPORT void clsql_mysql_data_seek (MYSQL_RES* res, unsigned int offset_high32, unsigned int offset_low32) { my_ulonglong offset; offset = offset_high32; offset = offset << 32; offset += offset_low32; mysql_data_seek (res, offset); } /* The following functions are used to return 64-bit integers to Lisp. They return the 32-bit low part and store in upper 32-bits in a located sent via a pointer */ static const unsigned int bitmask_32bits = 0xFFFFFFFF; #define lower_32bits(int64) ((unsigned int) int64 & bitmask_32bits) #define upper_32bits(int64) ((unsigned int) (int64 >> 32)) DLLEXPORT unsigned int clsql_mysql_num_rows (MYSQL_RES* res, unsigned int* pHigh32) { my_ulonglong nRows = mysql_num_rows (res); *pHigh32 = upper_32bits(nRows); return lower_32bits(nRows); } DLLEXPORT unsigned int clsql_mysql_affected_rows (MYSQL* res, unsigned int* pHigh32) { my_ulonglong nAffected = mysql_affected_rows (res); *pHigh32 = upper_32bits(nAffected); return lower_32bits(nAffected); } DLLEXPORT unsigned int clsql_mysql_insert_id (MYSQL* mysql, unsigned int* pHigh32) { my_ulonglong insert_id = mysql_insert_id (mysql); *pHigh32 = upper_32bits(insert_id); return lower_32bits(insert_id); } /* Accessor functions to hide the differences across MySQL versions */ DLLEXPORT unsigned int clsql_mysql_field_flags (MYSQL_FIELD* field) { return field->flags; } DLLEXPORT unsigned int clsql_mysql_field_type (MYSQL_FIELD* field) { return field->type; } DLLEXPORT char* clsql_mysql_field_name (MYSQL_FIELD* field) { return field->name; } DLLEXPORT unsigned long clsql_mysql_field_length (MYSQL_FIELD* field) { return field->length; } DLLEXPORT unsigned long clsql_mysql_field_max_length (MYSQL_FIELD* field) { return field->max_length; } #if MYSQL_VERSION_ID >= 40102 #include DLLEXPORT MYSQL_BIND* allocate_bind (unsigned int n) { return (MYSQL_BIND*) malloc (n * sizeof(MYSQL_BIND)); } DLLEXPORT void bind_param (MYSQL_BIND bind[], unsigned int n, unsigned long length, unsigned short is_null, void* buffer, unsigned short buffer_type, unsigned long buffer_length) { *bind[n].length = length; *bind[n].is_null = is_null; bind[n].buffer = buffer; bind[n].buffer_type = buffer_type; bind[n].buffer_length = buffer_length; } DLLEXPORT unsigned int clsql_mysql_stmt_affected_rows (MYSQL_STMT* stmt, unsigned int* pHigh32) { my_ulonglong nAffected = mysql_stmt_affected_rows (stmt); *pHigh32 = upper_32bits(nAffected); return lower_32bits(nAffected); } #endif cl-sql-6.7.2/db-mysql/mysql-objects.lisp0000644000175000017500000000163612303270414017152 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: mysql-objects.lisp ;;;; Purpose: CLSQL Object layer for MySQL ;;;; Created: May 2004 ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-mysql) (defmethod database-get-type-specifier ((type symbol) args database (db-type (eql :mysql))) (declare (ignore args database db-type)) (case type (wall-time "DATETIME") (tinyint "TINYINT") (smallint "SMALLINT") (mediumint "MEDIUMINT") (t (call-next-method)))) cl-sql-6.7.2/db-mysql/mysql-api.lisp0000644000175000017500000003445312473715066016314 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: mysql-api.lisp ;;;; Purpose: Low-level MySQL interface using UFFI ;;;; Programmers: Kevin M. Rosenberg based on ;;;; Original code by Pierre R. Mai ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2009 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:mysql) ;;;; Modifications from original code ;;;; - Updated C-structures to conform to structures in MySQL 3.23.46 ;;;; - Changed from CMUCL interface to UFFI ;;;; - Added and call a C-helper file to support 64-bit integers ;;;; that are used in a few routines. ;;;; - Removed all references to interiors of C-structions, this will ;;;; increase robustness when MySQL's internal structures change. ;;;; Type definitions ;;; Basic Types (uffi:def-foreign-type mysql-socket :int) (uffi:def-foreign-type mysql-bool :byte) (uffi:def-foreign-type mysql-byte :unsigned-char) (uffi:def-enum mysql-net-type (:tcp-ip :socket :named-pipe)) (uffi:def-array-pointer mysql-row (* :unsigned-char)) ;;; MYSQL-FIELD (uffi:def-enum mysql-field-types (:decimal :tiny :short :long :float :double :null :timestamp :longlong :int24 :date :time :datetime :year :newdate (:enum 247) (:set 248) (:tiny-blob 249) (:medium-blob 250) (:long-blob 251) (:blob 252) (:var-string 253) (:string 254) (:geometry 255))) (uffi:def-enum mysql-option (:connect-timeout :compress :named-pipe :init-command :read-default-file :read-default-group :set-charset-dir :set-charset-name :local-infile :protocol :shared-memory-base-name :read-timeout :write-timeout :use-result :use-remote-connection :use-embedded-connection :guess-connection :set-client-ip :secure-auth :report-data-truncation :reconnect :ssl-verify-server-cert)) (defvar +mysql-option-parameter-map+ '((:connect-timeout . :uint-ptr) (:compress . :none) (:named-pipe . :none) (:init-command . :char-ptr) (:read-default-file . :char-ptr) (:read-default-group . :char-ptr) (:set-charset-dir . :char-ptr) (:set-charset-name . :char-ptr) (:local-infile . :uint-ptr) (:protocol . :uint-ptr) (:shared-memory-base-name . :char-ptr) (:read-timeout . :uint-ptr) (:write-timeout . :uint-ptr) (:use-result . :none) (:use-remote-connection . :none) (:use-embedded-connection . :none) (:guess-connection . :none) (:set-client-ip . :char-ptr) (:secure-auth . :boolean-ptr) (:report-data-truncation . :boolean-ptr) (:reconnect . :boolean-ptr) (:ssl-verify-server-cert . :boolean-ptr))) (uffi:def-enum mysql-status (:ready :get-result :use-result)) ;;; Opaque pointers to mysql C-defined structures (uffi:def-foreign-type mysql-mysql (* :void)) (uffi:def-foreign-type mysql-mysql-res (* :void)) (uffi:def-foreign-type mysql-field (* :void)) (uffi:def-foreign-type mysql-bind (* :void)) ;;;; The Foreign C routines (declaim (inline mysql-init)) (uffi:def-function "mysql_init" ((mysql mysql-mysql)) :module "mysql" :returning mysql-mysql) ;; Need to comment this out for LW 4.2.6 ;; ? bug in LW version #-lispworks (declaim (inline mysql-real-connect)) (uffi:def-function "mysql_real_connect" ((mysql mysql-mysql) (host :cstring) (user :cstring) (passwd :cstring) (db :cstring) (port :unsigned-int) (unix-socket :cstring) (clientflag :unsigned-long)) :module "mysql" :returning mysql-mysql) (declaim (inline mysql-close)) (uffi:def-function "mysql_close" ((sock mysql-mysql)) :module "mysql" :returning :void) (declaim (inline mysql-select-db)) (uffi:def-function "mysql_select_db" ((mysql mysql-mysql) (db :cstring)) :module "mysql" :returning :int) (declaim (inline mysql-query)) (uffi:def-function "mysql_query" ((mysql mysql-mysql) (query :cstring)) :module "mysql" :returning :int) ;;; I doubt that this function is really useful for direct Lisp usage, ;;; but it is here for completeness... (declaim (inline mysql-real-query)) (uffi:def-function "mysql_real_query" ((mysql mysql-mysql) (query :cstring) (length :unsigned-int)) :module "mysql" :returning :int) (declaim (inline mysql-shutdown)) (uffi:def-function "mysql_shutdown" ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-dump-debug-info)) (uffi:def-function "mysql_dump_debug_info" ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-refresh)) (uffi:def-function "mysql_refresh" ((mysql mysql-mysql) (refresh-options :unsigned-int)) :module "mysql" :returning :int) (declaim (inline mysql-kill)) (uffi:def-function "mysql_kill" ((mysql mysql-mysql) (pid :unsigned-long)) :module "mysql" :returning :int) (declaim (inline mysql-ping)) (uffi:def-function "mysql_ping" ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-stat)) (uffi:def-function "mysql_stat" ((mysql mysql-mysql)) :module "mysql" :returning :cstring) (declaim (inline mysql-get-server-info)) (uffi:def-function "mysql_get_server_info" ((mysql mysql-mysql)) :module "mysql" :returning :cstring) (declaim (inline mysql-get-host-info)) (uffi:def-function "mysql_get_host_info" ((mysql mysql-mysql)) :module "mysql" :returning :cstring) (declaim (inline mysql-get-proto-info)) (uffi:def-function "mysql_get_proto_info" ((mysql mysql-mysql)) :module "mysql" :returning :unsigned-int) (declaim (inline mysql-list-dbs)) (uffi:def-function "mysql_list_dbs" ((mysql mysql-mysql) (wild :cstring)) :module "mysql" :returning mysql-mysql-res) (declaim (inline mysql-list-tables)) (uffi:def-function "mysql_list_tables" ((mysql mysql-mysql) (wild :cstring)) :module "mysql" :returning mysql-mysql-res) (declaim (inline mysql-list-fields)) (uffi:def-function "mysql_list_fields" ((mysql mysql-mysql) (table :cstring) (wild :cstring)) :module "mysql" :returning mysql-mysql-res) (declaim (inline mysql-list-processes)) (uffi:def-function "mysql_list_processes" ((mysql mysql-mysql)) :module "mysql" :returning mysql-mysql-res) (declaim (inline mysql-store-result)) (uffi:def-function "mysql_store_result" ((mysql mysql-mysql)) :module "mysql" :returning mysql-mysql-res) (declaim (inline mysql-use-result)) (uffi:def-function "mysql_use_result" ((mysql mysql-mysql)) :module "mysql" :returning mysql-mysql-res) (declaim (inline mysql-options)) (uffi:def-function "mysql_options" ((mysql mysql-mysql) (option mysql-option) (arg :pointer-void)) :module "mysql" :returning :int) (declaim (inline mysql-free-result)) (uffi:def-function "mysql_free_result" ((res mysql-mysql-res)) :module "mysql" :returning :void) (declaim (inline mysql-next-result)) (uffi:def-function "mysql_next_result" ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-fetch-row)) (uffi:def-function "mysql_fetch_row" ((res mysql-mysql-res)) :module "mysql" :returning (* (* :unsigned-char))) (declaim (inline mysql-fetch-lengths)) (uffi:def-function "mysql_fetch_lengths" ((res mysql-mysql-res)) :module "mysql" :returning (* :unsigned-long)) (declaim (inline mysql-fetch-field)) (uffi:def-function "mysql_fetch_field" ((res mysql-mysql-res)) :module "mysql" :returning mysql-field) (declaim (inline mysql-field-seek)) (uffi:def-function "mysql_field_seek" ((res mysql-mysql-res) (offset :unsigned-int)) :module "mysql" :returning :unsigned-int) (declaim (inline mysql-fetch-fields)) (uffi:def-function "mysql_fetch_fields" ((res mysql-mysql-res)) :module "mysql" :returning mysql-field) (declaim (inline mysql-fetch-field-direct)) (uffi:def-function "mysql_fetch_field_direct" ((res mysql-mysql-res) (field-num :unsigned-int)) :module "mysql" :returning mysql-field) (declaim (inline mysql-escape-string)) (uffi:def-function "mysql_escape_string" ((to (* :unsigned-char)) (from (* :unsigned-char)) (length :unsigned-int)) :module "mysql" :returning :unsigned-int) (declaim (inline mysql-debug)) (uffi:def-function "mysql_debug" ((debug :cstring)) :module "mysql" :returning :void) (declaim (inline clsql-mysql-num-rows)) (uffi:def-function "clsql_mysql_num_rows" ((res mysql-mysql-res) (p-high32 (* :unsigned-int))) :module "clsql-mysql" :returning :unsigned-int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-foreign-type mysql-stmt-ptr :pointer-void) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_init" ((res mysql-mysql-res)) :module "clsql-mysql" :returning mysql-stmt-ptr) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_prepare" ((stmt mysql-stmt-ptr) (query :cstring) (length :unsigned-long)) :module "clsql-mysql" :returning :int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_param_count" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :unsigned-int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_bind_param" ((stmt mysql-stmt-ptr) (bind mysql-bind)) :module "clsql-mysql" :returning :short) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_bind_result" ((stmt mysql-stmt-ptr) (bind mysql-bind)) :module "clsql-mysql" :returning :short) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_result_metadata" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning mysql-mysql-res) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_execute" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_store_result" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_fetch" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_free_result" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :short) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_close" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :short) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_errno" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :unsigned-int) #+(or mysql-client-v4.1 mysql-client-v5) (uffi:def-function "mysql_stmt_error" ((stmt mysql-stmt-ptr)) :module "clsql-mysql" :returning :cstring) ;;;; Equivalents of C Macro definitions for accessing various fields ;;;; in the internal MySQL Datastructures (declaim (inline mysql-num-rows)) (defun mysql-num-rows (res) (uffi:with-foreign-object (p-high32 :unsigned-int) (let ((low32 (clsql-mysql-num-rows res p-high32)) (high32 (uffi:deref-pointer p-high32 :unsigned-int))) (if (zerop high32) low32 (make-64-bit-integer high32 low32))))) (uffi:def-function "clsql_mysql_affected_rows" ((mysql mysql-mysql) (p-high32 (* :unsigned-int))) :returning :unsigned-int :module "clsql-mysql") (defun mysql-affected-rows (mysql) (uffi:with-foreign-object (p-high32 :unsigned-int) (let ((low32 (clsql-mysql-affected-rows mysql p-high32)) (high32 (uffi:deref-pointer p-high32 :unsigned-int))) (if (zerop high32) low32 (make-64-bit-integer high32 low32))))) (uffi:def-function "clsql_mysql_insert_id" ((res mysql-mysql) (p-high32 (* :unsigned-int))) :returning :unsigned-int :module "clsql-mysql") (defun mysql-insert-id (mysql) (uffi:with-foreign-object (p-high32 :unsigned-int) (let ((low32 (clsql-mysql-insert-id mysql p-high32)) (high32 (uffi:deref-pointer p-high32 :unsigned-int))) (if (zerop high32) low32 (make-64-bit-integer high32 low32))))) (declaim (inline mysql-num-fields)) (uffi:def-function "mysql_num_fields" ((res mysql-mysql-res)) :returning :unsigned-int :module "mysql") (declaim (inline clsql-mysql-eof)) (uffi:def-function ("mysql_eof" clsql-mysql-eof) ((res mysql-mysql-res)) :returning :char :module "mysql") (declaim (inline mysql-eof)) (defun mysql-eof (res) (if (zerop (clsql-mysql-eof res)) nil t)) (declaim (inline mysql-error)) (uffi:def-function ("mysql_error" mysql-error) ((mysql mysql-mysql)) :returning :cstring :module "mysql") (declaim (inline mysql-error-string)) (defun mysql-error-string (mysql) (uffi:convert-from-cstring (mysql-error mysql))) (declaim (inline mysql-errno)) (uffi:def-function "mysql_errno" ((mysql mysql-mysql)) :returning :unsigned-int :module "mysql") (declaim (inline mysql-info)) (uffi:def-function ("mysql_info" mysql-info) ((mysql mysql-mysql)) :returning :cstring :module "mysql") (declaim (inline mysql-info-string)) (defun mysql-info-string (mysql) (uffi:convert-from-cstring (mysql-info mysql))) (declaim (inline clsql-mysql-data-seek)) (uffi:def-function "clsql_mysql_data_seek" ((res mysql-mysql-res) (offset-high32 :unsigned-int) (offset-low32 :unsigned-int)) :module "clsql-mysql" :returning :void) (declaim (inline clsql-mysql-field-name)) (uffi:def-function "clsql_mysql_field_name" ((res mysql-field)) :module "clsql-mysql" :returning :cstring) (declaim (inline clsql-mysql-field-flags)) (uffi:def-function "clsql_mysql_field_flags" ((res mysql-field)) :module "clsql-mysql" :returning :unsigned-int) (declaim (inline clsql-mysql-field-type)) (uffi:def-function "clsql_mysql_field_type" ((res mysql-field)) :module "clsql-mysql" :returning :unsigned-int) (defun mysql-data-seek (res offset) (multiple-value-bind (high32 low32) (split-64-bit-integer offset) (clsql-mysql-data-seek res high32 low32))) cl-sql-6.7.2/db-mysql/mysql-client-info.lisp0000644000175000017500000000376113735402342017740 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: mysql-client-info.lisp ;;;; Purpose: Check mysql client version ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: April 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:mysql) (declaim (inline mysql-get-client-info)) (defvar *mysql-client-info* nil) (eval-when (:compile-toplevel :load-toplevel :execute) (uffi:def-function ("mysql_get_client_info" mysql-get-client-info) () :module "mysql" :returning :cstring) (setf *mysql-client-info* (uffi:convert-from-cstring (mysql-get-client-info))) (when (and (stringp *mysql-client-info*) (plusp (length *mysql-client-info*))) (cond ((eql (schar *mysql-client-info* 0) #\3) (pushnew :mysql-client-v3 cl:*features*)) ((eql (schar *mysql-client-info* 0) #\4) (pushnew :mysql-client-v4 cl:*features*) (when (and (>= (length *mysql-client-info*) 3) (string-equal "4.1" *mysql-client-info* :end2 3)) (pushnew :mysql-client-v4.1 cl:*features*))) ((eql (schar *mysql-client-info* 0) #\5) (pushnew :mysql-client-v5 cl:*features*) (when (and (>= (length *mysql-client-info*) 3) (string-equal "5.1" *mysql-client-info* :end2 3)) (pushnew :mysql-client-v5.1 cl:*features*))) ((eql (schar *mysql-client-info* 0) #\6) (pushnew :mysql-client-v6 cl:*features*)) (t (format t "Warning: Unknown mysql client version '~A', verify proper operation." *mysql-client-info*))))) cl-sql-6.7.2/db-mysql/mysql-loader.lisp0000644000175000017500000000430211746263021016766 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: mysql-loader.sql ;;;; Purpose: MySQL library loader using UFFI ;;;; Author: Kevin M. Rosenberg ;;;; Created: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:mysql) ;; searches clsql_mysql64 to accomodate both 32-bit and 64-bit libraries on same system (defparameter *clsql-mysql-library-candidate-names* `(,@(when (> most-positive-fixnum (expt 2 32)) (list "clsql_mysql64")) "clsql_mysql")) (defvar *mysql-library-candidate-names* '("libmysqlclient" "libmysql")) (defvar *mysql-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the MySQL client library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *mysql-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :mysql))) *mysql-library-loaded*) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :mysql))) (unless *mysql-library-loaded* (clsql:push-library-path clsql-mysql-system::*library-file-dir*) (clsql-uffi:find-and-load-foreign-library *mysql-library-candidate-names* :module "mysql" :supporting-libraries *mysql-supporting-libraries*) (clsql-uffi:find-and-load-foreign-library *clsql-mysql-library-candidate-names* :module "clsql-mysql" :supporting-libraries *mysql-supporting-libraries*) (setq *mysql-library-loaded* t))) (clsql-sys:database-type-load-foreign :mysql) cl-sql-6.7.2/db-mysql/testing/0000755000175000017500000000000010667176647015164 5ustar kevinkevincl-sql-6.7.2/db-mysql/testing/mysql-struct-size.cc0000644000175000017500000000050610667176647021133 0ustar kevinkevin#include #include "/usr/include/mysql/mysql.h" int main (int argc, char** argv) { printf ("Size of MYSQL struct: %ld\n", sizeof (MYSQL)); printf("Sizeof MYSQL_BIND: %d\n", sizeof(MYSQL_BIND)); printf("Sizeof MYSQL_FIELD: %d\n", sizeof(MYSQL_FIELD)); printf("Sizeof MYSQL_TIME: %d\n", sizeof(MYSQL_TIME)); } cl-sql-6.7.2/db-mysql/testing/mysql-struct-size.lisp0000644000175000017500000000044210667176647021514 0ustar kevinkevin(in-package :mysql) #+lispworks (progn (setq c (fli:allocate-foreign-object :type 'mysql-mysql)) (format t "~&Size MYSQL structure: ~d" (fli:pointer-element-size c))) #+allegro (progn (setq c (ff:allocate-fobject 'mysql-mysql :foreign)) (format t "~&Size MYSQL structure: ~A" c)) cl-sql-6.7.2/db-mysql/Makefile0000644000175000017500000000704214327124552015133 0ustar kevinkevin#!/usr/bin/make # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL MySQL interface # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. SUBDIRS= include ../Makefile.common base=clsql_mysql source=$(base).c object=$(base).o shared_lib=$(base).so shared64_lib=$(base)64.so dylib=$(base).dylib .PHONY: all all: $(shared_lib) CFLAGS:=-I /usr/local/include/mysql -I /usr/include/mysql -I /sw/include/mysql -I /opt/local/include/mysql -I /opt/local/include/mysql55/mysql -I /usr/local/mysql/include LDFLAGS:=-L/usr/local/lib64/mysql -L/usr/local/lib/mysql -L/usr/lib64/mysql -L/usr/lib/mysql -L/sw/lib -L/opt/local/lib/mysql -L/opt/local/lib/mysql5/mysql -L/usr/local/mysql/lib -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lmysqlclient -lz -lc CFLAGS32:=-I /usr/local/include/mysql -I /usr/include/mysql -I /sw/include/mysql -I /opt/local/include/mysql -I /opt/local/include/mysql5/mysql -I /usr/local/mysql/include -m32 LDFLAGS32:=-L/lib32 -L/usr/lib32 -lmysqlclient -lz -lc ifneq ($(OS_CYGWIN),0) CFLAGS:=-I /cygdrive/c/Program\ Files/MySQL/MySQL\ Server\ 5.0/include LDFLAGS:=-L/usr/local/lib64/mysql -L/usr/local/lib/mysql -L/usr/lib/mysql -L/sw/lib -L/opt/local/lib/mysql -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -lmysqlclient -lpthread -lz -lm -lgcc -lc endif ifneq ($(OS_DPKG_BUILDFLAGS),0) CFLAGS:=$(CFLAGS) $(shell dpkg-buildflags --get CFLAGS) LDFLAGS:=$(LDFLAGS) $(shell env DEB_BUILD_MAINT_OPTIONS=hardening=+all,-pie dpkg-buildflags --get LDFLAGS | sed "s/-Wl\|,/ /ig") endif $(shared_lib): $(source) Makefile ifneq ($(OS_AIX),0) gcc $(CFLAGS) -c -D_BSD -D_NO_PROTO -D_NONSTD_TYPES -D_MBI=void $(source) make_shared $(LDFLAGS) -o $(shared_lib) $(object) else ifneq ($(OS_SUNOS),0) cc $(CFLAGS) -KPIC -c $(source) -o $(object) cc -G $(object) $(LDFLAGS) -o $(shared_lib) else ifneq ($(OS_DARWIN64),0) cc $(CFLAGS) -arch x86_64 -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress $(source) -o $(dylib) cc -arch x86_64 -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress /usr/lib/libz.dylib -o z.dylib else ifneq ($(OS_DARWIN),0) cc $(CFLAGS) -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress $(source) -o $(dylib) cc -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress /usr/lib/libz.dylib -o z.dylib else ifneq ($(OS_CYGWIN),0) gcc $(CFLAGS) -DWIN32 -c $(source) -o $(object) ld -shared -soname=$(base) $(object) $(LDFLAGS) -o $(shared_lib) else ifneq ($(OS_LINUX64),0) gcc $(CFLAGS) -fPIC -c $(source) -o $(object) gcc $(LDFLAGS) -fPIC -shared -Wl,-soname=$(base) -lc $(object) -o $(shared64_lib) rm $(object) #@echo "Ensure that you have multiarch i386 build tools and libraries if you want to build 32-bit library" #-gcc $(CFLAGS32) -fPIC -c $(source) -o $(object) #-gcc $(LDFLAGS) -fPIC -shared -Wl,-soname=$(base) -lc $(object) $(LDFLAGS32) -o $(shared_lib) else gcc $(CFLAGS) -fPIC -c $(source) -o $(object) gcc -fPIC -shared -Wl,-soname=$(base) $(object) $(LDFLAGS) -o $(shared_lib) endif endif endif endif endif endif rm -f $(object) .PHONY: distclean distclean: clean @rm -f $(dylib) $(shared_lib) $(shared64_lib) $(object) z.dylib cl-sql-6.7.2/clsql-postgresql-socket.asd0000644000175000017500000000317211332141035017225 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-postgresql-socket.asd ;;;; Purpose: ASDF file for CLSQL PostgresSQL socket backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-postgresql-socket-system (:use #:asdf #:cl)) (in-package #:clsql-postgresql-socket-system) ;;; System definition (defsystem clsql-postgresql-socket :name "cl-sql-postgresql-socket" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL PostgreSQL Socket Driver" :long-description "cl-sql-postgresql-socket package provides a database driver to the PostgreSQL database via a socket interface." :depends-on (clsql md5 #-:clsql-cffi uffi #+:clsql-cffi cffi-uffi-compat #+sbcl sb-bsd-sockets) :components ((:module :db-postgresql-socket :components ((:file "postgresql-socket-package") (:file "postgresql-socket-api" :depends-on ("postgresql-socket-package")) (:file "postgresql-socket-sql" :depends-on ("postgresql-socket-api")))))) cl-sql-6.7.2/NEWS0000644000175000017500000000303112570246521012433 0ustar kevinkevinSep 14 2006 ----------- Version 4.0.0 release with incompatible backward change: - using ANSI mode for MySQL backend - reducing case changes in SQL output for symbols which will have an effect for users of mlisp (Allegro "Modern" Lisp) . - Add support for generating quoted strings in SQL output when specifying table names as strings rather than symbols. This may have an effect on applications that use strings as table names and use inconsistent case in the table names. Previously, those varying case strings would be mapped to a canonical case unquoted SQL output. But to accomodate users which need to specify case in table names, this mapping has been removed. See ChangeLog entry for details. Dec 30 2006 ----------- Version 3.8.0 released with incompatible backward change. See the ChangeLog entry for details. Aug 3 2006 ---------- CLSQL 3.0 has been released. The 3.0 release of CLSQL is a major rewrite compared to version 2.0. New features include: - Full CommonSQL backward compatibility with native documentation while retaining and adding many improvements beyond the CommonSQL standard. - Extensive (233 tests) regression suite - Addition of ODBC and Oracle backends I wish to acknowledge Marcus Pearce's significant contribution to this release. He has performed the initial port of Uncommonsql to CLSQL as well as the initial regression suite and most of the new documentation. He has contributed to many of the re-design decisions and new code for CLSQL. CLSQL's home is http://clsql.kpe.io Enjoy! Kevin Rosenberg cl-sql-6.7.2/BUGS0000644000175000017500000000241111746263021012416 0ustar kevinkevin1. SBCL/Postgresql Interaction Gabor Melis reported an interaction with SBCL and the postgresql database backend using a multithreaded program and Portable AllegroServe. It appears that libpg installs its own SIGPIPE handler. When a multithreaded program servicing socket requests has SIGPIPE conditions thrown, the running SBCL instance is killed. The web page http://linux.com.hk/docs/postgresql/libpq-threading.html has more information about libpq's SIGPIPE handler. 2. Object joining Aleksandar Bakic reported the documentation says that :home-key and :foreign-key properties of the :db-info property may contain lists of symbols. However, update-objects-joins fails in such cases. 2. configure file Automatically generate makefiles based on the configuration of an end-users system 3. SBCL/MySQL interaction Similar to the postgres interaction noted above SBCL installs its own SIGPIPE handler but the mysql library disables it breaking thread interrupts. See also http://ccl.clozure.com/irc-logs/lisp/2012-02/lisp-2012.02.22.txt Look for the conversation starting at 20:03:32 between bobbysmith007 and pkhuong. 4. Thread safety issues. While clsql attempts to be threadsafe there are some significant issues with some backends. See doc/threading-warnings.txt for more info. cl-sql-6.7.2/clsql-cffi.asd0000644000175000017500000000204011332141035014434 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-cffi.asd ;;;; Purpose: ASDF System definition for CLSQL using CFFI-UFFI-COMPAT ;;;; Author: Kevin M. Rosenberg ;;;; Created: Jan 2010 ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (push :clsql-cffi cl:*features*) (defpackage #:clsql-cffi-system (:use #:asdf #:cl)) (in-package #:clsql-cffi-system) (defsystem clsql-cffi :name "CLSQL-CFFI" :author "Kevin Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "CLSQL using CFFI-UFFI-COMPAT interface" :depends-on (clsql) :components nil) cl-sql-6.7.2/LATEST-TEST-RESULTS0000644000175000017500000000721612651763351014605 0ustar kevinkevinNote from Russ Tyndall 2015-03-23 : This is the current results of running the test suite against all the database backends I have accessible, on SBCL / UBUNTU64bit. It would be great to continue improving the test suite and skip tests that reliably fail, improve tests so that all pass. In the interim, I would like know that I am not increasing the number of failing tests :mysql No tests failed. 18 of 310 Tests skipped :odbc MSSQL2000/5 No tests failed. 22 of 306 Tests skipped: :odbc postgres *couldnt get them to run - foreign lib problems* :postgres-socket :postgres-socket-3 4 out of 308 total tests failed: :TIME/PG/OODML/USEC, :TIME/PG/OODML/NO-USEC, :TIME/PG/FDML/USEC, :FDML/SELECT/36. 20 of 308 Tests skipped: :sqlite3 1 out of 308 total tests failed: :FDDL/INDEX/3. 20 of 308 Tests skipped: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Version 3.0.0 run on August 3, 2004 on x86, x86_64, and PowerPC platforms POSTGRESQL: All 233 tests passed (x86, Allegro CL Enterprise Edition). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (x86, Allegro CL Enterprise Edition). MYSQL: All 213 tests passed (x86, Allegro CL Enterprise Edition). SQLITE: All 224 tests passed (x86, Allegro CL Enterprise Edition). ODBC/POSTGRESQL: All 232 tests passed (x86, Allegro CL Enterprise Edition). ODBC/MYSQL: All 213 tests passed (x86, Allegro CL Enterprise Edition). ORACLE: All 227 tests passed (x86, Allegro CL Enterprise Edition). AODBC/UNKNOWN: 23 of 231 tests failed (x86, Allegro CL Enterprise Edition). POSTGRESQL: All 233 tests passed (X86, CMU Common Lisp). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (X86, CMU Common Lisp). MYSQL: All 213 tests passed (X86, CMU Common Lisp). SQLITE: All 224 tests passed (X86, CMU Common Lisp). ODBC/POSTGRESQL: All 232 tests passed (X86, CMU Common Lisp). ODBC/MYSQL: All 213 tests passed (X86, CMU Common Lisp). ORACLE: All 227 tests passed (X86, CMU Common Lisp). POSTGRESQL: All 233 tests passed (NIL, LispWorks). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (NIL, LispWorks). MYSQL: All 213 tests passed (NIL, LispWorks). SQLITE: All 224 tests passed (NIL, LispWorks). ODBC/POSTGRESQL: All 232 tests passed (NIL, LispWorks). ODBC/MYSQL: All 213 tests passed (NIL, LispWorks). ORACLE: All 227 tests passed (NIL, LispWorks). POSTGRESQL: All 233 tests passed (X86, SBCL). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (X86, SBCL). MYSQL: All 213 tests passed (X86, SBCL). SQLITE: All 224 tests passed (X86, SBCL). ODBC/POSTGRESQL: All 232 tests passed (X86, SBCL). ODBC/MYSQL: All 213 tests passed (X86, SBCL). ORACLE: All 227 tests passed (X86, SBCL). POSTGRESQL: All 233 tests passed (64-bit AMD64, Allegro CL Enterprise Edition). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (64-bit AMD64, Allegro CL Enterprise Edition). MYSQL: All 223 tests passed (64-bit AMD64, Allegro CL Enterprise Edition). SQLITE: All 224 tests passed (64-bit AMD64, Allegro CL Enterprise Edition). ORACLE: All 227 tests passed (64-bit AMD64, Allegro CL Enterprise Edition). POSTGRESQL: All 233 tests passed (PowerPC, SBCL). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (PowerPC, SBCL). MYSQL: All 217 tests passed (PowerPC, SBCL). SQLITE: All 224 tests passed (PowerPC, SBCL). ODBC/POSTGRESQL: All 232 tests passed (PowerPC, SBCL). ODBC/MYSQL: All 217 tests passed (PowerPC, SBCL). POSTGRESQL: All 233 tests passed (ppc, OpenMCL). POSTGRESQL-SOCKET/POSTGRESQL: All 233 tests passed (ppc, OpenMCL). MYSQL: All 217 tests passed (ppc, OpenMCL). SQLITE: All 224 tests passed (ppc, OpenMCL). ODBC/POSTGRESQL: All 232 tests passed (ppc, OpenMCL). ODBC/MYSQL: All 217 tests passed (ppc, OpenMCL). cl-sql-6.7.2/LICENSE0000644000175000017500000000245714327125022012746 0ustar kevinkevinCopyright (C) 2002-2022 by Kevin M. Rosenberg Copyright (C) 1999-2001 Pierre R. Mai (MaiSQL ) Copyright (C) 1999-2020 onShore Development (UncommonSQL) Copyright (C) 1999-2001 Paul Meurer (SQL/ODBC) Copyright (C) 2010-2015 Marc Battyani Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cl-sql-6.7.2/ChangeLog0000644000175000017500000042022314327125022013506 0ustar kevinkevin2022-10-28 Kevin Rosenberg * Version 6.7.2 release * LICENSE: After consulting with the contributors to CLSQL, CLSQL is now relicensed under MIT license 2016-01-26 Kevin Rosenberg * Version 6.7.0 release * sql/utils.lisp: Apply patch from Martin Simmons for Lispworks 7 compatiblity 2016-01-17 Russ Tyndall * applied patches from Javeier Olaechea * allows unix socket connections in clsql-postgressql-socket3 * modernize asd slightly 2015-10-09 Russ Tyndall * add decimals.lisp file https://github.com/tlikonen/cl-decimals * use this for safe parsing of numeric / decimal / rational types * Added because newer postgres print money types as currency strings 2015-08-12 Kevin Rosenberg * Version 6.6.3 release * db-oracle/oracle-sql.lisp: Patch for PostgreSQL socket interface for unicode characters. Thanks to Jason Melbye. 2015-06-02 Daniel KochmaÅ„ski * clsql.asd, sql/package.lisp: Add ECL compatibility fixes * sql/db-interface.lisp: Fix declaration typo 2015-04-06 Russ Tyndall * sql/operations, sql/expressions: add postgresql E-string operator / expression. Needed for correct regex handling EG: [E "some string"]=> E'some string' 2015-03-30 Kevin Rosenberg * Version 6.6.2 release * db-oracle/oracle-sql.lisp: Remove extra hyphen, thanks to Thomas Vossen 2015-03-24 Russ Tyndall * sql/oodml.lisp: fixed call-next-method in the base of read-sql-value and replaced with a continuable sql-value-conversion-error * default read-sql-value for list * tests for sql-value-conversion-errors and list 2015-03-18 Russ Tyndall * {uffi,db-mysql}/Makefile: remove -pie build hardening for which caused load issues for Linux Mint 2015-03-18 Kevin Rosenberg * Version 6.6.1 release * {uffi,db-mysql}/Makefile: Remove pie from build hardening options for Debian/Ubuntu systems. Thanks to DJ and Russ Tyndall 2015-02-26 Kevin Rosenberg * Version 6.6.0 release * {uffi,db-mysql}/Makefile: Add build hardening for Debian 2015-02-24 Russ Tyndall * mysql-sql.lisp an error in type declarations generating a compilation warning was being treated as an error in recent SBCLs, fixed the type warning by correcting the type (still a ton of compliation notes) 2015-02-23 Russ Tyndall * sql/metaclasses.lisp made reinitialize-instance return the instance passed to it as SBCL now expected (mentioned on the SBCL-devel mailing list by Stas 2014-12-03 Russ Tyndall * sqlite-sql.lisp Added database arg to `canonicalize-result-types` so that it could correctly call `sqlite-aref` with the required number of arguments Thanks Zach Beane for the bug report. 2014-07-29 Russ Tyndall * mysql-api.lisp, mysql-sql.lisp, test-connection.lisp Added code to the mysql backend to pull all result sets as multiple args. This fixes a bug in the mysql backend where trying to query after executing a stored procedure (even on a pooled connection) would raise an error about the connection being out of sync. The second result set for the stored procedure seems to be empty, so not sure why we need to iterate past it. patch / bugreport provided by: Ilya Khaprov deadtrickster@github 2014-06-11 Russ Tyndall * databases.lisp, sqlite3-sql.lisp Similar to and overriding the patch 2014-01-30 937a3d, adds a default-encoding variable uses that in places where a nil encoding was being passed. Defaults to :utf-8. This is mostly in place so that uffi and cffi both work similarly (by moving the default into clsql instead of clsql-uffi). This allows my automated build environment to do its job 2014-06-10 Russ Tyndall * db-mysql/Makefile - the results of dpkg-buildflags --get LDFLAGS seem to have changed on my system and and sed was returning invalid command line arguments to ld. To resolve this I changed sed to emit valid args, which seems to have resolved the issue. 2014-04-24 Russ Tyndall * oodml.lisp, test-oodml.lisp Better handling of view-slots of type symbol/keyword. Better handling of printing and reading bindings (per mailing list request, always read and write in base 10) 2014-03-04 Kevin Rosenberg * Version 6.5.0: New release * makefile.common: Check for /usr/bin/dpkg-buildflags * {db-mysql,uffi}/Makefile: Use debian buildflags 2014-02-24 Russ Tyndall * oodml.lisp bind *print-length* to nil before printing lists/arrays to the database. 2014-01-30 Russ Tyndall * sqlite3-sql.lisp specify :utf-8 as the default encoding if there is not one (allows :clsql-cffi to be closer to working for this backend). I ran the test suite successfully once with :clsql-cffi, but there after I got spurious errors and especially unrecoverable errors while connecting about the database being locked 2014-01-30 Russ Tyndall * sqlite3-sql.lisp, fddl.lisp Dont compare database-identifiers with invalid comparison operators 2014-01-30 Russ Tyndall * generic-odbc.lisp, ooddl.lisp, generic-postgresql.lisp, test-init.lisp, ds-nodes.lisp, generic-odbc.lisp, odbc-sql.lisp auto-increment-column support improvement (mssql esp, now will auto-fill after insert). Use +auto-increment-names+ to determine auto-increment-column-p. This triggered much test failing as regards normalized classes / autoincrement primary key stuff. New odbc-postgresql-database sub-type POSSIBLY BREAKING CHANGES: 1 ) Previously all classes in a normalized heirachy had their p-key marked as "auto-increment". Usually auto-increment means a key supplied by the database system, so this was decidedly non-standard usage (clsql is explicitly providing the key for all normalized subclasses of any given parent see ds-nodes.lisp). Some RDMS will not allow insertion/updates of autoincrement columns without hoop jumping and, as it doesnt really make much sense, I removed the "auto-increment" aspects of normalized sub-classes. Now the primary keys are chained regardless. The parent-most key can be autoincrement or not. 2 ) ODBC Postgresql connections are now both GENERIC-ODBC-DATABASE and GENERIC-POSTGRESQL-DATABASE. Probably not a widely used path, but this change allows most of the previously failing tests to pass on this backend (we now format stuff correctly for postgres). I anticipate this probably is not perfect yet (IE: I probably missed something) 2014-01-29 Russ Tyndall * oodml.lisp, generics.lisp - added clsql-sys::view-classes-and-storable-slots generic (added method previously). Also added to-database-p keyword to allow overrides to distinguish between the two situations. Mostly so that clsql-helper:dirty-slots-mixin can filter slots when writing values to the database but still allow all slots to be read from the database 2014-01-17 Russ Tyndall * oodml.lisp, generics.lisp - added filter-select-list generic to allow fine grained control of generated query/object mappings 2014-01-07 Russ Tyndall * clsql-uffi.lisp, sqlite3 auto-increment support * clsql-uffi.lisp, test-basic.lisp, fixes related to unsigned vs signed ints (thanks Aaron Burrow) * cleaning and testing 2013-09-27 Russ Tyndall * fixed bug converting to boolean in db-mysql/mysql-sql.lisp from github user Sectoid https://github.com/UnwashedMeme/clsql/pull/1 2013-06-19 Russ Tyndall * sql/oodml.lisp, db-postgresql-socket3/sql.lisp, db-mysql/mysql-objects.lisp, sql/generic-odbc.lisp Refactored read-sql-value similar to the other recent refactorings * the symbol case now uses intern instead of read-from-string (which may not return a symbol and could have security issues since read-eval was not being unset) * read-eval is now off for all cases * centralized logic into a single case statement, hopefully making this more readable and debuggable * TODO: make these refactorings to the oracle backend (I cannot test against oracle and am loathe to change without testing 2013-06-19 Russ Tyndall * sql/mysql-objects.lisp Found and refactored a way some more eql specified methods of database-get-type-specifier in mysql 2013-06-18 Russ Tyndall * sql/oodml.lisp, sql/mysql-objects.lisp refactored database-output-sql-as-type in a similar fashion to the previous refactor of database-get-type-specifier (fewer methods using case instead of eql specifiers) * removed very strange definition of outputing floats as strings for something sane (it was previously doing silly work like setting the default read float type (which AFAICT doesnt affect printing)) * half of the cases nil returned "" other times it returned nil, now if we get a null value we return nil always * removed odd-logic (seemingly untouched since the initial import), that removed null characters from printed lists. If we have #\null in a printed list, we had probably better figure out what went wrong there rather than destructively modifying the list output on the way to the DB ;; removed (substitute-char-string escaped #\Null " ") 2013-06-18 Russ Tyndall * sql/generic-odbc.lisp, sql/generic-postgresql.lisp, sql/oodml.lisp tests/test-fddl.lisp refactored database-get-type-specifier for postgres and mssql Single methods with a case on the symbol arg (similar to the recent refactoring in oodml.lisp) This reduces line count and generally makes it easier to find and read all the backend-specific types 2013-06-10 Russ Tyndall * sql/oodml.lisp, sql/generic-postgresql.lisp, doc/ref-fddl.xml, sql/packages.lisp Updated get-database-type-specifier to handle text/longchar type and refactored * added a warning above defaulting to VARCHAR (since its probably NOT what is expected on a bad type specifier). * added a case where the specified type being a string, passes that string directly (to better/more easily allow db-specific data-types). * added cases where longchar or text converts to text, and exported those symbols (as this seemed type seemed to be missing from fddl/oddl anyway). * reorganized these default methods into a single method with a case statement rather than many eql specified methods (about half the code) * updated the docs to use text instead of longchar since text is a more standard db-type (pg,my,and ms all use text) 2013-11-23 Kiss Kalman * utils/sql.lisp: Commit patch adding ccl getenv support 2013-04-17 Kevin Rosenberg * Version 6.4.1 * sql/utils.lisp: Patch from Ben Hyde to add weak hash table support for CCL. 2013-03-07 Ryan Davis * db-postgresql-socket/postgresql-socket-api.lisp - bugfix to adapt to changes in md5:md5sum-sequence. CLSQL now requires a version of MD5 released on or after 2012-11-25 (the latest version currenty in quicklisp). Thanks to Nicolas Neuss for the bug report. * db-odbc/odbc-sql.lisp - keep a reference to the original connection spec used to create `odbc-database` connections 2013-01-09 Russ Tyndall sql/oodml.lisp - changed view-classes-and-storable-slots to a method (as it was intended to be all along) 2012-12-19 Kevin Rosenberg * Version 6.4 2012-11-20 Russ Tyndall ## Large refactoring of sql/oodml.lisp and surrounding code * cleaned up update-records-from-* to utilize a single codepath previously there was much duplicate code * tried to further unify direct/effective slot-defs * cleaned up much of the normalized classes code to be more consistent in how it operated, and the code it used (less copy/paste more functions) * tried to standardize iteration a bit, previously almost all of the iteration constructs in CL were used. Tried to standardize on loop for readability / cohesiveness * made functions to more easily look up particular slots, since this was being done differently in each function * added more doc-strings and updated documentation about normalized classes * inner-joins that are referenced in where clauses are no longer added to the select table list (since they are also referenced in the join position and this led to sql errors) * collect-table-references methods added for sql-ident-table and list ## Semantic changes * disallow where-less updates from objects (ie cannot call update-records-from* with a keyless object) * ordered-class-direct-slots now returns direct-slot-definitions instead of effective-slot-definitions (as per name) * direct-slot-definitions now contain the db-info hash table (same as effective slots) * removed this-class arg from update-instance-from-records - used to be used for normalized code, no longer needed for that. * find-all - bug fixes in table references, previously where clauses surrounded by a list would have none of their references added to the select. This was being exploited by certain code paths. Now all where clauses are searched - No longer includes order-by and distinct as columns in the select list. The values seemed to be ignored in every code path and distinct seemed to be intended to be used as a boolean anyway 2012-11-20 Nathan Bird * update-objects-joins - changed the default of slot from t (which used to mean :deferred) to :immediate (to match the default behavior of other parts of the system). It also seemed like a bad default to pull all the slots that were explicitly specified to be not pulled by default. This function now accepts more special values (:immediate, :deferred, :all, or a list of slots). To get the old behavior call with :slots :deferred. 2012-10-30 Russ Tyndall * sql/command-object.lisp - added dates/times to the parameter value coersion and pulled this into a new generic prepare-sql-parameter 2012-09-04 Kevin Rosenberg * Version 6.3 released 2012-09-04 Russ Tyndall * sql/expressions.lisp - Try to respect the casing of symbols where it seems intentional (ie: is not default). This should fix a failing test case, and I think behaves more understandibly. If you specify a casing '|Foo Bar| lets treat that a string "Foo Bar" and output it escaped 2012-08-28 Ryan Davis * db-sqlite3/sqlite3-api.lisp - allow pathnames in the connection settings, so '("/db/my.sqlite") and '(#P"/db/my.sqlite") are equivalent. Updated the docs to match. 2012-08-17 Russ Tyndall * db-postgresql-socket3/package.lisp - shadow postgresql-notification for compatibility with new cl-postgres (Thanks Zach) 2012-07-09 Russ Tyndall * sql/oodml.lisp - fixed a bug where the order by was being destructively modified, causing odd caching issues when the selected object was not statically known (eg unreferenced tables could show up in the query if they were cached by a previous call through this function. I replaced this code with a non-destructive variant which should solve this. Thanks to Philipp Marek for the bug report 2012-06-25 Russ Tyndall * sql/util.lisp, sql/metaclasses.lisp Dequote database-identifiers if needed (passed a quoted symbol) Metaclass args come through unquoted, so this eases interactions with them 2012-06-22 Russ Tyndall * sql/metaclasses.lisp: Changed compute-effective-slot-definition to correctly copy the autoincrement-sequence slot to the ESD previously it was being skipped (seemingly by accident). Thanks to flip214 on #lisp for the bug report 2012-04-26 Kevin Rosenberg * Version 6.2 released: thanks to all the contributors! 2012-04-25 Nathan Bird * doc/threading-warnings.txt: Adding some notes from J.T.Klein about the current state of thread-safety in clsql. This should be incorporated into the main docs at some point. 2012-04-25 Russ Tyndall * sql/expressions.lisp (output-sql): on rendering update/insert expression values, ensure that *in-subselect* is bound to T so that the values will be correctly paren delimited 2012-04-24 Nathan Bird * sql/expressions.lisp (output-sql): on mysql CREATE TABLE statements use 'ENGINE=innodb' instead of 'Type=InnoDB'. This has apparently been preferred since mysql 4.1 and mysql 5.5 removed type as a valid keyword. 2012-03-28 Russ Tyndall * sql/sequences.lisp: [A Patch FROM 2011-07-28 changed sequences. They were previously prefixed with _CLSQL_SEQ_ but are now suffixed with _CLSQL_SEQ. This is likely to break existing implementations using the default sequence names setting *old-sequence-names* to T, should force using the older naming scheme 2012-03-27 Ryan Davis * sql/expressions.lisp: Fixed bug with subqueries in the where clause of update-records and delete-records generating invalid SQL. Previously subselects in where clauses would not have enough parentheses, for example: "WHERE Id IN SELECT foo_id FROM bar" vs. "WHERE Id IN (SELECT foo_id FROM bar)" * tests/test-syntax.lisp: Added tests for using subqueries in the where clause in update-records and delete-records. Moved asserts in the test-output-sql/sql-ident-table function into the standard test framework. * doc/appendix.xml: added :connection-string to the information on ODBC connection specs, and added example code connecting to ODBC databases. 2012-01-05 Nathan Bird * db-odbc/odbc-dbi.lisp: handle sql decimal type in the same way as numeric type-- read into a double float. 2011-01-04 Russ Tyndall * sql/operations.lisp Fixed bug reported by JTK related to the not-null sql-expression especially as used in conjunction with the is operator. Made null called with more than one argument throw an exception instead of silently discarding all arguments past the first 2012-01-04 Nathan Bird * db-odbc/odbc-api.lisp (%sql-driver-connect): in the call to odbc's SQLDriverConnect default the WindowHandle argument to a null ptr so that connecting with :connection-string will work in the default case of SQL_DRIVER_NOPROMPT. I.e. you can now do things like: (clsql:connect '("DsnName" "UserName" "" :connection-string "DRIVER={FreeTDS};SERVER=...;DATABASE=...;UID=...;PWD=...;PORT=1433;TDS_Version=8.0;APP=clsql") :database-type :odbc) I believe the DsnName and Username at that point are only used when printing the connection information. 2011-12-20 Kevin Rosenberg * Version 6.1.1 * db-oracle/oracle.lisp: Typo correction (Elias Martenson) 2011-12-19 Kevin Rosenberg * Version 6.1.0 * db-oracle/oracle.lisp: Change length function to uffi:foreign-string-length to handle foreign encodings. Thanks to Elias Martenson. 2011-11-28 Russ Tyndall * db-odbc/odbc-api.lisp, tests/test-time.lisp In ODBC backend, avoid going through the common lisp universal-time type (because it lacks support for historic dates) *time-conversion-function* renamed to *time-format* Patch from: Francisco Vides Fernandez 2011-10-18 Russ Tyndall * db-odbc/odbc-api.lisp Added type specifier so MSSQL nvarchar fields can make it through 2011-09-12 Russ Tyndall * sql/fddl.lisp sql/generic-postgres.lisp db-mysql/mysql-sql.lisp sql/generic-odbc.lisp sql/odbc-api.lisp sql/odbc-dbi.lisp Fix bugs in list-attribute(s|-types) where passing an escaped, instead of unescaped column name, caused these functions to return less data than they should have. 2011-08-03 Kevin Rosenberg * CLSQL 6.0.0 released 2011-07-28 Russ Tyndall * db-postgresql-socket3/: Added a backend that utilized postgres socket api version 3. Uses the cl-postgres project (from postmodern) to handle this. Allows use of parameterized / prepared queries using clsql:command-object * sql/{expressions,fddl, generic-postgresql, ooddl}.lisp: Change how database identifiers are emitted to hopefully make this less brittle, and more easily intuitable. Previously every code path that wanted to emit a database identifier was responsible for coercing what was provided into a correctly escaped string. Sometimes two or three functions in a row were trying to correctly quote and output that string. I have tried to centralize this type coercion and logic into a single code path. everything should now call (escaped-database-identifier thing) immediately before splicing a database identifier into string being sent to the database * sql/oodml.lisp: added method choose-database-for-instance, which allows overriding which database connections are used based on object type. Can be used to prevent connection conflicts in multi-threaded environments * sql/syntax.lisp: [foo bar] and [foo.bar] read into the same clsql expression now (they used to be output the same, but after the above database-identifier change, they were output separately * test/: Better, more tests, better type coercion in tests and throughout (%get-int) [edit 2012-03-28 - RT] * sql/sequences.lisp: Sequences were previously prefixed with _CLSQL_SEQ_ but are now suffixed with _CLSQL_SEQ. This is likely to break existing implementations using the default sequence names setting *old-sequence-names* to T, should force using the older naming scheme 2011-07-16 Kevin Rosenberg * Version 5.4.0 release 2011-06-27 Nathan Bird * db-odbc/: memory management improvements: leak slower * MSSQL: TOP + DISTINCT work together 2011-06-20 Nathan Bird * sql/time.lisp: Handle parsing already parsed objects. * sql/oodml.lisp: raise exception if we generate an update with no where clause; incorporate Ryszard Szopa's patch for functional expressions in :order-by * sql/expressions.lisp: (listify nil) => nil instead of (nil). * db-odbc/: bugfixes for working with older versions of FreeTDS; support for bigints that works on mssql and postgres * MSSQL improvements: use top instead of limit, IDENTITY can be a column constraint, clsql:date becomes 'smalldatetime' 2011-06-20 Nathan Bird * Version 5.3.4 * db-postgresql-socket/postgresql-socket-api.lisp: Addendum to Otto Diesenbacher's patch that had a spurious write a 0 byte (to terminate string) that should have been just CCL. 2011-06-12 Kevin Rosenberg * Version 5.3.3 * db-postgresql-socket/postgresql-socket-api.lisp: Patch from Otto Diesenbacher for UTF8 encoded strings for CCL. FIXME: The best patch would be to use the user-set encoding from the database object and use UFFI's encoding strings to/from octet vectors rather than SB-UNICODE and CCL specific code in this file. 2011-04-21 Kevin Rosenberg * sql/generics.lisp: Add defgeneric for new database-last-auto-increment-id 2011-04-01 Kevin Rosenberg * Version 5.3.2 * db-mysql/mysql-client-info.lisp: Add recognition of version 6 of MySQL client library. * sql/metaclass.lisp: Fix the fix in the reader conditional 2011-03-30 Kevin Rosenberg * Version 5.3.1 * sql/metaclasses.lisp: Fix previous patch to work on non-SBCL systems 2011-03-29 Kevin Rosenberg * Version 5.3.0 * sql/metaclasses.lisp: Apply one-line patch to fix for newer SBCL (thanks to Nikodemus Siivola) * many_files: Applied multiple patches from Holger Schauer to improve autoincrement capability. 2010-10-24 Kevin Rosenberg * Version 5.2.0 * db-odbc/odbc-api.lisp: Change from SBCL-specific to UFFI version of octets-to-strings. Reported by Daniel Brunner * sql/oodml.lisp: Apply patch from Rupert Swarbrick : Fix behaviour with auto-inc primary keys. * sql/expressions.lisp, tests/test-syntax.lisp: Apply patch from Russ Tyndall to quote identifiers with space or special character. 2010-09-20 Kevin Rosenberg * Version 5.1.4 * sql/{pool,database}.lisp: Pass encoding argument to connections made from pool and with reconnect. 2010-08-16 Kevin Rosenberg * Version 5.1.3 * db-odbc/odbc-{api,dbi}.lisp: Commit patch from Memet Bilgin to fix issue with unicode and ODBC. 2010-08-16 Kevin Rosenberg * Version 5.1.2 * uffi/clsql-uffi.lisp: Commit patch from JT Klein fixing invocation of uffi:convert-from-foreign-string macro. When time allows, I'll investigate changing UFFI's macro to a function call and then revert this patch. 2010-06-15 Kevin Rosenberg * Version 5.1.1 * clsql-{uffi,mysql}.asd: Modify operation-done-p functions to guard against change introduced in new ASDF traversing. 2010-04-20 Kevin Rosenberg * Version 5.1.0 [DEPENDENCY UPGRADE: UFFI 2.x needed] * clsql-uffi.asd: Depend on UFFI version >= 2.0 to support foreign encoding of strings. 2010-04-16 Kevin Rosenberg * Version 5.0.6 * db-postgresql.lisp, sql/fddl.lisp: Fix typos [Thanks to Walter C. Pelissero] * sql/metaclasses.lisp: Work around type-check-function being set during defclass expansion in SBCL [Thanks to Walter C. Pelissero] * uffi/clsql-uffi.lisp: In call to uffi:convert-from-foreign-string, Set null-terminated-p to T when length not specified. [Thanks to Walter C. Pelissero] 2010-03-21 Kevin Rosenberg * Version 5.0.5 * sql/fdml.lisp: Fix DO-QUERY to actually return the last value of the body. 2010-03-02 Nathan Bird * doc/: Added a README on how to build doc; now builds on Ubuntu. * sql/oodml.lisp: READ-SQL-VALUE now has explicit method for handling double-floats and the default method will no longer attempt to convert values that have already been converted. * sql/syntax.lisp: Introduce file-enable-sql-reader-syntax which enables the syntax for the scope of the file without trying to keep track of the current syntax state. * sql/pool.lisp: Introduce clsql-sys:*db-pool-max-free-connections* which is a heuristic threshold for when to disconnect a connection rather than returning it to the pool. * sql/pool.lisp: Check connections for validity before returning to the user. 2010-03-01 Kevin Rosenberg * db-mysql/mysql-api.lisp: Remove spurious enumeration 2010-02-16 Kevin Rosenberg * Version 5.0.4 * db-mysql/mysql-api.lisp: Fix mysql_options UFFI parameter list * doc/ref-connect.xml: Document the MySQL options parameter as part of the connection-spec. 2010-02-15 Kevin Rosenberg * db-mysql/mysql-{api,sql}.lisp: Support sending options to MySQL using mysql_options, which occurs between the API calls of mysql_init and mysql_real_connect. 2010-02-11 Kevin Rosenberg * Version 5.0.3 * multiple-files: Further internationalization. Change UFFI:CONVERT-RAW-FIELD and UFFI:CONVERT-FROM-FOREIGN-STRINGS invocations to use the foreign character set encoding of the database object. Requires UFFI v.1.8.6 * Makefile.common: Fix OS_DARWIN64 setting 2010-02-11 Nathan Bird * MSSQL: better support for fddl 'date type. 2010-02-11 Kevin Rosenberg * Makefile.common, uffi/Makefile, db-mysql/Makefile: Better support OS X Snow Leopard by building universal (x86_64,i386) dylib bundles 2010-02-08 Kevin Rosenberg * Version 5.0.2 * sql/database.lisp: Fix missing slot-accessor (Thanks to Stelian Ionescu) * sql/generics.lisp: Add missing keyword to defgeneric (Thanks to Stelian Ionescu) 2010-02-07 Kevin Rosenberg * Version 5.0.1 * sql/{base-classes,database}.lisp: Add encoding slot for non-ASCII strings. * db-mysql/mysql-sql.lisp: Use UFFI:FOREIGN-ENCODED-OCTET-COUNT. Requires UFFI version 1.8.2 or above. 2010-02-06 Kevin Rosenberg * Version 5.0.0: First release of CLSQL to formally and consistently support non-ASCII strings with encoding of external formats for SQL strings. UFFI version 1.8.1 is higher is required. This change may introduce some differences in string handling for people who are using non-ASCII encoded characters. Thus, because of the risk of BACKWARD INCOMPATIBILITY, the major version number was incremented with this release. 2010-02-06 Kevin Rosenberg * tests/test-i18n.lisp: Bind UFFI:*DEFAULT-EXTERNAL-FORMAT* for testing multibyte encodings. * uffi/clsql-uffi.lisp: Changes for UFFI 1.7.4's new support for encoding foreign strings with a specified external format. 2010-02-06 Kevin Rosenberg * sql/metaclasses.lisp: If no declared slot type in compute-lisp-type-from-specified-type, then use t as lisp type. Issue noted when testing Clozure CL 1.4. 2010-02-06 Kevin Rosenberg * tests/test-init.lisp: Turn off the benign console notices for testing on postgres. 2010-02-05 Kevin Rosenberg * clsql-test.asd, tests/{test-i18n,test-init}.lisp: Load test-i18n.lisp and use its tests as long as 'uffi:no-i18n is not present in cl:*features*. This requires UFFI 1.7.2 or above. 2010-02-05 Kevin Rosenberg * sql/utils.lisp: Reading #\no-break_space causes an error for non-unicode SBCL. Conditionalize read of #\no-break_space for non-unicode SBCL and 8-bit string Allegro. 2010-02-03 Kevin Rosenberg * tests/test-init.lisp: Add *test-report-width* variable and word-wrap skipped test reason field. 2010-01-29 Kevin Rosenberg * Version 4.3.3 * clsql-cffi.asd: New file that causes CLSQL to use CFFI-UFFI-COMPAT library rather than UFFI. Perform 'asdf:load-op on CLSQL-CFFI rather than CLSQL system to use CFFI-UFFI-COMPAT. 2010-01-29 Nathan Bird * tests/*.lisp: A lot more tests and test setup tweaks. * sql/expressions.lisp: output-sql on sql-relational-exp does better arity checking now. (apply #'sql-and some-list) gives better results. 29 Jan 2009 Kevin Rosenberg * sql/oodml.lisp: Fix for UPDATE-RECORD-FROM-SLOTS for normalized view classes 28 Jan 2009 Kevin Rosenberg * Version 4.3.2 * Change "normalise" from British spelling for consistency with other American spellings in CLSQL. 28 Jan 2009 Kevin Rosenberg * db-mysql/Makefile: Add directory for Fedora 11/12 on 64-bit platform (Thanks to Michael Pheasant) and remove a 32-bit directory 28 Jan 2009 Kevin Rosenberg * Version 4.3.1 * sql/utils.lisp: Ensure Lispworks 6 lock is created in sharing mode 20 Jan 2009 Nathan Bird * Version 4.3.0 * Rewrite tests to use datasets 07 Jan 2009 Kevin Rosenberg * sql/utils.lisp: Changes to support Lispworks 6 10 Dec 2009 Kevin Rosenberg * Version 4.2.0 * doc/ref-ooddl.lisp: Add needed CDATA escapes * doc/clsql.pdf, doc/html.tar.gz: Build new manuals with normalized view classes. 10 Dec 2009 Kevin Rosenberg Large patch from Thijs Oppermann to add support for normalized view classes. When having view class that inherit from others, CLSQL by default builds tab all the columns from the parent in the child. This patch is meant to normali so that a join is done on the primary keys of the concerned tables to get a set. 10 Dec 2009 Kevin Rosenberg * sql/time.lisp: Patch from Oleg Tihonov to SYNTAX-PARSE-ISO-8601 to properly parse fractions of seconds. 10 Dec 2009 Kevin Rosenberg * sql/time.lisp: Patch from Oleg Tihonov to roll function to properly use USEC argument. 21 Nov 2009 Kevin Rosenberg * Version 4.1.2 * Makefiles: On 64-bit Linux systems, try to build both 32 and 64-bit interface libraries. This requires the installation of multiarch build tools as well as 32-bit support libraries (libc, libz and libmysqlclient). 04 Sep 2009 Kevin Rosenberg * Version 4.1.1 * sql/fdml.lisp: Rework do-query to use supplied database parameter when passed a sql-object-query (thanks to JTK ) * sql/generic-postgresql.lisp: Allow optional connect parameters for postgresql databases (thanks to Stephen Compall) * doc/ref-{clsql,connect}.xml, sql/db-interfaces.lisp: Fix transposed letters (thanks to Stephen Compall) * db-mysql/Makefile: Add directory for MacPorts mysql5 port (thanks to Stephen Compall) * sql/database.lisp: Have database-type default be *default-database-type* (thanks to Desmond O. Chang) * sql/transactions.lisp: Improved handlining of nested transactions (thanks to Eli Naeher) * sql/time.lisp: Commit patch to fix parse-iso-8601-duration (thanks to Stephen Compall) * sql/database.lisp: Use :verbose nil for asdf:operate invocation (Thanks to Mackram Raydan) * sql/metaclasses.lisp: Rework initialize-instance for view-class-direct-slot-definition (thanks to Stephen Compall) 31 Aug 2009 Kevin Rosenberg * sql/db-interface.lisp: Fix spelling error (thanks to David Thompson) * clsql-mysql.asd/db-mysql/mysql-loader.lisp: Commit patch from Andreas Franke to honor windows drive letter when loading clsql_mysql C library. 31 Aug 2009 Kevin Rosenberg * Version 4.1.0 * db-mysql/mysql-{sql,api}.lisp,db-mysql/clsql_mysql.c: Latest version of mysqlclient once again changed the C structures from which the mysql backend reads data. Rather than adding yet another structure definition which is enabled by the client version as read by mysql-client-info.lisp, the mysql backend has been re-written to ignore in the internal C structures. Instead, C wrapper functions for slot access have been added to clsql_mysql.c and are used by mysql-sql.lisp to access the internals of C structures. This adds a bit of overhead, but completely separates the lisp code from trying to keep up with the continually changing internal C structure of mysql. All tests in the test suite executed correctly with this change. 31 Aug 2009 Kevin Rosenberg * Version 4.0.6 * sql/database.lisp: Fix syntax on process-lock (thanks to Stian Sletner) * db-mysql/mysql-sql.lisp: Allow use of database parameter in database-list function (thanks to Michael Pheasant) * sql/oodml.lisp: Allow NULL values for floating-point fields (thanks to Jan Rychter) 02 Jun 2009 Kevin Rosenberg * Version 4.0.5 * sql/database.lisp: Add process-lock for deleting database from a pool (thanks to Ralf Mattes). 25 Feb 2008 Kevin Rosenberg * Version 4.0.4 * sql/expressions.lisp: Remove stray form (thanks to Samuel Ward) 12 Dec 2007 Kevin Rosenberg * sql/expressions.lisp: Bind *in-subselect* when outputting selections (patch from unknown source). 11 Dec 2007 Kevin Rosenberg * Version 4.0.3 * sql/metaclasses.lisp: Unify base-table processing by extracting the correct code from initialize-instance :around into the helper function set-view-table-slot. Call that function also in reinitialize-instance :around replacing erroneous code discovered by Josh Feinstein. 17 Nov 2007 Kevin Rosenberg * BUGS: Add note about benefit of using configure file to create Makefiles (suggestion from Joe Corneli) 22 Oct 2007 Kevin Rosenberg * Version 4.0.2 * db-postgresql/postgresql-sql.lisp: Patch from Gabriele Favalessa based on Andrew Golding suggestion for more informative :error-id slot. 17 Sep 2007 Kevin Rosenberg * Version 4.0.1 * db-mysql/mysql-sql.lisp: Convert query to uffi cstring (thanks to Albert Krewinkel). * doc/Makefile, doc/html.xsl: Change output encoding from ISO-8859-1 to UTF-8 14 Sep 2007 Kevin Rosenberg * Version 4.0.0: Major version increase to warn of potential backwards incompatibility. * NEWS: Document potentional backward incompatible changes * db-mysql/mysql-sql.lisp: Changes session SQL mode to ANSI immediately after connecting. This may break compatibility with some applications who are using non-ANSI features with MySQL. This change is required to properly support view-classes using a string as their :base-table attribute. This allows users to specify the case of table names. This is feature is even more essential for MySQL itself since MySQL uses case-sensitive table names. Use connection-based database-create and database-destroy rather than trying to invoke command-line mysql utility. Remove automatic upcasing of strings from list-indices. * db-postgresql/postgresql-sql.lisp: Use connection-based database-create and database-destroy rather than trying to invoke command-line utilities. * db-postgresql-socket/postgresql-socket-sql.lisp: Use database-execute-command rather than execute-command for database-{create,destroy}. Connect to postgres database rather than template1 for those database creation/deletion. * sql/metaclasses.lisp: Store the string value of :base-table if a string is provided. Perform sql-escape at time of view-table name creation. * tests/test-init.lisp: Use "ej_join" as a string, rather than a symbol, since "ej_join" is specified as :base-table. Clear the expression output-cache in case the code for generating sql output has changed. * test/test-oodml.lisp: whitespace fix * sql/ooddl.lisp: Use quoted string for primary key constraint if table name is specified as a string. * sql/oodml.lisp: Don't convert a string view-table name to database's default case. * sql/expressions.lisp: Properly handle table and attribute identifiers when they are a string. Do not change case of symbols to match database default case. * sql/operations.lisp: Change multiword symbols to upper case. * sql/fddl.lisp: Quote base-table if a string to preserve case for drop-table and create-table. * tests/test-syntax.lisp: Add tests of low-level string attribute identifiers. 20 Jul 2007 Kevin Rosenberg * Version 3.8.6 * db-oracle/oracle-loader.lisp: Rework use of ORACLE_HOME directory (problem noted on clsql-devel by icardo Boccato Alves) * sql/pool.lisp: Remove incorrect keyword * sql/database.lisp: Rework WITH-DATABASE to not make the database the default database (reported by Saurabh Nanda and Chaitanya Gupta) * doc/ref-connect.lisp: Update the documentation to WITH-DATABASE to emphasis that make-default has a default value of nil. * sql/transaction.lisp: Adjust commit/rollback messages for Microsoft SQL Server. (patch from Nathan Bird) * sql/metaclasses.lisp: Use finalize-inheritance hack on SBCL because of trouble with def-view-class compilations (patch from Nathan Bird) 15 Jul 2007 Kevin Rosenberg * Version 3.8.5 * db-mysql/mysql-loader.lisp: Revert previous change since libmysql is not dynamically loaded on Windows 22 Jun 2007 Kevin Rosenberg * Version 3.8.4 * db-mysql/mysql-loader.lisp: Do not bother loading libmysqlclient since that library is dymically linked to clsql-mysql library. Thus, the mysql library will be automatically loaded. This has only been tested on Linux, thus far. 29 May 2007 Kevin Rosenberg * tests/test-fddl.lisp: Add :order-by for :fddl/big/1 as reported by Ricardo Boccato Alves 02 May 2007 Kevin Rosenberg * sql/database.lisp: Add ability of WITH-DATABASE to return multiple values (patch from Liam Healy) 25 Apr 2007 Kevin Rosenberg * Version 3.8.3 * doc/connect.xml: variable description fix by Liam Healy * db-sqlite3/sqlite3-api.lisp, uffi/clsql-uffi-loader.lisp: Apply patches from Marcus Pierce to reduce load-time warnings * sql/package.lisp: Export iso-timestring as requested by Kevin Blaisdell 23 Mar 2007 Kevin Rosenberg * Version 3.8.2 * sql/db-postgresql-socket-api.lisp: Change read-socket-sequence to disable wide characters for crypt salt sequence on SBCL, based on patch from Lars Nostdal. 26 Jan 2007 Kevin Rosenberg * Version 3.8.1 * sql/pool.lisp: Test pooled connection when popped from the pool to ensure the connection still works. Currently, implemented only for MySQL. 17 Jan 2007 Kevin Rosenberg * db-mysql/Makefile: Add potential mysql directories 31 Dec 2006 Kevin Rosenberg * sql/metaclasses.lisp: Remove usused saved-initargs * clsql.asd: Also check ~/.clsql-init.lisp at load-time (usually used to push search libraries) 30 Dec 2006 Kevin Rosenberg * Version 3.8.0: BACKWARD INCOMPATABLE CHANGE! * db-postgresql/postgresql-{api,loader,sql,package}.lisp: Apply patch from Edi Weitz to avoid conflict with new Lispworks 5 POSTGRESQL package name. CLSQL's new package will be PGSQL, however on non-Lispworks platforms, the nickname POSTGRESQL will still be available. Applications directly using low-level POSTGRESQL package are recommended to use the new PGSQL name. * db-oracle/oracle-{api,sql}.lisp, sql/{expressions,loop-extension}.lisp, Apply patch from Edi Weitz to reduce compiler warnings. 28 Dec 2006 Kevin Rosenberg * Version 3.7.9 * sql/expressions.lisp: Commit patch from Edi Weitz to use *default-database* for SQL-OUTPUT if no database is explicitly passed to function. * uffi/clsql-uffi-loader.lisp: Change load order to first try plain name/type before attempting user-specified paths (patch from Edi Weitz) * uffi/ptrbits.c: New file to return number of bits in an pointer * uffi/Makefile: use intbits to name .so file based on bit size. Build both 32-bit and 64-bit libraries on 64-bit platform. 30 Nov 2006 Kevin Rosenberg * Version 3.7.8 * db-sqlite3/sqlite3-sql.lisp: Commit patch from Edi Weitz fixing error display 16 Oct 2006 Kevin Rosenberg * Version 3.7.7 * db-postgresql/postgresql-sql.lisp: Remove uffi:convert-foreign-to-native wrapper since using cstring for PQresultErrorField 16 Oct 2006 Kevin Rosenberg * Version 3.7.6 * db-postgresql/postgresql-api.lisp: Fix UFFI return type for PQresultErrorField foreign function. 16 Oct 2006 Kevin Rosenberg * Version 3.7.5 * doc/intro.xml: Update supported platforms. * db-postgresql/postgresql-{package,api,sql}.lisp: Apply changes from Andew Golding to use a more-specific error code from PostgreSQL than the generic fatal error code of the result set. 03 Oct 2006 Kevin Rosenberg * sql/syntax.lisp: Commit patch from Marcus Pearce to improve readtable modifications 02 Oct 2006 Kevin Rosenberg * sql/syntax.lisp: Check that original reader syntax functions stored before trying to restore them. 20 Sep 2006 Kevin Rosenberg * sql/syntax.lisp: Apply patch from Marcus Pearce to correctly display sql reader syntax. 06 Sep 2006 Kevin Rosenberg * uffi/clsql-uffi-loader.lisp, db-mysql/mysql-loader.lisp: Change from using *features* to decide on 64-bit platform and check size of most-positive-fixnum instead. Needed to support clisp amd64. 03 Sep 2006 Kevin Rosenberg * Version 3.7.1 * sql/metaclasses.lisp: Rework slot type's to be more AMOP compatibile. Add warning for a metaclass condition that should not occur. * sql/time.lisp: Fixed symbol case inconsistency causing problem in AllegroCL's modern lisp. First sign of bug noted by Joel Reymond on clsql-devel. * clsql.asd: Make time.lisp depend on utils.lisp 31 Aug 2006 Kevin Rosenberg * db-mysql/mysql-loader.lisp: Apply patch from Marcus Pearce to push *library-file-dir* to CLSQL's library path. 30 Aug 2006 Kevin Rosenberg * Version 3.7.0: New platforms supported: SBCL/Win32, CLISP/Win32, CLISP/Cygwin, CLISP/Linux x86, CLISP/Linux amd64, OpenMCL amd64. CLISP support requires the latest development versions of CLISP, cffi, and cffi-uffi-compat packages. * Makefile.common: Add OS detection * uffi/make.sh, db-mysql/make.sh: Remove files * uffi/Makefile, db-mysql/Makefile: Add support for cygwin compilation. Refactor to remove need to make.sh shell scripts. * clsql.asd: Add support for loop extensions for clisp. Support clisp via cffi. * sql/loop-extension.lisp: Define loop-record-iteration-path in CLSQL-SYS package rather than CL-USER. Add support for ansi-loop on clisp. * sql/ansi-loop.lisp: New file to support iteration on clisp. * db-mysql/mysql-api.lisp: Remove old mysql C API functions that no longer exist in the mysql client library. * doc/ref-fdml.lisp: Correct default field-type. * sql/expressions.lisp: Use database-output-as-type if value exists for boolean output. Fixed bug with noted with MySQL 5.0.24 and boolean values. 28 Aug 2006 Kevin Rosenberg * Version 3.6.7 * sql/oodml.lisp: Remove high debugging level declaration 14 Aug 2006 Kevin Rosenberg * Version 3.6.6 * sql/generic-postgresql.lisp: Fix assumption that postgres user id is always 1. Fixes problem noted with PostgreSQL 8.1. 12 Aug 2006 Kevin Rosenberg * Version 3.6.5 * sql/generic-postgresql.lisp: Add slot for has-table-pg_roles to lazily cache if pg_roles tables exist. Selectively use SQL from Joel's previous patch if pg_roles table exists. Should now work with both postgresql 7.4 and 8.x. 12 Aug 2006 Kevin Rosenberg * Version 3.6.4 * clsql.asd: Add support for c:\etc\clsql-init.lisp as possible local initialization file * db-mysql/mysql-loader.lisp: Remove former method of using pathnames as name candidates. * db-odbc/odbc-api.lisp: Work-around Allegro/Windows FFI bug that generates incorrect integer return type * sql/generic-postgresql.lisp: Revert patch from Joel Reymont since it fails on versions of postgresql that lack the pg_role table 07 Jul 2006 Kevin Rosenberg * Version 3.6.3 * sql/transactions.lisp: Important typo fix from Alexey Antipov for database-start-transaction 04 Jul 2006 Kevin Rosenberg * Version 3.6.2 * db-postgresql/postgresql-sql.lisp: Apply patch from Vladimir Sekissov to close connection when failing to connect to database. * sql/generic-postgresql.lisp: Apply patch from Joel Reymont to avoid dropping system views. * sql/oodml.lisp: Apply patch from Joel Reymont to avoid listify a nil value [patch sponsored by Flektor] * clsql-uffi.asd, uffi/make.sh: Patch from Richard Kreuter for netbsd compilation 15 May 2006 Kevin Rosenberg * doc/ref-ooddl.xml: Add documentation for :db-reader and :db-writer slots for def-view-class macro [as reported missing by Thomas Fischbacher]. 09 May 2006 Kevin Rosenberg * db-postgresql-socket/postgresql-socket-api.lisp: Apply patch from Marko Kocic adding the socket creation function needed for CLISP. 08 May 2006 Kevin Rosenberg * Version: 3.6.0 (requires UFFI v1.5.11 or greater) * db-oracle/metaclasses.lisp: Patch from James Bielman for checking slot constraints. * db-oracle/oracle-{api,sql}.lisp: Avoid dead pointers on loading saved openmcl images (based on patch from James Bielman) 06 May 2006 Kevin Rosenberg * doc/ref-fdml.xml: Documentation patch from Marcus Pearce for limit keyword 03 May 2006 Kevin Rosenberg * Version 3.5.7 * sql/time.lisp: Apply patch from Aleksandar Bakic to extended duration parsing and unparsing to include year and month. * clsql-uffi.asd, uffi/clsql-uffi-loader.lisp: Apply patch from Nathan Bird improving library search on Windows platform. * doc/ref-fdml.xml, /doc/TODO, tests/test-fdml.lisp, tests/test-init.lisp: Apply patch from Marcus Pearce documenting and testing :limit and :offset for SELECT 20 Mar 2006 Kevin Rosenberg * Version 3.5.6 * clsql-postgresql-socket.asd, * db-postgresql-socket/postgresql-socket-package.lisp: Use the cl-md5 package on all platforms. Based on report from Alan Caulkins. 09 Mar 2006 Kevin Rosenberg * Version 3.5.5 * uffi/make.sh, db-mysql/make.sh: Add GNU uname 28 Feb 2006 Kevin Rosenberg * Version 3.5.4 * sql/metaclasses.lisp: Apply patch from Friedrich Dominicus to fix accessor for new versions of SBCL * db-oracle/oracle-sql.lisp: Apply patch from James Bielman to improving parsing of time. * db-db2/db2-constants.lisp: Change NULL_HANDLE has suggested by Harold Lee. * db-oracle/oracle-dbi.lisp: Add support for SQL BIT type as noted by Russ Tyndall. 16 Jan 2006 Kevin Rosenberg * Version 3.5.3 * sql/time.lisp: Commit patch from Aleksandar Bakic to properly handle destructive flag * db-postgresql-socket/postgresql-socket-api.lisp: Apply patch from Steven Harris for socket files with SBCL. * sql/pool.lisp: Apply patch from Vladimir Sekissov so that new connections added to the pool do not become the *default-database* * sql/connect.lisp: Optionally set *default-database* for pooled connection when make-default is generalized true. 23 Dec 2005 Kevin Rosenberg * Version 3.5.1 * sql/expressions.lisp: Ensure table names are properly escaped before comparing -- fixes bug reported by Asbjørn Bjørnstad on CLSQL-Devel. 02 Dec 2005 Kevin Rosenberg * sql/generic-postgresql.lisp: improved decoding of table attribute parameters [from Vladimir Sekissov] * sql/metaclasses.lisp: check that metaclass is standard-db-class or it's subclass to prevent adding standard-db-object to supers if somebody in the path has it already when metaclass inherited from standard-db-class. [from Vladimir Sekissov] 26 Nov 2005 Kevin Rosenberg * Version 3.5.0 * tests/test-init.lisp, tests/test-fddl.lisp, tests/test-fdml.lisp, * db-odbc/odbc-api.lisp, db-odbc/odbc-ff-interface.lisp, * db-odbc/odbc-package.lisp, db-odbc/odbc-constants.lisp * db-odbc/odbc-dbi.lisp, db-odbc/odbc-sql.lisp * sql/fddl.lisp, sql/generic-odbc.lisp, sql/db-interface.lisp * sql/transaction.lisp, sql/package.lisp, sql/time.lisp Commit patch from Dominic Robinson providing support for Microsoft SQL Server * doc/csql.lisp: Fix typo in slot name 24 Nov 2005 Kevin Rosenberg * Version 3.4.7 * sql/time.lisp: Commit patch from Aleksandar Bakic for correct handling of decode-time usec value * clsql-mysql.asd: Commit patch from Harald Hanche-Olsen to correct the name of the shared library file. 16 Nov 2005 Kevin Rosenberg * version 3.4.6 * sql/metaclasses.lisp: Avoid calling change-class on effective-slot-definitions on sbcl to conform to sbcl 0.9.6.38 changes. 15 Nov 2005 Kevin Rosenberg * Version 3.4.5 * sql/expressions.lisp: Patch from James Biel to add subselects 14 Nov 2005 Kevin Rosenberg * Version 3.4.4 [ Requires UFFI 1.5.7+] * db-oracle/oracle-{api,sql}.lisp: Patch from James Biel to fix lifetime of foreign strings for Oracle calls 13 Nov 2005 Kevin Rosenberg * Version 3.4.3 * db-oracle/oracle-{api,sql}.lisp: Patch from James Biel to improve performance 12 Nov 2005 Kevin Rosenberg * Version 3.4.2 * clsql-uffi.asd: Patch from James Biel improving loading * db-oracle/oracle-{api,sql}.lisp: Patch from James Biel to support 64-bit lisps 12 Nov 2005 Kevin Rosenberg * Version 3.4.1 * sql/expressions.lisp: Escape numbers to SQL strings at expression level. 11 Nov 2005 Kevin Rosenberg * Version 3.4: Add MySQL 5 support * db-mysql/mysql-client-info.lisp: Recognize MySQL 5 * db-mysql/mysql-sql.lisp: Add support for views in MySQL 5 * doc/mysql-macosx-notes.txt: New document from Martin Brooks 7 Nov 2005 Kevin Rosenberg * src/time.lisp: Apply patch from Aleksandar Bakic for ROLL function. * BUGS: Added report for update-object-joins by Aleksandar Bakic 4 Nov 2005 Kevin Rosenberg * Version 3.3.4 [UFFI >= 1.5.5 needed] * db-odbc/odbc-api.lisp: Apply patch from Yaroslav Kavenchuk to add missing #\' character. * clsql.asd: Add support for CLSQLINIT environmental variable, based on patch from Yaroslav Kavenchcuk. New version of UFFI required. 30 Oct 2005 Kevin Rosenberg * Version 3.3.3 * sql/oodml.lisp: Apply patch from Drew Crampsie to fix update-objects-joins when using the :target-slot attribute 26 Oct 2005 Kevin Rosenberg * Version 3.3.2 * sql/expressions.lisp: Avoid parenthesis on multiple group-by fields as noted by Harald Hanche-Olsen. * tests/test-syntax.lisp: Add test for multiple field group-by 25 Oct 2005 Kevin Rosenberg * Version 3.3.1 * sql/time.lisp: Commit patch from Alan Shields to display escape string on wall-time display only when *print-escape* is true. 11 Oct 2005 Kevin Rosenberg * sql/metaclasses.lisp: Commit patch from Will to properly set db-reader slot in effective-slot-definition * sql/expressions.lisp: Commit patch from Alan Shields adding make-load-form for sql-relational-exp * sql/generic-postgresql.lisp: Commit patch from Aleksandar Bakic adding support for new NUMBER type 17 Sep 2005 Kevin Rosenberg * Version 3.3.0 * sql/time.lisp: Apply patch from Alan Shields adding DATE type. * doc/ref-ooddl.xml: Documentation of new type * notes/add-type-hints.txt: New file from Alan Shields * sql/fddl.lisp: Add owner keyword to drop-table as suggested by Francis Leboutte * db-postgresql-socket/postgresql-socket-sql.lisp: Fix database-probe as noted by Francis Leboutte. Similar fix applied to db-mysql and db-postgresql. * sql/expressions.lisp: Allow string table names for output as contributed by Francis Leboutte. * examples/clsql-tutorial.lisp: Support :postgresql-socket as noted by Francis Leboutte 08 Sep 2005 Kevin Rosenberg * Version 3.2.4 * doc/into.xml: Change download from ftp to http protocol 08 Sep 2005 Kevin Rosenberg * Version 3.2.3 * db-oracle/oracle-sql.lisp: Correction for v3.2.2 changes by Edi Weitz 08 Sep 2005 Kevin Rosenberg * Version 3.2.2 * db-oracle/oracle-sql.lisp: Add check for zero increment as suggested by Edi Weitz. Add missing database-sequence-last function as noted and tested by Edi Weitz. Ensure that UFFI buffer is freed in handle-oci-error. Add unwind-protect to sql-stmt-exec. Free UFFI stmthp object when query cursor is freed with OCI. 22 Aug 2005 Kevin Rosenberg * uffi/clsql-uffi-loader.lisp: Commit patch from astor@pvv.ntnu.no to display search path when error occurs loading foreign library. 05 Jul 2005 Kevin Rosenberg * Version 3.2.1 * doc/appendix.xml: Incorporate Edi Weitz's notes into documentation with changes to support case-sensitive lisp implementations. Add paragraph on using /etc/clsql-init.lisp site initialization file. * clsql.asd: Load file /etc/clsql-init.lisp, if it exists, after package is loaded to set site-specific configuration 2005-06-24 Edi Weitz * sql/db-interface.lisp: Added new special variable *FOREIGN-LIBRARY-SEARCH-PATHS* and function PUSH-LIBRARY-PATH to manipulate it. * sql/package.lisp: Export these. * uffi/clsql-uffi-loader.lisp: Used new variable; changed order of libs. * db-mysql/mysql-loader.lisp: Changed order of libs. 09 Jun 2005 Kevin Rosenberg * Version 3.2.0: REQUIRES UFFI VERSION 1.4.38 OR HIGHER * clsql-mysql.asd: Renamed clsql/mysql interface library from mysql to clsql_mysql * clsql-uffi.asd: Renamed clsql/uffi interface library from mysql to clsql_uffi * uffi/clsql_uffi.c: Renamed from uffi.c * db-mysql/clsql_mysql.c: Renamed from mysql.c * db-mysql/Makefile, db-mysql/Makefile.msvc, db-mysql/mysql-loader.lisp: Rename shared library * uffi/Makefile, uffi/Makefile.msvc, uffi/uffi-loader.lisp: Rename shared library * db-*/*-loader.lisp: Commit big patch from Edi Weitz to remove absolute pathnames when searching for foreign libraries. foreign library loading. 07 Jun 2005 Kevin Rosenberg * Version 3.1.16 * db-mysql/mysql-api.lisp: Commit patch from Espen Wiborn to support UTF-8 on sbcl unicode. 18 May 2005 Kevin Rosenberg * Version 3.1.15 * sql/time.lisp: Fix bug in roll that caused failure in test suite 17 May 2005 Kevin Rosenberg * Version 3.1.14 * sql/oodml.lisp: Properly handle when db-writer is NIL 11 May 2005 Kevin Rosenberg * sql/expressions.lisp: Avoid using simple-string declaration when a non-simple string may be encountered. [issue noted by will@cesmail.net] Add a simple-string declaration for a local string generated. 06 May 2005 Kevin Rosenberg * sql/oodml.lisp: Change db-writer and db-reader processing to accept a symbol as well as function to serve as a function designator [issue noted by will@cesmail.net] 05 May 2005 Kevin Rosenberg * Version 3.1.13 * sql/time.lisp: Fix error in submitted patch which caused error in timestrings with 19 or less characters. 27 Apr 2005 Kevin Rosenberg * Version 3.1.12 * db-postgresql-socket/postgresql-api.lisp: Commit patch from Tim Howe to fix read-socket-sequence on non-sb-unicode sbcl. 26 Apr 2005 Kevin Rosenberg * Version 3.1.12 * sql/time.lisp: Commit patch from Daniel Lowe which adds support for fractional seconds which is required by PostgreSQL * db-postgresql/postgresql-loader.lisp: Add library path for Windows 25 Apr 2005 Kevin Rosenberg * sql/csql.lisp: Update URL for "SQL for Web Dummies" [Sean Champ] 24 Apr 2005 Kevin Rosenberg * Version 3.1.11 * sql/syntax: Commit patch from Alan Shields to supress reader macros when *read-supress* is T. 13 Apr 2005 Kevin Rosenberg * Version 3.1.10 * db-postgresql-socket/postgresql-socket-api.lisp: Commit patch from Janis Dzerins to support unicode on SBCL * sql/syntax: Commit patch from Alan Shields to improve reporting of invalid syntax statements. 06 Apr 2005 Kevin Rosenberg * Version 3.1.9 * db-mysql/mysql-sql.lisp: Add port to connection specification based on patch from Dave Watson * doc/appendix.xml: Document MySQL port parameter to connection spec 03 Apr 2005 Kevin Rosenberg * Version 3.1.8 * sql/time.lisp: Patch from Keith James for parsing ISO-8601 timestamps 18 Mar 2005 Kevin Rosenberg * sql/oodml.lisp: Add missing database argument [Patch from Alan Caulkins] 03 Mar 2005 Kevin Rosenberg * sql/oodml.lisp: Improve database priority in update-records-from-instance [Patch from Walter C. Pelissero] 17 Feb 2005 Kevin Rosenberg * Version 3.1.7 * sql/package.lisp: Export database-reconnect from clsql-sys 08 Feb 2005 Kevin Rosenberg * sql/oodml.lisp: Use explicit database in fault-join-target-slot [Patch from Walter Pelissero] 29 Jan 2005 Kevin Rosenberg * db-postgresql/postgresql-loader.lisp: Add additional directories to Fink on darwin [patch from Cyrus Harmon]. 29 Jan 2005 Kevin Rosenberg * Version 3.1.6 * sql/oodml.lisp: Clear view instance cache when delete-instance-records is invoked [suggested by Alan Shutko]. * uffi/clsql-uffi-loader.lisp: Improvements for loading with SBCL X86-64 * sql/metaclasses.lisp: Don't change case of a :base-table string supplied to def-view-class [fix suggested by Fred Gilham]. 25 Jan 2005 Kevin Rosenberg * tests/*.lisp: Change Vladamir to Vladimir per Cyrus Harmon's suggestion. * sql/utils.lisp: Fix unnecessary consing noted by Fred Gilham. * doc/*.xml: Fix spelling of Vladimir 24 Jan 2005 Kevin Rosenberg * doc/bookinfo.xml, doc/csql.xml, doc/intro.xml: Update links now that LispWorks is an independant company [noted by Martin Thornquist] 22 Jan 2005 Kevin Rosenberg * db-sqlite/sqlite-sql.lisp, db-sqlite3/sqlite3-sql.lisp: Better support for 64 bit environments 05 Jan 2005 Kevin Rosenberg * Version 3.1.5 * sql/metaclass.lisp: Make t the default value of :set [noted by Cyrus Harmon] 28 Dec 2004 Kevin Rosenberg * Version 3.1.4 * uffi/clsql-uffi.lisp: Add support for unsigned integers * db-mysql/mysql-sql.lisp: Add support for detecting/marking unsigned integers. Apply patch from Yannick Gingras to implement database-sequence-last. 26 Dec 2004 Kevin Rosenberg * doc/ref-fdml.lisp: Fix variable tag name to varname [noted by Eduardo Munoz] * db-mysql/mysql-loader.lisp: Handle library paths for 64-bit systems 06 Dec 2004 Kevin Rosenberg * Version 3.1.2 * sql/ooddl.lisp: Accept patch from Klaus Harbo for update-object-joins. * sql/metaclass.lisp: Remove unnecssary (and runtime error causing) change-class invocation when running on CLISP. * db-mysql/mysql-api.lisp: Commit patch from Paul Werkowski to fix structure name. * sql/database.lisp: More specific error message with trying to use a database value of NIL. * sql/expressions.lisp: Accept a string for the table name in (sql-output sql-delete database) [suggested by Ed Symanzik]. 11 Nov 2004 Kevin Rosenberg * Version 3.1.1 * sql/generic-postgresql.lisp: Commit patch from Chris Capel to ignore columns which have been dropped. * clsql-postgresql-socket.asd, db-postgresql-socket/postgresql-socket-package.lisp: Use sb-md5 package on SBCL, recommended by Chris Capel 09 Nov 2004 Kevin Rosenberg * Version 3.1.0 released: New SQLite3 backend by Aurelio Bignoli * doc/appendix.xml: Document SQLITE3 backend, patch by Aurelio Bignoli * sql/operations.lisp: Add lower and upper SQL functions [Daniel Lowe]. 08 Nov 2004 Kevin Rosenberg * sql/expressions.lisp: Fix slot name [thanks to Daniel Lowe] 31 Oct 2004 Kevin Rosenberg * clsql-sqlite3, db-sqlite3/*: NEW BACKEND contributed by Aurelio Bignoli 23 Oct 2004 Kevin Rosenberg * sql/oodml.lisp: Commit patch from Walter Pelis to use an object's database for a select on its slot. 20 Oct 2004 Kevin Rosenberg * uffi/uffi.c, uffi/clsql-uffi.lisp: Commit patch from Aurelio Bignoli to fix negative 64-bit integers 07 Oct 2004 Kevin Rosenberg * db-mysql/mysql.c: Fix parameters in bind_param call 07 Oct 2004 Kevin Rosenberg * uffi/clsql-uffi.lisp: Add support for :blob result-type * db-mysql/mysql-sql.lisp: Add support for :blob result-type 04 Oct 2004 Kevin Rosenberg * db-mysql/mysql-sql.lisp, db-db2/db2-sql.lisp: Add missing quotes for types in code that is still in development (thanks to Joerg Hoehle) 03 Oct 2004 Kevin Rosenberg * Version 3.0.8 released * db-sqlite/sqlite-*.lisp: Apply patch from Aurelio Bignoli with improvements 01 Oct 2004 Kevin Rosenberg * multiple: Apply patch from Joerg Hoehle with multiple improvements. 01 Oct 2004 Kevin Rosenberg * Version 3.0.7 released * sql/oodml.lisp, sql/package.lisp, db-mysql/mysql-objects.lisp: Add support for mediumint. * sql/metaclass.lisp: Rework CLISP MOP handling * sql/ooddl.lisp: Work-around to have CLISP finalize standard-db-class 28 Sep 2004 Kevin Rosenberg * sql/metaclass.lisp: Support CLISP's attribute name for the type field in direct class slots 27 Sep 2004 Kevin Rosenberg * Version 3.0.6 released * BUGS: New file. Document suspected SIGPIPE interaction between SBCL and libpq used in postgresql backend. * doc/ref-fdml.lisp: Document the :caching and :refresh keywords of the SELECT function. * doc/ref-ooddml.lisp: Document the new *default-caching* variable. * sql/package.lisp: Export *default-caching* * sql/oodml.lisp: Use *default-caching* to control default caching behavior. 21 Sep 2004 Kevin Rosenberg * Version 3.0.5 release * doc/appendix.xml: Add note about loading Oracle8 version * db-oracle/oracle-loader.lisp: Support Oracle8 based on data from David Young. 10 Sep 2004 Kevin Rosenberg * doc/Makefile, doc/catalog-darwin.xml: Apply patch from Cyrus Harmon for building docs on Mac OS X * sql/package.lisp: Add new (pre-release) clisp MOP package 09 Sep 2004 Kevin Rosenberg * Version 3.0.4 Release * multiple: Remove superfluous quotes in UFFI def-type and def-foreign-type forms. 07 Sep 2004 Kevin Rosenberg * Version 3.0.3 Release * db-postgresql-socket/postgresql-socket-api.lisp: Commit patch from Tagore Smith to call force-output after sending authentication * db-odbc/odbc-api.lisp: Move ODBC v3 conversons * db-odbc/odbc-sql.lisp: Load mysql or postgresql package when connecting to a database of that type so that functions that indicate capabilities of database are available. 02 Sep 2004 Kevin Rosenberg * db-odbc/odbc-api.lisp: More conversions to ODBC v3 02 Sep 2004 Kevin Rosenberg * Version 3.0.2 Release * TODO: Add note about ODBC on Windows * db-odbc/odbc-loader.lisp: Add /winnt/system32/ to search directories * db-odbc/odbc-ff-interface.lisp: Change the return type of SQLSetEnvAttr to :short 02 Sep 2004 Marcus Pearce * examples/clsql-tutorial.lisp: added missing initarg for the COMPANYID slot of the employee View Class definition [reported by Franz Deuzer]. 01 Sep 2004 Kevin Rosenberg * Version 3.0.1 Release * tests/test-init.lisp: Add second join class to employee-address to test a class with two join slots. * sql/oodml.lisp: Fix find-all function for a class with multiple join slots * TODO: Remove need to test/fix multiple join classes 27 Aug 2004 Kevin Rosenberg * db-mysql/Makefile, db-mysql/mysql-loader.lisp: accept patch from Jon Buffington for file locations on Darwin. 17 Aug 2004 Kevin Rosenberg * sql/db-interface.lisp: Improve messages when functions are passed a database object, but the method is not specialized for that database type. * sql/metaclasses.lisp: Fix inline declaration (reported by Cyrus Harmon) 14 Aug 2004 Kevin Rosenberg * TODO: Add bug report about SQL generation with a table containing two join slots. * sql/oodml.lisp: Add optional size to VARCHAR type 3 Aug 2004 Kevin Rosenberg * Version 3.0.0 Release * sql/expressions.lisp: Change declaration that caused error on openmcl * db-aodbc/aodbc-sql.lisp: Fix storage location of odbc connection. Specialize database-query since dbi's :types keyword is different than generic-odbc's :result-types keyword * sql/db-interface.lisp: Add warnings for methods not specialized by a db backends * tests/test-fddl.lisp: Fix case of symbols to support case-sensitive Allegro * db-oracle/oracle-sql.lisp: Rework errbuf in handle-oci-error * tests/test-init.lisp: Note that odbc driver for postgresql doesn't properly handle table ownership * LATEST-TEST-RESULTS: update with version 3.0.0 1 Aug 2004 Marcus Pearce * sql/expressions.lisp: conditionalise escaping of backslash in generated SQL strings on backend. * tests/test-fdml.lisp: test for escaping of backslash. * sql/oodml.lisp: minor tidying in FIND-ALL. 26 Jul 2004 Kevin Rosenberg * NEWS: Initial 3.0 announcement draft * README: Expand acknowledgements of incorporated projects * CONTRIBUTORS: Further document Marcus Pearce contributions 23 Jul 2004 Marcus Pearce * sql/oodml.lisp: add DATABASE-OUTPUT-SQL-AS-TYPE method specialisation to print floats with the exponent markers removed. * tests/test-oodml.lisp: add tests for updating records with floats. 22 Jul 2004 Marcus Pearce * db-oracle/oracle-sql.lisp: enable :OWNER :ALL in DATABASE-LIST-* for CommonSQL compatibility. * tests/test-init.lisp: skip test :FDDL/TABLE/6 on Oracle since this column constraint syntax is not supported. * tests/test-fddl.lisp: change column indexed in test :FDDL/INDEXES/2 from EMPLID to LAST_NAME since Oracle complains that EMPLID is already indexed. 17 Jul 2004 Marcus Pearce * doc/ref-fdml.xml: document CACHE-TABLE-QUERIES. * tests/test-fdml.xml: add test for CACHE-TABLE-QUERIES. * doc/ref-ooddl.xml: minor changes to syntax and examples entries for uniformity. * doc/ref-oodml.xml: add examples for OODML. * sql/oodml.lisp: ensure SELECT passes on its REFRESH argument to FIND-ALL. * sql/metaclasses.lisp: update docstrings. * tests/test-init.lisp: change :db-constraints for emplid to (:not-null :unique) as a temporary test for multiple column constraints in DEF-VIEW-CLASS. * tests/test-oodml.lisp: add tests for *DB-AUTO-SYNC* and return type of (SETF SLOT-VALUE-USING-CLASS). * TODO, doc/TODO: remove items done. * README: fix typo. 16 Jul 2004 Marcus Pearce * sql/oodml.lisp: on Lispworks, use weak valued hash tables for object caching. * sql/expressions.lisp: Fix SQL generation for the symbol NIL. 16 Jul 2004 Marcus Pearce * sql/expressions.lisp: reactivate caching of generated SQL strings. Move methods for DATABASE-OUTPUT-SQL, OUTPUT-SQL and SQL-HASH-KEY here from sql/fdml.lisp. Rationalise behaviour of SQL-OUTPUT, OUTPUT-SQL and DATABASE-OUTPUT-SQL. * sql/fdml.lisp: remove disabled method ADD-STORAGE-CLASS. Move methods for DATABASE-OUTPUT-SQL, OUTPUT-SQL and SQL-HASH-KEY to sql/expressions.lisp. * sql/ooddl.lisp: replace call to DATABASE-OUTPUT-SQL in DATABASE-PKEY-CONSTRAINT with call to SQL-OUTPUT. * sql/generics.lisp: add docstrings. 15 Jul 2004 Kevin Rosenberg * Version 2.11.16 * db-oracle/oracle-sql.lisp: Remove OpenMCL specific code in favor of fixing UFFI with James Bielman's patch 14 Jul 2004 Kevin Rosenberg * Version 2.11.15 * db-oracle/oracle-sql.lisp: Apply patch for OpenMCL/OSX from James Bielman 14 Jul 2004 Marcus Pearce * README, INSTALL: update URLs. Minor updates to descriptions. * tests/README: remove stuff about editing contexts. 12 Jul 2004 Kevin Rosenberg * db-oracle/oracle-objects.lisp: Change *default-varchar-length* to *default-string-length* 12 Jul 2004 Marcus Pearce * tests/test-syntax.lisp, tests/test-fdml.lisp: add tests for escaping of single quotes. * tests/test-fddl.lisp: add tests for column and table constraints in CREATE-TABLE. Add test for OWNER keyword parameter to LIST-TABLES (assuming same underlying machinery in other FDDL functions). * tests/test-init.lisp: restrict above test to postgresql and oracle. 12 Jul 2004 Kevin Rosenberg * db-sqlite/sqlite-sql.lisp: Fix condition as reported by Aurelio Bignoli. 11 Jul 2004 Kevin Rosenberg * sql/oodml.lisp, sql/package.lisp, doc/ref-ooddl.lisp, db-mysql/mysql-objects.lisp: Add tinyint type 10 Jul 2004 Kevin Rosenberg * Version 2.11.14 * doc/*.xml: documentation additionals and fixes so that docbook passes xmllint. 9 Jul 2004 Kevin Rosenberg * Version 2.11.13 * sql/fdml.lisp: Apply patch from Kim Minh Kaplan to change escaping of single quotes. Mild optimizations for escaped string output. * doc/ref-ooddl.lisp: documentation additions * doc/ref-oodml.lisp: Add purpose to functions * TODO: Add need to test single quote escaping 7 Jul 2004 Kevin Rosenberg * doc/ref-ooddl.xml, doc-ref-oodml.xml: documentation additions * sql/ooddl.lisp: Added SMALLINT type * sql/generic-postgresql.lisp: Added INT2 as SMALLINT type * db-mysql/mysql-objects.lisp: Added SMALLINT type * sql/package.lisp: Export SMALLINT * sql/expressions.lisp: Add MYSQL's UNSIGNED and ZEROFILL as db-constraints 6 Jul 2004 Marcus Pearce * sql/expressions.lisp: add AUTO-INCREMENT and UNIQUE to the recognised column constraints for CREATE-TABLE and the :DB-CONSTRAINTS View Class slot option. * sql/ooddl.lisp: fix bug preventing the :DB-CONSTRAINTS View Class slot option accepting a list of constraints [reported by Travis Cross]. * doc/ref-fddl.xml: add some examples of specifying column and table constraints to the documentation for CREATE-TABLE. * TODO: add note about adding tests for table/column constraints. Add optimisation note about using cached attribute types in insert/update operations. 3 Jul 2004 Marcus Pearce * doc/appendix.xml: add notes about idiosyncrasies/unsupported features and so on the documentation for each backend. * doc/TODO: remove items done. * doc/ref-transaction.xml: add note in introduction about autocommit mode as a difference from CommonSQL. * doc/ref-syntax.xml: add notes about SQL syntax state functions being macros in CLSQL. Add note about SQL operators which are CLSQL extensions. 2 Jul 2004 Marcus Pearce * Version 2.11.12 released * doc/ref-recording.xml: document SQL I/O recording. * doc/ref-prepared.xml: new file for documenting prepared statements. * doc/clsql.xml: comment out include for large object and CLSQL-SYS documentation. * doc/ref-conditions.xml: complete documentation of condition system. * doc/global-index.xml: add symbols from condition system and remove those from LOB and prepared statement APIs. * doc/ref-fdml.xml: complete documentation of FDML. * doc/glossary.xml: add View Class. * doc/TODO: remove items done. * sql/conditions.lisp: make SQL-CONDITION a parent of SQL-ERROR. * sql/package.lisp: remove FOR-EACH-ROW from exports list. Export additional slot accessors for condition classes. 1 Jul 2004 Kevin Rosenberg * doc/ref-ooddl.lisp: Add documentation * doc/ooddl.lisp: Move *DEFAULT-VARCHAR-LENGTH* from oodml.lisp and rename to *DEFAULT-STRING-LENGTH*. Add docstring. * doc/oodml.lisp: Rename references to new name of *DEFAULT-STRING-LENGTH* 1 Jul 2004 Marcus Pearce * doc/ref-transaction.xml: document transaction handling. * sql/transaction.lisp: ensure that COMMIT, ROLLBACK and START-TRANSACTION return NIL as per the CommonSQL spec. Modify ADD-TRANSACTION-{ROLLBACK|COMMIT}-HOOK such that a database is passed as a keyword argument defaulting to *DEFAULT-DATABASE*. Added docstrings. 30 Jun 2004 Marcus Pearce * doc/ref-fdml.xml: document the FDML. * doc/ref-fddl.xml: move documentation for TRUNCATE-DATABASE here. * sql/ooddl.lisp: moved *default-varchar-length* to here from oodml.lisp and renamed to *default-string-length* 23 Jun 2004 Kevin Rosenberg * sql/oodml.lisp: Add keyword :transactions to def-view-from-class to allow specifying transactionless table creation * doc/ref-oodml.lisp: Add new keyword to signature of DEF-VIEW-FROM-CLASS 18 Jun 2004 Marcus Pearce * Version 2.11.11 * sql/expressions.lisp: when removing duplicate table identifiers in the FROM clause of a query, check both table name and alias are equivalent. * sql/fdml.lisp: remove DESCRIBE-TABLE. * sql/db-interface.lisp: remove generics DESCRIBE-TABLE and DATABASE-DESCRIBE-TABLE. * sql/package.lisp: remove DESCRIBE-TABLE, DATABASE-DESCRIBE-TABLE and LIST-TABLE-INDEXES. * sql/generic-postgresql.lisp: add reader conditional #+nil for DATABASE-DESCRIBE-TABLE and comment about its uses for re-implementing LIST-ATTRIBUTE-TYPES with a single SQL query returning type info for all attributes. Fix DATABASE-SEQUENCE-LAST. * sql/fddl.lisp: remove LIST-TABLE-INDEXES and redefine LIST-INDEXES with additional keyword parameter :ON. * tests/test-fddl.lisp: replace LIST-TABLE-INDEXES in :fddl/index/3 with LIST-INDEXES (with :ON parameter). * doc/global-index.xml: remove DESCRIBE-TABLE and LIST-TABLE-INDEXES. * doc/ref-connect.xml: minor tidying. * doc/ref-fddl.xml: document the FDDL. * doc/TODO: removed items done. Moved note about transaction handling from TODO to here. * TODO: move note about transaction handling to doc/TODO. Added optimization note about LIST-ATTRIBUTE-TYPES and LIST-INDEXES. 13 Jun 2004 Marcus Pearce * Version 2.11.10 * sql/syntax.lisp: updated docstrings. * sql/package.lisp: exported DATABASE-NAME-FROM-SPEC from CLSQL package. * sql/database.lisp: add docstrings for CREATE-DATABASE, DESTROY-DATABASE, TRUNCATE-DATABASE and LIST-DATABASES. Replace CLSQL-GENERIC-ERROR signalled in RECONNECT with SQL-CONNECTION-ERROR. * doc/ref-syntax.xml, doc/global-index.xml: minor tidying. * doc/ref-connect.xml: document connection/initialisation. * doc/ref-fdml.xml: move TRUNCATE-DATABASE reference entry here. * doc/TODO: remove items done. * Makefile: add db-oracle to to SUBDIRS. 13 Jun 2004 Kevin Rosenberg * sql/oodml.lisp: Add new serialization functions: WRITE-INSTANCE-TO-STREAM and READ-INSTANCE-FROM-STREAM * sql/expressions.lisp: Avoid duplicate FROM names when selecting from a table that has more than one primary index. * sql/conditions.lisp: Fix printing of closed-database error 13 Jun 2004 Kevin Rosenberg * Version 2.11.9 * sql/conditions.lisp: Set initial slot value for message in SQL-WARNING * sql/transactions.lisp: Correctly set slots of SQL-WARNING 12 Jun 2004 Marcus Pearce * sql/package.lisp: export DATABASE-TYPE from CLSQL and subclasses of SQL-EXPRESSION from CLSQL-SYS. * sql/syntax.lisp: make error signalled in SQL-OPERATION an SQL-USER-ERROR. Make SQL-OPERATOR return just one value. * doc/Makefile: added Mandrake linux. * doc/catalog-redhat.xml, doc/catalog-mandrake.xml: new files. * doc/appendix.xml: fixed little typo (adsf). * doc/glossary.xml: removed closed-database and note about sql-expression, added some entries. * doc/ref-syntax.xml: documented the symbolic SQL syntax. 10 Jun 2004 Kevin Rosenberg * Version 2.11.8 * db-mysql/mysql-loader.lisp: Remove load of unnecessary zlib library * multiple: Add generalized-boolean type as requested by Edi Weitz * TODO: Added need for test of generalized-boolean 9 Jun 2004 Kevin Rosenberg * Version 2.11.7 released * uffi/clsql-uffi-loader.lisp: Apply patch from Edi Weitz for loading with clc-register-user-package. Remove personal directory from path lisp. * db-mysql/mysql-loader.lisp: Similar changes 8 Jun 2004 Kevin Rosenberg * Version 2.11.6 released * sql/oodml.lisp: Commit patch from Edi Weitz to fix symbol writing/reading * TODO: Add need for symbol slot test 7 Jun 2004 Marcus Pearce * sql/package.lisp: remove duplicate export of *CACHE-TABLE-QUERIES-DEFAULT*. * doc/ref-*.xml, doc/global-index.xml: new files documenting the CommonSQL compatible api. * tests/test-fdml.lisp: modified the test :fdml/transaction/3 to reflect changes in return values of WITH-TRANSACTION. 04 Jun 2004 Kevin Rosenberg * tests/README: Fix filename [reported by Bill Clementson] * sql/transactions.lisp: Apply return value patch from Edi Weitz for WITH-TRANSACTION * tests/README: Remove ptester package requirement (as noted by Bill Clementson) 03 Jun 2004 Kevin Rosenberg * Version 2.11.5 released * examples/clsql-tutorial.lisp: Remove obsolete :nulls-ok attribute, Select connection-spec based on connection type. Bugs reported by Bill Clementson. * uffi/uffi.dll, uffi/uffi.lib: Recompile with Visual Studio 2003 * db-mysql/mysql-loader.lisp: Update check for zlibwapi library name on Windows, add \bin\ directory to search path 31 May 2004 Marcus Pearce * db-odbc/odbc-sql.lisp: DB-TYPE replaced with DATABASE-TYPE in DATABASE-CONNECT. * sql/operations.lisp: substr now generates SUBSTR for use on Oracle; added a new operator SUBSTRING for use elsewhere. minus now generates MINUS for use on Oracle. Nvl signals an error if not called with exactly 2 arguments. Add concat function for use instead of the || operator on MySQL and Oracle. * sql/syntax.lisp: changed internal symbol for the || operator to CONCAT-OP. * sql/expressions.lisp: removed redundant and unused functions GENERATE-SQL (cf. SQL-OUTPUT) and DATABASE-CONSTRAINT-DESCRIPTION (cf. MAKE-CONSTRAINTS-DESCRIPTION). * sql/generics.lisp: removed generic function for DATABASE-CONSTRAINT-DESCRIPTION (see above). * tests/test-syntax.lisp: modified/added tests according to changes in sql/operations.lisp. * tests/test-fdml.lisp: changed SUBSTR to SUBSTRING in test :fdml/select/21. * sql/package.lisp: added the operators SQL-SUBSTRING, SQL-CONCAT-OP and SQL-USERENV to the shared exports list. Removed ROLLBACK-TRANSACTION, COMMIT-TRANSACTION, DATABASE-START-TRANSACTION, DATABASE-ABORT-TRANSACTION, DATABASE-COMMIT-TRANSACTION, TRANSACTION-LEVEL, TRANSACTION, RECORD-SQL-COMMAND and RECORD-SQL-RESULT from shared exports list. 30 May 2004 Kevin Rosenberg * db-postgresql/postgresl-sql.lisp: Avoid computing result-types lisp when nil result-types. Return only one value when field-types nil. * db-mysql/mysql-sql.lisp: Simple queries now working with prepared statements. 30 May 2004 Kevin Rosenberg * Version 2.11.4: MySQL 4.1 now passes all tests * sql/package.lisp: Add API for prepared statments. * sql/fdml.lisp: Change implicit flatp processing for string map-query for greater CommonSQL conformance. Add high-high API for prepared statements. * tests/test-basic.lisp: Add test for map-query and single argument. * sql/transactions.lisp: Change name/semantics of autocommit to set-autocommit. * sql/generic-postgresql.lisp: Add support for prepared statements. * tests/test-internal.lisp: New file * sql/odbc-api.lisp: Update to using ODBC V3 protocol * clsql-mysql.asd, clsql-uffi.asd: Remove check and Common Lisp Controller invocation. * db-mysql/mysql-api.lisp: Add support for MySQL 4.1 field structure * sql/expressions.lisp: Avoid emitting double parenthesis when a function contains a subselect. 27 May 2004 Kevin Rosenberg * Version 2.11.3 * sql/ooddl.lisp: Commit patch from Edi Weitz fixing return type (setf slot-value-using-class) * TODO: add not that need a test case for the above fix * db-sqlite: Remove clisp support since clisp can not run CLSQL with its MOP usage * db-oracle/oracle-sql.lisp: By default, use OCIEnvCreate as introduced in Oracle8. Leave older code selectable by a reader macro for Oracle7 and prior. Avoid use of OCIServerAttach since CLSQL uses OCILogon and does not the more complex session management. 26 May 2004 Kevin Rosenberg * sql/oodml.lisp: Commit universal-time typo patch from Edi Weitz * test/test-init.lisp: Add universal-time slot to person. * test/test-fddl.lisp: Add tests of universal-time slot * test/test-ooddl.lisp: Test universal-time slot in an object * TODO: Remove need for universal-time test * debian/rules, debian/control: Add cl-sql-oracle binary package * doc/appendix.xml: Add Oracle backend information * db-oracle/oracle-objects.lisp: Add database-get-type-specifier for universal-time. Convert BIGINT CLSQL type to CHAR SQL type * db-mysql/mysql-sql.lisp: Fix condition name to sql-connection-error * doc/ref-clsql.xml: Renamed from ref_clsql.xml. Change the documentation for map-query to reflect changed in arguments to be CommonSQL compatible. Updated old clsql conditions to new CommonSQL compatible conditions. 25 May 2004 Kevin Rosenberg * sql/oodml.lisp: (string n) now produces a CHAR field. Add new VARCHAR type. Added *default-varchar-length* rather than previous hard-coded varchar length. Remove 'simple-string and 'simple-base-string since they are subtypes of 'string. * db-oracle/oracle-sql.lisp: Use *default-varchar-length* rather than local hard-coded value. * sql/metaclasses.lisp: Convert specified type VARCHAR and (VARCHAR n) to Lisp type string. Convert specified-type (CHAR n) to string. Convert specified-type CHAR to lisp type character. * sql/generic-postgresql.lisp: (string n) => (CHAR n) * sql/operations.lisp: Add userenv * doc/TODO: Add AUTOCOMMIT. Remove need for large table and bigint slot tests * sql/oracle-sql.lisp: Add 64-bit bigint direct conversion * uffi/clsql-uffi.lisp: Handle signed 64-bit integers * test/test-init.lisp: Add large table with bigint slot 25 May 2004 Kevin Rosenberg * Version 2.11.1 released: Much simpler Oracle client library loading. Now uses ORACLE_HOME environmental variable as well as tests default path for Oracle Instant Client. 25 May 2004 Kevin Rosenberg * Version 2.11.0 released: Full Oracle support. All tests pass * db-oracle/oracle-sql.lisp: Add declaration so that SBCL runs efficiently. * tests/test-init.lisp: capitalize odbc backend name in banner * CONTRIBUTORS: Add note about Marcus' excellent work * sql/oodml.lisp: Removed old stub function * clsql.asd: Use module names in current package rather than keyword package * db-oracle/oracle-sql.lisp: Don't trim trailing spaces. Prevent interrupts in setting sequence position. Make autocommits more efficient. * tests/test-init.lisp: Skip 2 tests on Oracle which have unsupported syntax * sql/oodml.lisp: Get rid of undocumented raw-string type. CommonSQL strings are raw (non-trimmed trailing whitespace). Add database-get-type-specifier and read-sql-value for NUMBER and CHAR. * sql/base-classes.lisp: Add autocommit slot * sql/transaction.lisp: Added autocommit processing, mild cleaning. * doc/intro.xml: Add Oracle 24 May 2004: Marcus Pearce (m.t.pearce@city.ac.uk) * db-postgresql-socket/postgresql-socket-sql.lisp: replace CLSQL-SIMPLE-WARNING with SQL-WARNING. * db-sqlite/sqlite-sql.lisp: replace CLSQL-SIMPLE-WARNING with SQL-WARNING. * db-aodbc/aodbc-sql.lisp: replace CLSQL-ERROR with SQL-ERROR. * clsql.asd: reworked module structure in package definition and file names to better reflect component functionality. * sql/package.lisp: added SQL-FATAL-ERROR and SQL-TIMEOUT-ERROR to exports list. Removed duplicate and obsolete exports. Exported remaining SQL operations: SQL-SOME, SQL-<>, SQL-BETWEEN, SQL-DISTINCT, SQL-NVL and SQL-FUNCTION. Organised exports by functionality/file and according to whether they are specified by CommonSQL or CLSQL extensions. * sql/transaction.lisp: replace CLSQL-SIMPLE-WARNING with SQL-WARNING. * sql/generics.lisp: moved generics for QUERY and EXECUTE-COMMAND here from basic-sql.lisp. * sql/expressions.lisp: NEW FILE: renamed from classes.lisp (deleted). * sql/fddl.lisp: NEW FILE: renamed from table.lisp (deleted). * sql/fdml.lisp: NEW FILE: merger of basic-sql.lisp and sql.lisp (both deleted). * sql/ooddl.lisp: NEW FILE: ooddl from objects.lisp (deleted). * sql/oodml.lisp: NEW FILE: oodml from objects.lisp (deleted). 23 May 2004 Kevin Rosenberg * Version 2.10.22 released * sql/kmr-mop.lisp, sql/objects.lisp: Since SBCL is the only implementation that has reversed class slots, change the default for ordered-class-slots so that slots are now in the same order an in the def-view-class. * sql/sql.lisp: Honor case of string table identifier to INSERT-RECORDS * test/test-fddl.lisp: Add two tests for mixed case names * db-oracle/oracle-sql.lisp: Add missing database qualifier. Return NUMBER (double) for computed fields, this will require some adjustment to the test suite which in many cases expects integers. * test/test-fdml.lisp: Accomodate that Oracle returns doubles for computed columns 22 May 2004 Kevin Rosenberg * Version 2.10.21 released * sql/sequences.lisp: Move generic sequence functions here from db-sqlite, db-odbc, and db-aodbc. * sql/*.lisp: Add db-type parameter to generic functions READ-SQL-VALUE, DATABASE-GET-TYPE-SPECIFIER, and OUTPUT-SQL-VALUE-AS-TYPE. Update methods to use these. * sql/generic-postgresql.lisp, sql/generic-odbc.lisp: New files * db-odbc/odbc-sql.lisp, db-aodbc/aodbc-sql.lisp: Move common code to sql/generic-odbc.lisp * db-postgresql/postgresql-sql.lisp, db-postgresql-socket/postgresql-socket-sql.lisp: Move common code to sql/generic-postgresql.lisp * sql/classes.lisp: honor case of string tables when outputting queries * sql/objects.lisp: Add database type to default database-get-type-specifier method * sql/sql.lisp: Add database type to default database-abort-transaction method * db-mysql/mysql-objects.lisp: New file * sql/objects.lisp: Move MySQL specific code to mysql-objects.lisp * sql/utils.lisp: Add GETENV function which will be used to get ORACLE_HOME from environment * test/test-fdml.lisp: String table names are now case sensitive, so convert to default db case for FDML/SELECT/25 22 May 2004 Kevin Rosenberg * Version 2.10.20 released: Oracle backend now fails 6 out of 200 tests * TODO: Added 2 variances from CommonSQL. Add tests for owner phrases and string identifiers with non-default case * sql/table.lisp: Don't convert string table name to a symbol. * sql/classes.lisp: Honor case of string identifiers * sql/sql.lisp: Ensure recyclebin is purged for Oracle in TRUNCATE-DATABASE * db-oracle/oracle-sql.lisp: Add sequence functions, fix use of of owner phrases. Obtain server and client versions. * db-oracle/oracle-objects.lisp: Fix type specifiers * tests/test-fddl.lisp: Allow :varchar2 and :number as data types * tests/test-init.lisp: Properly get username from Oracle connection-spec 22 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/generics.lisp: reworked docstrings. Remove generics for ADD-TO-RELATION and REMOVE-FROM-RELATION. * sql/objects.lisp: reworked docstrings. Changed UPDATE-OBJECT-JOINS to UPDATE-OBJECTS-JOINS for CommonSQL compatibility. * sql/package.lisp: Changed UPDATE-OBJECT-JOINS to UPDATE-OBJECTS-JOINS for CommonSQL compatibility. Remove ADD-TO-RELATION and REMOVE-FROM-RELATION. * tests/test-oodml.lisp: Changed UPDATE-OBJECT-JOINS to UPDATE-OBJECTS-JOINS for CommonSQL compatibility. * doc/TODO: added notes about extra slot options to DEF-VIEW-CLASS. * sql/conditions.lisp: add documentation for conditions. Add SQL-TIMEOUT-ERROR and SQL-FATAL-ERROR for CommonSQL compatibility. 21 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/basic-sql.lisp: reworked docstrings. * sql/transactions.lisp: reworked docstrings. * sql/sql.lisp: reworked docstrings. * sql/initialize.lisp: reworked docstrings. INITIALIZE-DATABASE-TYPE sets *DEFAULT-DATABASE-TYPE* for CommonSQL compatibility. * sql/database.lisp: reworked docstrings. * doc/TODO: added notes about START-TRANSACTION and IN-TRANSACTION-P and FDML extensions and database extensions. 20 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * db-oracle/oracle-sql: Use clsql-specific error conditions. Use owner keyword. * db-oracle/make9.sh: add makefile for building with Oracle 9 client libraries * sql/table.lisp: Add logic for dealing with Oracle 10g vs. previous Oracle versions with the PURGE option required for drop table. This needs to be converted to a generic function and moved to db-oracle/oracle-sql.lisp 20 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/classes.lisp: remove unused PARAMS slot in SQL-IDENT-ATTRIBUTE. * sql/syntax.lisp: remove unused PARAMS keyword arg to SQL-EXPRESSION. * sql/table.lisp: reworked docstrings. * sql/objects.lisp: moved *default-update-objects-max-len* here from table.lisp. * doc/TODO: notes about :if-does-not-exist arg to DROP-TABLE, DROP-VIEW and DROP-INDEX and the use of the :transactions and :constraints keyword args to CREATE-TABLE. * sql/classes.lisp: the DESCRIPTION argument to CREATE-TABLE is now CommonSQL compatible with respect to column constraints. 20 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * sql/oracle-sql.lisp: Now compiles and runs on SBCL. Requires UFFI 1.5.0 or higher 20 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.19 * sql/conditions.lisp: Fix cerror 19 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.18 released: New condition hierarchy to be compatible with CommonSQL -- not backward compatible with previous CLSQL. * sql/db-interface.lisp: Add more default methods * sql/objects.lisp: Add explicit table name to order-by parameters in find-all when only one table to avoid selecting a duplicate row. Fix error in FIND-ALL when using :order-by such as (([foo] :asc)) as previous logic was adding two fields (foo asc) to SELECT query. Make :result-types :auto be the default for object selections. Properly handle caching key when using multiple order-by with asc/desc directions. * db-oracle/*.lisp: Much improvements, now passes 90% of test suite 19 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/recording.lisp: reworked docstrings. * sql/syntax.lisp: reworked docstrings. * doc/TODO: added notes about extensions to SQL-RECORDING-P and the SQL syntax state functions being macros. 19 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * sql/package.lisp: Export initialize-database-type and *initialize-database-types* from CLSQL package. * sql/conditions.lisp: Add new CommonSQL compatible conditions, remove old CLSQL conditions. * sql/loop-extensions.lisp: Make errors of type sql-user-error * */*.lisp: Convert to from old to new conditions 18 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * sql/table.lisp: Add PURGE to drop command for oracle 10g backend. To handle this difference, will need to add a new database-drop-table generic function. * db-oracle/oracle-sql.lisp: Move server-version and major-version-number to database object to allow multiple connections to Oracle servers of different versions. 18 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * TODO: moved notes about backends to doc/TODO. * doc/TODO: added notes about backends and select extensions. * sql/base-classes.lisp: remove obsolete schema slot in database class. 16 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * db-oracle/oracle-api: Add OCIServerVersion * db-oracle/oracle-sql: Query and store server version on connect * sql/db-interface.lisp: Add new db-type-has-bigint? generic function to handle OCI's lack of bigint support * test/test-basic.lisp: Separate bigint testing * test/test-utils.lisp: Add oracle to specs and list of backends * doc/TODO: New file * test/test-fdml.lisp: Added FDML/SELECT/34 to test run-time instantiation of variables in reader macros. * TODO: Remove item already complete. Add note about condition variances 16 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/syntax.lisp: added condition to the reader macro to treat [*] as a column identifier (rather than an operation) for CommonSQL compatibility. * tests/test-fdml.lisp: add tests for ORDER-BY and SET-OPERATION keword args to SELECT, [*] as column identifier, new MAP-QUERY behaviour and the ANY and ALL operators in subqueries. * tests/test-init.lisp: add set-operation and subquery tests to appropriate skip lists. * sql/objects.lisp: remove redundant and non CommonSQL compatible ORDER-BY-DESCENDING keyword argument for SELECT. * sql/classes.lisp: remove redundant and non CommonSQL compatible ORDER-BY-DESCENDING keyword argument for SELECT. * tests/test-oodml.lisp: add test for ORDER-BY keyword to SELECT with object queries. 15 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * sql/db-interface.lisp: Add new db-type-has-union? since Mysql 3.23 does not support unions. * sql/test-init.lisp: Don't try union tests on database backends which do not support it. * db-oracle/*.lisp: initial port to UFFI * sql/objects.lisp: implement UPDATE-OBJECT-JOINS, implement REFRESH for SELECT. * tests/test-oodml.lisp: Add tests for deferred retrieval, caching, refresh, and update-object-joins * tests/test-init.lisp: Add deferred-employee-address class 15 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/operations.lisp: make MINUS operator a synonym for EXCEPT. Add COALESCE operator and make NVL a synonym for this. Make ANY, SOME, ALL and EXISTS generate function expressions so they output the correct SQL. * sql/classes.lisp: SELECT now generates appropriate SQL when passed the SET-OPERATION and ALL keyword arguments. * sql/classes.lisp: the ORDER-BY keyword argument to SELECT now accepts ordering constraints as pairs of the form (column direction) where direction may be :ASC or :DESC. * tests/test-syntax.lisp: added tests for MINUS and COALESCE/NVL. Correct tests for ANY, SOME, ALL and EXISTS. * tests/test-fdml.lisp: added test for COALESCE. * sql/sql.lisp: MAP-QUERY now applies FUNCTION to QUERY-EXPRESSION using funcall unless QUERY-EXPRESSION returns one column and its FLATP slot is not nil in which case apply is used. * tests/test-basic.lisp: modified calls to MAP-QUERY to reflect the changes. * TODO: remove items done. * db-postgresql/postgresql-sql.lisp: no need to reverse results in DATABASE-LIST-ATTRIBUTES. * db-postgresql-socket/postgresql-socket-sql.lisp: no need to reverse results in DATABASE-LIST-ATTRIBUTES. 15 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/classes.lisp: SELECT now accepts table identifiers as strings for CommonSQL compliance. Add support for qualified sql identifiers with aliased table names. * tests/test-fdml.lisp: added tests for table identifiers as strings in SELECT and for aliased definitions. * tests/test-syntax.lisp: added tests for alias definitions. 15 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/sql.lisp: PRINT-QUERY now calls QUERY with result-types and field-names set to nil. * sql/sql.lisp: PRINT-QUERY now computes column sizes correctly with null attribute values. * sql/operations.lisp: modify SQL concatenation operator to accept unescaped || symbol. * sql/syntax.lisp: modify sql reader macro function to accept unescaped sql concatenation operator. * tests/test-fdml.lisp: unescape sql concatenation operator. * tests/test-syntax.lisp: unescape sql concatenation operator. * TODO: remove items done. Add notes about SQLITE/MYSQL backends. Note to add test for universal-time. Note about difference from CommonSQL in transaction handling. 13 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * tests/test-init.lisp: Add deferred-employee-address class * tests/test-oodml.lisp: Add deferred retrieval testgs 12 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.17 * LATEST-TEST-RESULTS: Run on all platforms, add AMD64 * sql/sql.lisp: Add FOR-EACH-ROW macro from clsql-classic/sql.lisp * db-sqlite/sqlite-uffi-api.lisp: Fix row-pointer type * *: Fix minor style warnings * clsql-classic: Remove system and subdirectory * clsql-base: Remove system and subdirectory and fold into clsql system * doc/intro.xml: Remove reference to old clsql-base. Add x86_64 as supported platform. 12 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.16: CLSQL now fully supports AllegroCL AMD64 * db-odbc/odbc-api.lisp: work around return-type bug [spr28889] in Allegro 7.0beta AMD64 * db-odbc/*.lisp: Add a layer of indirection to foreign-type of ODBC longs since this type can vary on 64-bit platforms depending upon the compilation options of unixODBC. * db-mysql/mysql-api.lisp: Fix int vs. long slots in foreign structures found by testing with AllegroCL 7.0b AMD64. * db-*/*-loader.lisp: Load 64-bit libraries on 64-bit platorms * sql/objects.lisp: Simple implementation of UPDATE-OBJECT-JOINS. Initial caching support for SELECT * tests/test-oodml.lisp: Avoid using cache when testing select. * sql/kmr-mop.lisp: Explicitly check slot order and store as a cl:*feature* * sql/recording.lisp: Remove additional types to increase CommonSQL conformance. * tests/test-init.lisp: Change a :column attribute to test symbols as value * sql/relations.lisp: Remove functions since they don't support many to many relationships. * examples/clsql-tutorial.lisp, doc/csql.lisp: Remove use of add-to-relations function and replace with explicit field settings. * base/classes.lisp: Remove obsolute query-stream. Add record-caches slot. 9 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.15 * LATEST-TEST-RESULTS: results with current version * sql/kmr-mop.lisp: Make CMUCL reader macros specific for cmu18 since cmu19 has opposite order of class slots. * sql/objects.lisp: Fix (setf slot-value-using-class) for Lispworks * tests/test-fdml.lisp: Renumber SELECT tests to avoid overwriting a previous test * tests/test-init.lisp: Check test-database-underlying-type for ODBC/MySQL tests 8 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/operations.lisp: complete remaining operations for the sql syntax: SUBSTR, SOME, ORDER-BY, GROUP-BY, NULL, DISTINCT, EXCEPT, UNION, INTERSECT, BETWEEN. * sql/classes.lisp: add new classes: SQL-BETWEEN-EXPRESSION, SQL-QUERY-MODIFIER-EXPRESSION and SQL-SET-EXPRESSION. * tests/test-syntax.lisp: add tests for new operations. * tests/test-fdml.lisp: add tests for queries based on new operations. * tests/test-init.lisp: add select/20 to tests skipped for sqlite and select/20, query/5, query/7 and query/8 to tests skipped by mysql. * TODO: removed entries done. 8 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * tests/benchmarks.lisp: Add immediate vs. deferred join test. 8 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.13: Now works on openmcl 0.14.2 * sql/objects.lisp: Add :retrieval :immediate for object selections * tests/test-init.lisp: Add non-index fields for testing join class employee-addresss * test/test-oodml.lisp: Add tests for retrieval immediate * sql/metaclasses.lisp: Handle differences in direct-slot-definition values which are now listifed by openmcl 14.2. * sql/objects.lisp: more framework for supporing immediate retrieval 7 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * docs/intro.xml: Upload location of a README file * sql/metaclass.lisp: Work-around openmcl's CHANGE-CLASS changing the type-specifier. Use a lisp type of (OR NULL FOO) for a specified-type of FOO unless :db-constraints :not-null. No need to specialize finalize-inheritance for openmcl. * tests/test-*.lisp: Rename fields so that joins occur on fields with different names. This ensures that join code is selecting the proper name. * test/test-init.lisp: Add :base-table for employee-address view class for testing. * sql/objects.lisp: Use view-table rather than name of table in a number of places to fix errors noted with using :base-table. 6 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/objects.lisp: replace *update-records-on-make-instance* with *db-auto-sync* which also controls both automatic creation of new records on creation of new instance and updating of record fields on setting of instance slots (as suggested by Edi Weitz). * tests/test-init.lisp: replace *update-records-on-make-instance* with *db-auto-sync*. * sql/package.lisp: replace *update-records-on-make-instance* with *db-auto-sync*. * TODO: replace *update-records-on-make-instance* with *db-auto-sync*. * sql/objects.lisp: remove redundant rebindings of *db-initializing* and *default-database* in FIND-ALL. * sql/package.lisp: import time functions from CLSQL-BASE. * tests/test-time.lisp: replace CLSQl-BASE package qualifier with CLSQL. * tests/test-fdml.lisp: replace CLSQl-BASE package qualifier with CLSQL. * tests/test-init.lisp: replace CLSQl-BASE package qualifier with CLSQL. * tests/test-ooddl.lisp: replace CLSQl-BASE package qualifier with CLSQL. 4 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * sql/classes.lisp: Add SQL-OBJECT-QUERY type. Have [select 'class] now return a sql-object-query type rather than directly performing a query. This improves CommonSQL conformance. * sql/sql.lisp: Add new QUERY method for SQL-OBJECT-QUERY. Move from basic/basic-sql.lisp the DO-QUERY and MAP-QUERY since they now depend on sql-object-query-type. * sql/loop-extensions.lisp: Move from base package * classic/package.lisp: remove references to map-query and do-query 4 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * TODO: New section on optimizations, especially optimizing JOINs. * sql/objects.lisp: Have :target-slot return of list of lists rather than a list of cons pairs to be conformant with CommonSQL. Make :target-slot much more efficient by using a SQL inner join statement and just requiring one SQL query. Add :retrieval :deferrred to target-slot joins. Add placeholder for update-objects-join. * sql/classes.lisp: Add :inner-join and :on slots to sql-query class and process them for query output-sql. 4 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.11 * base/basic-sql.lisp: Avoid multiple evaluation of query-expression in DO-QUERY * sql/objects.lisp: Make SELECT a normal function. SELECT now accepts type-modified database identifiers, such as [foo :string] which means that the values in column foo are returned as Lisp strings. Add new *update-records-on-make-instance* special variable controlling automatic creation of new instances. Add missing RESULT-TYPES keyword to FIND-ALL. Add :target-slot support. * sql/packages.lisp: Export *update-records-on-make-instance* * test/test-oodml.lisp: Add tests for :target-slot and many-to-many selections. * test/test-fdml.lisp: Add tests for type-modified database identifiers. * test/test-init.lisp: Stop using add-relation since implementing many-to-many joins. Use *update-records-on-make-instance* to automatically store records on instance creation. Add many-to-many employee-address view-class. 4 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.10 * base/loop.lisp: Add object iteration. Use :result-type :auto for result-set. Remove duplicate (and non-correct) code for non-list variables by simply making an atom variable into a list. * sql/package.lisp: Remove unnecessary clsql-sys package and replace it with clsql. * sql/metaclasses.lisp: Properly store specified-type from direct-slot-definition and then store translated type in effective-slot-definition * sql/classes.lisp: Don't output type in sql-output for SQL-IDENT-ATTRIBUTE. This is in preparation for supporting [foo :integer] as fields in SELECT. * sql/query.lisp: Set default for :result-types to :auto in FDML QUERY. * sql/objects.lisp: Use specified-type when invocating database-get-type-specifier. def-view-class macro now returns the class instance. * base/basic-sql.lisp: Make :AUTO the default value for :RESULT-TYPES for MAP-QUERY and DO-QUERY. * sql/objects.lisp: Add bigint type * test/tests-basic.lisp: Add tests for :result-types for MAP-QUERY and DO-QUERY * test/test-fdml.lisp: Add test for result-types in LOOP and also using single symbol rather than a list for variables. Add test that default :result-types is auto for FDML QUERY. * test/test-syntax.lisp: Don't expect TYPE in the SQL-OUTPUT of SQL-IDENT-ATTRIBUTE. * test/test-oodml.lisp: Enable OO loop iteration test, modify it so it doesn't depend on boolean where. 4 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * Version 2.10.9 * sql/objects.lisp: added derived type specifier for universal time. * sql/package.lisp: added #:universal-time to clsql-sys exports. * tests/test-oodml.lisp: added test for translation of boolean slots in SELECT with object queries. 3 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * db-odbc/odbc-api.lisp: Fix changing nil to "NIL" for odbc/postgresql backend. * db-odbc/odbc-sql.lisp: Fix ATTRIBUTE-TYPE so that it can handle NIL values from the ODBC driver * tests/benchmarks.lisp: New file with initial benchmark suite * sql/relations.lisp: fix to add subclassing support, minor optimizations [Edi Weitz] 3 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.8 * base/conditions.lisp: Add *backend-warning-behavior* special variable. * db-postgresql-socket/postgresql-socket-sql.lisp: Honor value of *backend-warning-behavior* * tests/test-fdml.lisp: Remove test of raw boolean value since different backends handle this differently. Add test for :column attribute. * tests/test-oodml.lisp: Add tests for boolean slot value and for :void-value attribute * tests/test-init.lisp: Use *backend-warning-behavior* to suppress warnings from postgresql about implicitly creating primary key in tables. Add new address table. 3 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.7 * db-odbc/odbc-dbi.lisp: Convert TINYINT to integers when result-types is :auto * sql/objects.lisp: Properly handled writing/reading Boolean values from SQL database when retrieving objects. * test/test-fdml.lisp: Add another test for boolean results * test/utils.lisp: Fix incorrect declaration 2 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * Version 2.10.6 * sql/generics.lisp: add generic function for SELECT. * sql/objects.lisp: make SELECT a method specialisation. * sql/classes.lisp: MAKE-QUERY now calls SELECT if the selections referred to are View Classes. * base/basic-sql.lisp: in DO-QUERY and MAP-QUERY, if the query-expression arg evaluates to a list, then we have an object query. * tests/test-oodml.lisp: add tests for DO-QUERY and MAP-QUERY with object queries. * TODO: remove items done and add a todo for SELECT. * sql/objects.lisp: SELECT takes a :field-names arg to pass on to QUERY. * sql/sql.lisp: add :field-names arg to QUERY. * tests/test-fdml.lisp: minor rework to use :field-names arg to SELECT. 2 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * sql/objects.lisp: fix bug in FIND-ALL when SELECT called with 2 or more View Classes. * sql/objects.lisp: make the :flatp argument to SELECT work with object queries. * sql/objects.lisp: make SELECT accept a :result-types argument (defaults to :auto) which is passed on to QUERY. * sql/objects.lisp: SELECT returns field-names as a second value. * tests/test-ooddl.lisp: add flatp arg to SELECT calls as appropriate. * tests/test-fdml.lisp: add flatp/result-types arguments to calls to SELECT and take only first value as appropriate. * tests/test-fdml.lisp: add two new tests for query result coercion and the field-names returned as a second value from SELECT. * tests/test-oodml.lisp: add flatp arg to SELECT calls as appropriate. 1 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.6-pre1 * sql/metaclasses.lisp: Add void-value slot * doc/csql.xml: Update def-view-class documentation * test/test-init.lisp: Change old :db-type to :db-kind. Remove old :nulls-ok attributes. * sql/objects.lisp: Add new universal-time and bigint types. Optimize reading of integers using parse-integer rather than read-from-string. * */*.lisp: Merge clsql-base-sys and clsql-base packages into clsql-base package * classic/sql.lisp: Move large object support into base, leaving classic without any functionality that is provided in the clsql system. * classic/package.lisp: Rename clsql-classic-sys package to its former nickname of clsql-classic 1 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.5: SQLite backend now passes all result-types tests * clsql-sqlite.asd: Depend on clsql-uffi system * db-sqlite/sqlite-sql.lisp: Use clsql-uffi:convert-raw-field for efficiency and code reuse. * db-sqlite/sqlite-api-uffi.lisp: Change (* :char) to (* :unsigned-char) for better cross-implementation compatibility. 1 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.4 * sql/tables.lisp: Fix typo in CACHE-TABLE-QUERIES [Marcus Pearce] * db-postgresql/postgresql-sql.lisp: Fix foreign-string vs. cstring bug on SBCL in result-field-names function as reported by Marcus Pearce * db-sqlite/sqlite-sql.lisp: Fix in database-store-next-row manifest in SBCL testing 1 May 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.3 * sql/database.lisp: Conform more to CommonSQL output for STATUS command [Marcus Pearce] * sql/sqlite-sql.lisp: Rework to use result-types * sql/sqlite-api-clisp.lisp: Add compatibility layer with sqlite-api-uffi.lisp so that sqlite-sql.lisp can be cleaned up of most clisp reader conditionals * sql/test-init.lisp: Now run field type tests on sqlite backend 30 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.2 * base/basic-sql.lisp: Set default value of :result-types to :auto for more CommonSQL conformance. * test/test-fdml.lisp: Add tests for numeric value of fields 30 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.10.1: New API function: CACHE-TABLE-QUERIES. * base/basic-sql.lisp, db-*/*-sql.lisp: More CommonSQL conformance. Return field names as second value for QUERY. This can be overridden for efficiency with the new keyword :FIELD-NAMES set to NIL in the QUERY invocation. * test/test-fdml.lisp: Add tests for new field-name feature * sql/metaclass.lisp: Remove old Lispworks cruft and replace it with invocation of new code in kmr-mop.lisp which actually works with Lispworks 4.2 * doc/ref_clsql.xml: Document new :FIELD-NAMES keyword to QUERY function * base/db-interface.lisp: Document the multiple values returned by DATABASE-ATTRIBUTE-TYPE so matches the undocumented CommonSQL behavior. * sql/table.lisp: Add *CACHE-TABLE-QUERIES-DEFAULT* and *DEFAULT-UPDATE-OBJECTS-MAX-LEN* variables and export them. LIST-ATTRIBUTE-TYPES now conforms to CommonSQL spec. Implement CACHE-TABLE-QUERIES. * db-odbc/odbc-sql.lisp: Fix attribute-type function * test/test-fddl.lisp: Add tests for attribute type * db-mysql/mysql-sql.lisp: Mild optimization in accessing field structures. * base/classes.lisp: Add attribute-cache slot to database clas * base/initialize.lisp: initialize-database-type now automatically loads database-type backend as needed. * base/test-init.lisp: Utilize new initialize-database-type functionality. * TODO: remove items done 30 Apr 2004 Marcus Pearce (m.t.pearce@city.ac.uk) * Version 2.9.6 * sql/objects.lisp: remove create/drop-sequence-from-class. * sql/objects.lisp: add INSTANCE-REFRESHED generic function. * sql/objects.lisp: improved CommonSQL compatibility for UPDATE-RECORD-FROM-SLOT, UPDATE-RECORD-FROM-SLOTS, UPDATE-RECORDS-FROM-INSTANCE and DELETE-INSTANCE-RECORDS. * sql/generics.lisp: move generics from objects.lisp to here. 29 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.9.6-pre1 * db-mysql/mysql-client-info.lisp: Add client version 4.1 detection * sql/sql.lisp: Make *default-database* the default for TRUNCATE-DATABASE 28 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.9.5 * db-mysql/mysql-sql.lisp: Fix bug in transaction capability detection * sql/objects.lisp: Commit patch from Slawek Zak to allow specifying :metaclass in DEF-VIEW-CLASS invocation. This allows defining classes on a metaclass specialized from standard-db-class. 24 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.9.4: Multiple changes to support Allegro's "modern" lisp which uses a lowercase reader and has case-sensitive symbols * sql/classes.lisp: Fix make-load-form bug for sql-ident-table exposed by case-sensitive mlisp. 22 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.9.3: All tests now pass on all platforms! * LATEST-TEST-RESULTS: New file with summary of test results * sql/generics.lisp: New file for generic function definitions. * test/test-init.lisp: Display names of skipped tests. Use unwind-protect to ensure disconnect * sql/objects.lisp: Change database-type to database-underlying-type so that actual database engine is properly identified * db-odbc/odbc-api.lisp: Have default *time-conversion-function* return an ISO timestring for compatibility with other drivers. Workaround bug in MyODBC for LIST-TABLE-INDEXES * test/test-fdml.lisp: Accomodate that odbc-postgresql driver returns floating-point values for floor and truncate operations * db-aodbc/aodbc-sql.lisp: Implement DATABASE-LIST-VIEWS * tests/test-basic.lisp: Port to regression tester * test/test-init.lisp: Output to *report-stream* * docs/appendix.xml: Document ODBC and SQLite backends. * sql/classes.lisp: Make output-sql require a database parameter. This allows SQL generation to have the proper case to support the differences in case handling between CommonSQL API, Postgresql, MySQL, Oracle. 21 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.9.2: Improvments in database capability introspection and querying. Support transactions in MySQL where available. All tests now pass on MySQL and SQLite in addition to postgresql and postgresql-socket. ODBC fails only with OODDL/TIME/1 and OODDL/TIME/2. * db-odbc/odbc-sql.lisp: Add DATABASE-LIST-VIEWS. Better support DATABASE-LIST-SEQUENCES. * clsql-uffi.asd, clsql-mysql.asd: Improve shared library loading * Database_capabilies: add HAS-VIEWS, HAS-CREATE/DESTROY-DB, HAS-BOOLEAN-WHERE, TRANSACTION-CAPABLE * tests/*.lisp: Check database capabilities and remove tests which the database backend does not support * sql/table.lisp: Add :TRANSACTIONS keyword to create table which controls whether InnoDB tables will be created when supported on the underlying MySQL server. 20 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.9.0: New API function: LIST-TABLE-INDEXES, supported by all database backends (except AODBC since AODBC doesn't support index querying) * db-obdc/odbc-sql.lisp: Support DATABASE-LIST-INDEXES * db-odbc/odbc-api.lisp: Add %TABLE-STATISTICS function to support index queries * db-aodbc/aodbc-sql.lisp: Filter driver manager "information_schema" tables from LIST-TABLES * tests/test-basic.lisp: Remove table after testing * tests/test-fddl.lisp: Test LIST-TABLE-INDEXES * base/db-interface.lisp: Add DATABASE-UNDERLYING-TYPE which gets the underlying type of database -- required when dealing with ODBC databases and want to query database capabilities. Added DB-USE-COLUMN-ON-DROP-TABLES? as first database-backend specific feature. Is T on :mysql, NIL on other backends. Change DROP-TABLE to query this. 19 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.8.2: Build changes for FreeBSD [Slawek Zak] 19 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.8.1 * db-odbc/odbc-sql.lisp: Add DATABASE-LIST function * db-odbc/odbc-dbi.lisp: Add LIST-ALL-DATA-SOURCES function 19 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.8.0: New API function: LIST-DATABASES * base/utils.lisp: Fix command-output on CMUCL/SBCL * db-*/*-sql.lisp: Add new database-list function * base/database.lisp: Add new LIST-DATABASES command 18 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.9 * db-sqlite/sqlite-sql.lisp: Fix sequence functions. * db-sqlite/sqlite-api-uffi.lisp: Print error string correctly. 18 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.7 * doc/csql.xml, examples/clsql-tutorial.lisp: Patch for db-kind from Eduardo Munoz. 17 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.6 * base/objects.lisp, base/classes.lisp: Patch for db-kind from Eduardo Munoz 16 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.5 * base/basic-sql.lisp: Fix FLATP in QUERY 16 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.3: Implement RECONNECT 15 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.2: Fix ODBC on Lispworks Windows 15 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.1: Fix for new ODBC backend. clsql-odbc now works on SBCL, CMUCL, OpenMCL in addition to AllegroCL and Lispworks. 15 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.7.0: New backend: ODBC. Tests as well as AODBC backend on Allegro,Lispworks. SBCL and CMUCL don't work quite yet. Requires UFFI v1.4.11+ * db-odbc/*.lisp: Add ODBC3 function SQLSetEnvAttr to explicitly set ODBC2 support. Add BIGINT support. Add result-types support. Added SQLTables. Fix array type in fetch-all-rows. Make width changable by database or query. * base/utils.lisp: Add process functions * base/package.lisp: Export utils to CLSQL-BASE-SYS * db-aodbc: Implement sequence functions, database-list-tables, database-list-attributes * tests/utils.lisp: Add support for ODBC backend, rework READ-SPECS to use +all-db-types+ * db-mysql/mysql-sql.lisp: Use WITHOUT-INTERRUPTS for SEQUENCE-NEXT 13 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.13. Requires UFFI version 1.4.9 * db-odbc/*.lisp: Further porting. Pre-alpha code! But, basic query is now working. 13 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.12 * base/transactions.lisp: Add quote for macro expansion of WITH-TRANSACTIONS [Time Howe] * db-sqlite/sqlite-sql.lisp: Support memory database in database-probe [Ng Pheng Siong] * db-odbc/*.lisp: Initial port to UFFI of SQL-ODBC. The DBI layer is not finished. 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.11 * sql/objects.lisp: add :root-class functionality for list-classes and add duration type support [Marcus Pearce] * db-odbc: Add mid-level [DBI] layer 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.10 * db-aodbc: Add methods for generic functions, some are not yet implemented. * clsql-odbc.asd, db-odbc/*.lisp: Initial start of ODBC support 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.9 * base/package.lisp: Add missing symbols [Marcus Pearce] 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.8 * test/test-fddl.lisp: Cleanup fix [Marcus Pearce] * utils/time.lisp: Multiple fixes [Marcus Pearce] * sql/sql.lisp: Fix for truncate-database [Marcus Pearce] 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.7 * sql/*.lisp: Remove schema versioning cruft [Marcus Pearce] * Makefile: Add classic subdirectory 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.6 * sql/sql.lisp: Fix TRUNCATE command, bug reported by Marcus Pearce * sql/sql.lisp: Remove EXPLAIN function. Postgresql/Oracle specific and easy for an application to directly support. Idea from Marcus Pearce. * base/basic-sql.lisp: Remove DESCRIBE-TABLE top-level API as duplicates LIST-ATTRIBUTE-TYPES [Marcus Pearce]. Keep low-level interface for future optimization supporting LIST-ATTRIBUTE-TYPES command. * Makefile: Add to db-sqlite and test directories. Include them in top-level Makefile 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.5 * sql/relations.lisp: Add missing file * utils/time.lisp: Fixes/extensions [Marcus Pearce] * test/test-time.lips: New file [Marcus Pearce] 10 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.4 * test/test-init.lisp: Properly handle object creation. Close database after use. * sql/sql.lisp: Make DESCRIBE-TABLE a generic function so can have methods specialized on table being a string or an sql-table object. * base/pool.lisp: Really fix CMUCL locking 10 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.3 * test/test-init.lisp: Signal correctly if any errors occurred in any test suite * base/loop-extensions.lisp: Fix error introduced for Lispworks * base/pool.lisp: Fix locking for CMUCL * base/objects.lisp: Remove schema-version cruft 10 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.2: New CLSQL API functions: DESCRIBE-TABLE AND TRUNCATE-DATABASE Currently, this are only supported on :postgresql and :postgresql-socket * base/database.lisp: automatically load ASDF system in CONNECT if not already loaded * base/tests.lisp: disconnect database after testing * base/*.lisp: Remove CLOSED-DATABASE type in favor of storing open/closed status in slot of database * base/pool.lisp: Support locks for CMUCL, OpenMCL, SBCL * db-postgresql/postgresql-sql.lisp: add DATABASE-RECONNECT, DATABASE-DESCRIBE-TABLE * db-sqlite/sqlite-sql.lisp: Add missing slots in database * base/conditions: Remove duplicate condition * db-*/*-sql.lisp: Fill new database slot DATABASE-TYPE * base/recording.lisp: Add new :QUERY type for recording 10 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.1: documentation fixes, merged classic-tests into tests 10 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.0 released: New API functions CREATE-DATABASE, DESTORY-DATABASE, PROBE-DATABASE * doc/ref_clsql.xml: Document new functions * base/database.lisp: New API functions * base/conditions.lisp: Added CLSQL-ACCESS-ERROR * base/utils.lisp: Fix use of position-char. Add COMMAND-OUTPUT used by backends for running external programs. Fix parsing of SQL*NET-compatible connection-specs. * base/loop-extension.lisp: Simplify package use for Lispworks and Allegro * db-*/*-sql.lisp: Added DATABASE-CREATE, DATABASE-DESTORY, PROBE-DATABASE methods * tests/test-init.lisp, clasic-tests/tests.lisp: Use destroy-database and create-database to ensure testing with empty database * tests/test-connection.lisp: Add tests for parsing of string connection-specs * examples/run-tests.sh: New file for running test suite on all installed CL implementations * examples/clsql-tutorial.lisp: moved from doc directory * examples/dot.clsql-tests.config: New file giving an example test configuration * test/README: Add notes about rtest/ptester downloads and link to sample test configuration file. 10 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.5.1 released: * tests/*.lisp: Rework so tests are run on multiple backends automatically based on the contents of ~/.clsql-tests.config. Reuse helper functions from classic-tests. * base/database.lisp: Support connection-spec as string for CONNECT * classic-tests/tests.lisp: Automatically load database backends as needed. 09 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.5.0 released: All tests for CLSQL and CLSQL-CLASSIC pass on all platforms. * base/loop-extension.lisp: Add Lispworks loop-extension. Improve type specifying on other platforms. 09 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.4.2 released: loop extension now supported on Allegro, all CLSQL-TESTS pass on Allegro. * sql/metaclasses.lisp: Some optimization of compute-slots, be selective when ordered-class-slots needs to be called instead of class-slots * TODO: add URL with documentation on extending Lispworks LOOP form 09 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.4.1 released: CLSQL-TESt suite passes all tests for postgresql and CMUCL, SBCL, OpenMCL. Allegro and Lispworks pass all tests except for FDML/LOOP/1 since the loop extension have not yet been ported to those implementions. * sql/metaclasses.lisp: Added new slot to standard-db-class to hold user-specified type. OpenMCL adjustments to compensate for its type-predicate function. Since AllegroCL, Lispworks, and OpenMCL have different slot orders, added compute-slots and ordered-class-slots functions so their slot order matches SBCL/CMUCL. 08 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.4.0 released: All tests for clsql-classic now finish correctly on Allegro, Lispworks, CMUCL, SBCL, OpenMCL for mysql, postgresql, postgresql-sockets, and sqlite backends. * db-mysql/mysql-sql.lisp: Fix array dereferencing * classic-tests/tests.lisp: Fix package name of number-to-sql-string. * clsql.asd/clsql-tests.asd: Add support for asdf:test-op * db-sqlite/sqlite-api-{uffi,sql}.lisp: Multiple UFFI fixes, now passes tests on all support UFFI platforms. * db-postgresql-socket/postgresql-socket-api.list: Ported to SBCL and OpenMCL * multiple: Finish renaming of :types keyword to :result-types for greater CommonSQL compatibility, including documentation * sql/basic-cmds.lisp: Remove obsolete file 08 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.3.3 released * Fixes for sequences on mysql and sqlite [Marcus Pearce] * Fixes for uffi sqlite backend [Aurelio Bignoli / Kevin Rosenberg] * Fix for schema table [Marcus Pearce] * Add loop extension support for SBCL and OpenMCL [Marcus Pearce] * Fixes to test suite [Marcus Pearce] 06 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * db-*/*-sql.lisp: Ensure that expr in database-query-result-set is a string * Documentation integration 06 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * With for Marcus Pearce's excellent work, I've merged his clsql-usql port into clsql. The original clsql interface is available in the clsql-classic package. 02 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Integrate patch from Marcus Pearce adding further support for providing backend for UncommonSQL 10 Mar 2004 Kevin Rosenberg (kevin@rosenberg.net) * Integrate patch from Aurelio Bignoli for SQLite backend 11 Nov 2003 Kevin Rosenberg (kevin@rosenberg.net) * Converted documentation to XML format * Made package installable with asdf-install 23 Jul 2003 Kevin Rosenberg (kevin@rosenberg.net) * Add for-each-row macro 12 Dec 2002 Kevin Rosenberg (kevin@rosenberg.net) * uffi/clsql-uffi.lisp: return NIL for numeric fields that are NULL 16 Oct 2002 Kevin Rosenberg (kevin@rosenberg.net) * Add support for SBCL, OpenMCL, and SCL * Add *load-truename* to search path for clsql's compiled libraries. 01 Sep 2002 Kevin Rosenberg (kevin@rosenberg.net) * Rework use of file types in .asd files 17 Aug 2002 Kevin Rosenberg (kevin@rosenberg.net) * Add .asd definition files for ASDF users 31 Jul 2002 Kevin Rosenberg (kevin@rosenberg.net) * Restructure directories for Common Lisp Controller v3 compatibility 25 Jul 2002 Kevin Rosenberg (kevin@rosenberg.net) * Also change case of logical host in loader files * Rework handling of logical pathnames 05 Jul 2002 Kevin Rosenberg (kevin@rosenberg.net) * Change case of logical host 14 May 2002 Kevin Rosenberg (kevin@rosenberg.net) * clsql-base.system: Added base package that can be used without high-level SQL commands. Used for adding support for UncommonSQL. * *.system: Reworked logical pathnames to be more consistent with Common Lisp Controller. * debian/*: Completed initial Debian support 10 May 2002 Marc Battyani (marc.battyani@fractalconcept.com) * sql/classes.cl: * sql/transactions.cl: Added transaction support. Functions/macros added: with-transaction, commit-transaction, rollback-transaction, add-transaction-commit-hook, add-transaction-rollback-hook 04 May 2002 Marc Battyani (marc.battyani@fractalconcept.com) * sql/sql.cl: * sql/pool.cl: * sql/functional.cl: Added pool support in connect/disconnect and with-database. Removed with-db-from-pool as with-database can now works with the connections pool 01 May 2002 Marc Battyani (marc.battyani@fractalconcept.com) * sql/sql.cl: * sql/pool.cl: * sql/classes.cl: * sql/package.cl: Completed connection pool. Added with-db-from-pool macro. 27 Apr 2002 Kevin Rosenberg (kevin@rosenberg.net) * Multiple files: Added initial support for connection pool * sql/transactions.cl Took transaction code from UncommonSQL and integrated into CLSQL code. See file for disclaimer about why this was added. 23 Apr 2002 Kevin Rosenberg (kevin@rosenberg.net) * interfaces/postgresql/postgresql-sql.cl: Fix keyword typo in database-read-large-object * interfaces/mysql/mysql-loader.cl Fix loading on Win32 * test-suite/tester-clsql.cl Fix type coercion of double-float * doc/* Added debian docbook catalog, made it the default 19 Apr 2002 Marc Battyani (marc.battyani@fractalconcept.com) * interface/postgresql/postgresql-api.cl: * interface/postgresql/postgresql-sql.cl: * sql/sql.cl: * sql/db-interface.cl: Added large objects support for postgresql. 07 Apr 2002 Kevin Rosenberg (kevin@rosenberg.net) * src/postgresql-socket/postgresql-socket-api.cl: Fixed find-foreign-function call, eliminated crypt warning * Makefiles: Multiple improvements * sql/usql.cl: Moved functionality from low-level interfaces to this file via generic functions * test-suite/tester.cl: Added test with acl-compat-tester, moved others to old-tests directory. 06 Apr 2002 Kevin Rosenberg (kevin@rosenberg.net) * src/usql.cl: Reinstated commented out sections * interfaces/postgresql/postgresql-loader.cl: * interfaces/mysql/mysql-loader.cl: Updated find-forieign-library support. * interfaces/postgresql-socket/postgresql-socket-package.cl: Fixed require form for Lispworks (Thanks Marc Battyani!) * interfaces/postgresql-socket/postgresql-socket-api.cl: Fixed eval of def-function for crypt library. 31 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * Added interface to support USQL high-level rouines 29 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * Separated db-interface and conditions from sql/sql.cl * Improved foreign library loading testing * interfaces/postgresql/postgresql-api.cl Added PQisBusy function * interfaces/clsql-uffi/clsql-uffi.cl Fixed sign error for 64-bit processing 27 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * interfaces/postgresql-socket/postgresql-socket-api.cl: Fixes to read-double-from-socket. Added 64-bit integer support. * test-suite/xptest-clsql.cl Added testint for 64-bit integers * Additons to installation docs 26 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * interfaces/postgresql-socket/postgresql-socket-api.cl: Implemented direct socket reading for field type :double * Added usage information for :types to documentation * interfaces/mysql/mysql-sql.cl: Fixed type specifiers in atoi, atol, atof calls * interfaces/clsql-uffi: Created new directory. Split common interface routines that use UFFI into this package. Required especially to support direct reading of 64-bit integers into bignums and bypassing temporary strings. * test-clsql.cl: Updated to test postgresql-socket's read-double-from-socket function. * test-suite/xptest-clsql.cl Started work on test suite 25 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * interfaces/mysql/mysql-api.cl: Added mysql-fetch-fields, mysql-fetch-field-direct Got :auto types working * interfaces/postgresql/postgresql-api.cl * interfaces/postgresql-socket/postgresql-socket-api.cl Added pgsql-field-types enum. Got :auto types working. * multiple-files Renamed :field-types to :types. 24 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * Added field-types parameter to query, database-query, database-query-result-set, map-query. Haven't added code to utilize field types, yet. * Changed postgresql-socket result set from cons to a structure * Updated test-clsql.cl to use automated testing with a config file * Changed return types of field accessors from cstring to (* :unsigned-char). This prepares for being able to use specified type conversions when taking field data into lisp. * Added field-type processing for most interfaces. Not done yet. 23 Mar 2002 Kevin Rosenberg (kevin@rosenberg.net) * doc/ref.sgml: Updated MAP-QUERY example to use *read-default-float-format* (John Foderaro) * Extensive work to foreign library loaders and .system files to check for successful loading of foreign libraries. * Modified test-clsql.cl to allow more modularity and automated testing in future release. * mysql/mysql-sql.lisp: Added field types 01 Jan 2002 Kevin Rosenberg (kevin@rosenberg.net) * mysql/mysql-sql.lisp: - Added support for Allegro CL and Lispworks using UFFI layer - Changed database-connect to use mysql-real-connect. This way, can avoid using double (unwind-protect) - Changed database-connect to have MySQL library allocate space for MYSQL structure. This will make the code more robust in the event that MySQL library changes the size of the mysql-mysql structure. cl-sql-6.7.2/uffi/0000755000175000017500000000000014327126007012666 5ustar kevinkevincl-sql-6.7.2/uffi/Makefile.msvc0000644000175000017500000000154711335067642015311 0ustar kevinkevin# -*- Mode: Makefile -*- ########################################################################### # FILE IDENTIFICATION # # Name: Makefile.msvc # Purpose: Makefile for the CLSQL UFFI helper package (MSVC) # Author: Kevin M. Rosenberg # Created: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################### BASE=clsql_uffi # Nothing to configure beyond here SRC=$(BASE).c OBJ=$(BASE).obj DLL=$(BASE).dll $(DLL): $(SRC) cl /MD /LD -D_MT /DWIN32=1 /D__LCC__=1 $(SRC) del $(OBJ) $(BASE).exp clean: del /q $(DLL) $(BASE).LIB cl-sql-6.7.2/uffi/clsql-uffi-package.lisp0000644000175000017500000000207412303270414017212 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-uffi-package.cl ;;;; Purpose: Package definitions for common UFFI interface routines ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: Mar 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-uffi (:use #:cl #:uffi) (:export #:find-and-load-foreign-library #:canonicalize-type-list #:convert-raw-field #:atoi #:atol #:atof #:make-64-bit-integer #:make-128-bit-integer #:split-64-bit-integer) (:documentation "Common functions for interfaces using UFFI")) cl-sql-6.7.2/uffi/Makefile.32+64bits0000644000175000017500000000557311335067642015677 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL UFFI interface # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common PTRBITS:=$(shell gcc -o ptrbits ptrbits.c && ./ptrbits) base:=clsql_uffi basebits:=$(base) ifeq ($(PTRBITS),64) basebits:=$(base)64 endif source=$(base).c object=$(basebits).o shared_lib=$(basebits).so shared_lib32=$(base)32.so object32=$(base)32.o .PHONY: all ifeq ($(PTRBITS),64) all: $(shared_lib) $(shared_lib32) else all: $(shared_lib) endif $(shared_lib): $(source) Makefile ifneq ($(OS_AIX),0) gcc -c -D_BSD -D_NO_PROTO -D_NONSTD_TYPES -D_MBI=void $(source) make_shared -o $(shared_lib) $(object) else ifneq ($(OS_SUNOS),0) cc -KPIC -c $(source) -o $(object) cc -G $(object) -o $(shared_lib) else ifneq ($(OS_DARWIN),0) cc -dynamic -c $(source) -o $(object) ld -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress -o $(base).dylib $(object) ld -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress /usr/lib/libz.dylib -o z.dylib else ifneq ($(OS_CYGWIN),0) gcc -c $(source) -o $(object) ld -shared -soname=$(base) $(LDFLAGS) $(object) -o $(shared_lib) else gcc -fPIC -DPIC -c $(source) -o $(object) ld -shared -soname=$(base) -lc $(object) -o $(shared_lib) endif endif endif endif rm $(object) ifeq ($(PTRBITS),64) $(shared_lib32): $(source) Makefile ifneq ($(OS_AIX),0) gcc -m32 -c -D_BSD -D_NO_PROTO -D_NONSTD_TYPES -D_MBI=void $(source) -o ($object32) make_shared -o $(shared_lib32) $(object32) else ifneq ($(OS_SUNOS),0) cc -m32 -KPIC -c $(source) -o $(object32) cc -G $(object32) -o $(shared_lib32) else ifneq ($(OS_DARWIN),0) cc -m32 -dynamic -c $(source) -o $(object32) ld -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress -o $(base)32.dylib $(object32) ld -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress /usr/lib/libz32.dylib -o z.dylib else ifneq ($(OS_CYGWIN),0) gcc -m32 -c $(source) -o $(object32) ld -shared -soname=$(base) $(LDFLAGS) $(object32) -o $(shared_lib32) else gcc -m32 -fPIC -DPIC -c $(source) -o $(object32) ld -shared -soname=$(base) -L /lib32 -L /usr/lib32 -lc $(object32) -o $(shared_lib32) endif endif endif endif endif rm $(object32) .PHONY: distclean distclean: clean rm -f $(base).dylib $(base).dylib $(basebits).so $(base).o ptrbits cl-sql-6.7.2/uffi/clsql-uffi.lisp0000644000175000017500000001167712303270414015632 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-uffi.cl ;;;; Purpose: Common functions for interfaces using UFFI ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: Mar 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-uffi) (defun canonicalize-type-list (types auto-list) "Ensure a field type list meets expectations" (declare (optimize (speed 3) (safety 0))) (do ((i 0 (1+ i)) (new-types '()) (length-types (length types)) (length-auto-list (length auto-list))) ((= i length-auto-list) (nreverse new-types)) (declare (fixnum length-types length-auto-list i)) (if (>= i length-types) (push t new-types) ;; types is shorter than num-fields (push (case (nth i types) (:int (case (nth i auto-list) (:int32 :int32) (:int64 :int64) (t t))) (:double (case (nth i auto-list) (:double :double) (t t))) (:int32 (if (eq :int32 (nth i auto-list)) :int32 t)) (:int64 (if (eq :int64 (nth i auto-list)) :int64 t)) (:blob :blob) (:uint :uint) (t t)) new-types)))) (uffi:def-function "atoi" ((str (* :unsigned-char))) :returning :int) (uffi:def-function ("strtoul" c-strtoul) ((str (* :unsigned-char)) (endptr (* :unsigned-char)) (radix :int)) :returning :unsigned-long) #-windows (uffi:def-function ("strtoull" c-strtoull) ((str (* :unsigned-char)) (endptr (* :unsigned-char)) (radix :int)) :returning :unsigned-long-long) #-windows (uffi:def-function ("strtoll" c-strtoll) ((str (* :unsigned-char)) (endptr (* :unsigned-char)) (radix :int)) :returning :long-long) #+windows (uffi:def-function ("_strtoui64" c-strtoull) ((str (* :unsigned-char)) (endptr (* :unsigned-char)) (radix :int)) :returning :unsigned-long-long) #+windows (uffi:def-function ("_strtoi64" c-strtoll) ((str (* :unsigned-char)) (endptr (* :unsigned-char)) (radix :int)) :returning :long-long) (uffi:def-function "atol" ((str (* :unsigned-char))) :returning :long) (uffi:def-function "atof" ((str (* :unsigned-char))) :returning :double) (uffi:def-constant +2^32+ 4294967296) (uffi:def-constant +2^64+ 18446744073709551616) (uffi:def-constant +2^32-1+ (1- +2^32+)) (defmacro make-64-bit-integer (high32 low32) `(if (zerop (ldb (byte 1 31) ,high32)) (+ ,low32 (ash ,high32 32)) (- (+ ,low32 (ash ,high32 32)) +2^64+))) ;; From high to low ints (defmacro make-128-bit-integer (a b c d) `(+ ,d (ash ,c 32) (ash ,b 64) (ash ,a 96))) (defmacro split-64-bit-integer (int64) `(values (ash ,int64 -32) (logand ,int64 +2^32-1+))) (uffi:def-type char-ptr-def (* :unsigned-char)) (defun strtoul (char-ptr) (declare (optimize (speed 3) (safety 0) (space 0)) (type char-ptr-def char-ptr)) (c-strtoul char-ptr uffi:+null-cstring-pointer+ 10)) (defun strtoull (char-ptr) (declare (optimize (speed 3) (safety 0) (space 0)) (type char-ptr-def char-ptr)) (c-strtoull char-ptr uffi:+null-cstring-pointer+ 10)) (defun strtoll (char-ptr) (declare (optimize (speed 3) (safety 0) (space 0)) (type char-ptr-def char-ptr)) (c-strtoll char-ptr uffi:+null-cstring-pointer+ 10)) (defun convert-raw-field (char-ptr type &key length encoding) (declare (optimize (speed 3) (safety 0) (space 0)) (type char-ptr-def char-ptr)) (unless (uffi:null-pointer-p char-ptr) (case type (:double (atof char-ptr)) (:int (atol char-ptr)) (:int32 (atoi char-ptr)) (:uint32 (strtoul char-ptr)) (:uint (strtoul char-ptr)) (:int64 (strtoll char-ptr)) (:uint64 (strtoull char-ptr)) (:blob (if length (uffi:convert-from-foreign-usb8 char-ptr length) (error "Can't return blob since length is not specified."))) (t ;; NB: this used to manually expand the arg list based on if length and encoding ;; were provided. If this is required the macro is aweful and should be rewritten ;; to accept nil args (as it appears to) (uffi:convert-from-foreign-string char-ptr :null-terminated-p (null length) :length length :encoding encoding))))) cl-sql-6.7.2/uffi/clsql_uffi.lib0000644000175000017500000000317210667176647015532 0ustar kevinkevin! / 1086378685 0 118 ` v–Ê__IMPORT_DESCRIPTOR_uffi__NULL_IMPORT_DESCRIPTORuffi_NULL_THUNK_DATA__imp__atol64_atol64/ 1086378685 0 128 ` v–Ê__IMPORT_DESCRIPTOR_uffi__NULL_IMPORT_DESCRIPTOR__imp__atol64_atol64uffi_NULL_THUNK_DATAuffi.dll/ 1086378685 0 483 ` L½ÒÀ@.debug$S?Œ@B.idata$2Ëß@0À.idata$6 ýß@ À uffi.dll(  Microsoft (R) LINK uffi.dll@comp.id ]ÿÿ.idata$2@Àh.idata$6.idata$4@Àh.idata$5@Àh6L__IMPORT_DESCRIPTOR_uffi__NULL_IMPORT_DESCRIPTORuffi_NULL_THUNK_DATA uffi.dll/ 1086378685 0 248 ` L½ÒÀ@·.debug$S?d@B.idata$3£@0À uffi.dll(  Microsoft (R) LINK@comp.id ]ÿÿ__NULL_IMPORT_DESCRIPTORuffi.dll/ 1086378685 0 273 ` L½ÒÀ@Ó.debug$S?Œ@B.idata$5Ë@0À.idata$4Ï@0À uffi.dll(  Microsoft (R) LINK@comp.id ]ÿÿuffi_NULL_THUNK_DATA uffi.dll/ 1086378685 0 37 ` ÿÿL½ÒÀ@_atol64uffi.dll cl-sql-6.7.2/uffi/ptrbits.c0000644000175000017500000000026210667176647014543 0ustar kevinkevin/* Prints the number of bits in a pointer. * Copyright (c) 2006 Kevin Rosenberg */ #include int main() { char *p; printf ("%d\n", 8*sizeof(p)); return (0); } cl-sql-6.7.2/uffi/clsql_uffi.c0000644000175000017500000000333111335067642015166 0ustar kevinkevin/**************************************************************************** * FILE IDENTIFICATION * * Name: clsql-uffi.c * Purpose: Helper functions for common interfaces using UFFI * Programmer: Kevin M. Rosenberg * Date Started: Mar 2002 * * This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg * * CLSQL users are granted the rights to distribute and use this software * as governed by the terms of the Lisp Lesser GNU Public License * (http://opensource.franz.com/preamble.html), also known as the LLGPL. ***************************************************************************/ #if defined(WIN32)||defined(WIN64) #include BOOL WINAPI DllEntryPoint(HINSTANCE hinstdll, DWORD fdwReason, LPVOID lpvReserved) { return 1; } #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT #endif const unsigned int bitmask_32bits = 0xFFFFFFFF; #define lower_32bits(int64) ((unsigned int) int64 & bitmask_32bits) #define upper_32bits(int64) ((unsigned int) (int64 >> 32)) /* Reads a 64-bit integer string, returns result as two 32-bit integers */ DLLEXPORT unsigned int atol64 (const unsigned char* str, unsigned int* pHigh32) { #if defined(WIN32)||defined(WIN64) __int64 result = 0; #else long long result = 0; #endif int minus = 0; int first_char = *str; if (first_char == '+') ++str; else if (first_char == '-') { minus = 1; ++str; } while (*str) { int i = *str - '0'; if (i < 0 || i > 9) /* Non-numeric character -- quit */ break; result = i + (10 * result); str++; } if (minus) result = -result; *pHigh32 = upper_32bits(result); return lower_32bits(result); } cl-sql-6.7.2/uffi/clsql-uffi-loader.lisp0000644000175000017500000000472012303270414017065 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-uffi-loader.sql ;;;; Purpose: Library loader using CLSQL UFFI helper library ;;;; Author: Kevin M. Rosenberg ;;;; Created: Mar 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-uffi) (defun find-and-load-foreign-library (filenames &key module supporting-libraries (errorp t)) "Attempt to load a foreign library. This will search for any of the filenames, as well as any of the filenames in any of the clsql:*foreign-library-search-paths*" (setq filenames (if (listp filenames) filenames (list filenames))) (flet ((try-load (testpath) (handler-case (uffi:load-foreign-library testpath :module module :supporting-libraries supporting-libraries) (error nil)))) ;(c) (warn "~A" c) nil)))) (or (loop for type in (uffi:foreign-library-types) thereis (loop for name in filenames for pn = (make-pathname :name name :type type) thereis (or (try-load pn) (loop for search-path in clsql:*foreign-library-search-paths* thereis (try-load (merge-pathnames pn search-path)))))) (when errorp (error "Couldn't load foreign librar~@P ~{~S~^, ~}. (searched ~S: ~S)" (length filenames) filenames 'clsql:*foreign-library-search-paths* clsql:*foreign-library-search-paths*))))) ;; searches clsql_uffi64 to accomodate both 32-bit and 64-bit libraries on same system (defvar *clsql-uffi-library-filenames* `(,@(when (> most-positive-fixnum (expt 2 32)) (list "clsql_uffi64")) "clsql_uffi")) (defvar *clsql-uffi-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the MySQL client library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") cl-sql-6.7.2/uffi/Makefile0000644000175000017500000000501614327124552014333 0ustar kevinkevin#!/usr/bin/make # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL UFFI interface # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2006 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. SUBDIRS= include ../Makefile.common base=clsql_uffi source=$(base).c object=$(base).o shared_lib=$(base).so shared64_lib=$(base)64.so dylib=$(base).dylib ifneq ($(OS_DPKG_BUILDFLAGS),0) CFLAGS:=$(CFLAGS) $(shell dpkg-buildflags --get CFLAGS) LDFLAGS:=$(LDFLAGS) $(shell DEB_BUILD_MAINT_OPTIONS=hardening=+all,-pie dpkg-buildflags --get LDFLAGS | sed "s/-Wl\|,/ /ig") endif .PHONY: all all: $(shared_lib) $(shared_lib): $(source) Makefile ifneq ($(OS_AIX),0) gcc -c -D_BSD -D_NO_PROTO -D_NONSTD_TYPES -D_MBI=void $(source) make_shared -o $(shared_lib) $(object) else ifneq ($(OS_SUNOS),0) cc -KPIC -c $(source) -o $(object) cc -G $(object) -o $(shared_lib) else ifneq ($(OS_DARWIN64),0) cc -arch x86_64 -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress $(source) -o $(dylib) cc -arch x86_64 -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress /usr/lib/libz.dylib -o z.dylib else ifneq ($(OS_DARWIN),0) cc -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress $(source) -o $(dylib) cc -arch i386 -bundle /usr/lib/bundle1.o -flat_namespace -undefined suppress /usr/lib/libz.dylib -o z.dylib else ifneq ($(OS_CYGWIN),0) gcc -c $(source) -o $(object) ld -shared -soname=$(base) $(LDFLAGS) $(object) -o $(shared_lib) else ifneq ($(OS_LINUX64),0) gcc $(CFLAGS) -fPIC -DPIC -c $(source) -o $(object) gcc $(LDFLAGS) -fPIC -shared -Wl,-soname=$(base) -lc $(object) -o $(shared64_lib) rm -f $(object) #@echo "Ensure that you have multiarch i386 build tools if you want to build 32-bit library" #-gcc -m32 $(CFLAGS) -fPIC -DPIC -c $(source) -o $(object) #-gcc -m32 $(LDFLAGS) -fPIC -shared -Wl,-soname=$(base) -lc $(object) -o $(shared_lib) else gcc -fPIC -DPIC -c $(source) -o $(object) ld -shared -soname=$(base) -lc $(object) -o $(shared_lib) endif endif endif endif endif endif rm -f $(object) .PHONY: distclean distclean: clean @rm -f $(dylib) $(shared_lib) $(shared64_lib) $(object) z.dylib cl-sql-6.7.2/clsql-tests.asd0000644000175000017500000000362211616055736014717 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; File: clsql-tests.asd ;;;; Authors: Marcus Pearce and Kevin Rosenberg ;;;; Created: 30/03/2004 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-tests-system (:use #:asdf #:cl)) (in-package #:clsql-tests-system) (eval-when (:compile-toplevel :load-toplevel :execute) (unless (find-package '#:uffi) (asdf:operate 'asdf:load-op 'uffi))) (defsystem clsql-tests :name "CLSQL Tests" :author "" :maintainer "" :version "" :licence "" :description "A regression test suite for CLSQL." :depends-on (clsql rt) :components ((:module tests :serial t :components ((:file "package") (:file "utils") (:file "test-init") (:file "datasets") (:file "ds-employees") (:file "ds-nodes") (:file "ds-artists") (:file "benchmarks") (:file "test-internal") (:file "test-basic") (:file "test-time") (:file "test-connection") (:file "test-fddl") (:file "test-fdml") (:file "test-ooddl") (:file "test-oodml") (:file "test-syntax") (:file "test-pool") ; #-uffi:no-i18n (:file "test-i18n") )))) (defmethod perform ((o test-op) (c (eql (find-system 'clsql-tests)))) (operate 'load-op 'clsql) (unless (funcall (intern (symbol-name '#:run-tests) (find-package '#:clsql-tests))) (error "test-op failed"))) cl-sql-6.7.2/clsql-db2.asd0000644000175000017500000000310311332141035014175 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-db2.asd ;;;; Purpose: ASDF definition file for CLSQL Db2 backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-db2-system (:use #:asdf #:cl)) (in-package #:clsql-db2-system) ;;; System definition (defsystem clsql-db2 :name "clsql-db2" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL Db2 Driver" :long-description "cl-sql-db2 package provides a database driver to the Db2 database system." :depends-on (clsql-uffi) :components ((:module :db-db2 :components ((:file "db2-package") (:file "db2-loader" :depends-on ("db2-package")) (:file "foreign-resources" :depends-on ("db2-package")) (:file "db2-constants" :depends-on ("db2-package")) (:file "db2-api" :depends-on ("db2-constants" "db2-loader")) (:file "db2-sql" :depends-on ("db2-api" "foreign-resources")) (:file "db2-objects" :depends-on ("db2-sql")))))) cl-sql-6.7.2/db-postgresql/0000755000175000017500000000000014327126007014523 5ustar kevinkevincl-sql-6.7.2/db-postgresql/postgresql-package.lisp0000644000175000017500000000450711335067642021223 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-package.cl ;;;; Purpose: Package definition for low-level PostgreSQL interface ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:pgsql #-(and :lispworks (not :lispworks4)) (:nicknames #:postgresql) (:use #:cl #:clsql-uffi) (:export #:pgsql-oid #:pgsql-conn-status-type #:pgsql-conn-status-type#connection-ok #:pgsql-conn-status-type#connection-bad #:pgsql-exec-status-type #:pgsql-exec-status-type#empty-query #:pgsql-exec-status-type#command-ok #:pgsql-exec-status-type#tuples-ok #:pgsql-exec-status-type#copy-out #:pgsql-exec-status-type#copy-in #:pgsql-exec-status-type#bad-response #:pgsql-exec-status-type#nonfatal-error #:pgsql-exec-status-type#fatal-error #:pgsql-conn #:pgsql-result #:pgsql-ftype#bytea #:pgsql-ftype#int2 #:pgsql-ftype#int4 #:pgsql-ftype#int8 #:pgsql-ftype#float4 #:pgsql-ftype#float8 ;; Used by PQresultErrorField to get the sql error code #:+PG-DIAG-SQLSTATE+ ;; Functions #:PQsetdbLogin #:PQlogin #:PQfinish #:PQstatus #:PQerrorMessage #:PQexec #:PQresultStatus #:PQresultErrorField ; used to grab the SQLSTATE code from an error #:PQresultErrorMessage #:PQntuples #:PQnfields #:PQfname #:PQfnumber #:PQftype #:PQfsize #:PQcmdStatus #:PQoidStatus #:PQcmdTuples #:PQgetvalue #:PQgetlength #:PQgetisnull #:PQclear #:PQisBusy ;;Large Objects (Marc B) #:lo-create #:lo-open #:lo-write #:lo-read #:lo-lseek #:lo-close #:lo-unlink ) (:documentation "This is the low-level interface to PostgreSQL.")) cl-sql-6.7.2/db-postgresql/postgresql-sql.lisp0000644000175000017500000004351111544475457020436 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-sql.lisp ;;;; Purpose: High-level PostgreSQL interface using UFFI ;;;; Date Started: Feb 2002 ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-postgresql (:use #:common-lisp #:clsql-sys #:pgsql #:clsql-uffi) (:export #:postgresql-database) (:documentation "This is the CLSQL interface to PostgreSQL.")) (in-package #:clsql-postgresql) ;;; Field conversion functions (defun make-type-list-for-auto (num-fields res-ptr) (let ((new-types '())) (dotimes (i num-fields) (declare (fixnum i)) (let* ((type (PQftype res-ptr i))) (push (case type ((#.pgsql-ftype#bytea #.pgsql-ftype#int2 #.pgsql-ftype#int4) :int32) (#.pgsql-ftype#int8 :int64) ((#.pgsql-ftype#float4 #.pgsql-ftype#float8) :double) (otherwise t)) new-types))) (nreverse new-types))) (defun canonicalize-types (types num-fields res-ptr) (if (null types) nil (let ((auto-list (make-type-list-for-auto num-fields res-ptr))) (cond ((listp types) (canonicalize-type-list types auto-list)) ((eq types :auto) auto-list) (t nil))))) (defun tidy-error-message (message &optional encoding) (unless (stringp message) (setq message (uffi:convert-from-foreign-string message :encoding encoding))) (let ((message (string-right-trim '(#\Return #\Newline) message))) (cond ((< (length message) (length "ERROR:")) message) ((string= message "ERROR:" :end1 6) (string-left-trim '(#\Space) (subseq message 6))) (t message)))) (defmethod database-initialize-database-type ((database-type (eql :postgresql))) t) (uffi:def-type pgsql-conn-def pgsql-conn) (uffi:def-type pgsql-result-def pgsql-result) (defclass postgresql-database (generic-postgresql-database) ((conn-ptr :accessor database-conn-ptr :initarg :conn-ptr :type pgsql-conn-def) (lock :accessor database-lock :initform (make-process-lock "conn")))) (defmethod database-type ((database postgresql-database)) :postgresql) (defmethod database-name-from-spec (connection-spec (database-type (eql :postgresql))) (check-connection-spec connection-spec database-type (host db user password &optional port options tty)) (destructuring-bind (host db user password &optional port options tty) connection-spec (declare (ignore password options tty)) (concatenate 'string (etypecase host (null "localhost") (pathname (namestring host)) (string host)) (when port (concatenate 'string ":" (etypecase port (integer (write-to-string port)) (string port)))) "/" db "/" user))) (defmethod database-connect (connection-spec (database-type (eql :postgresql))) (check-connection-spec connection-spec database-type (host db user password &optional port options tty)) (destructuring-bind (host db user password &optional port options tty) connection-spec (uffi:with-cstrings ((host-native host) (user-native user) (password-native password) (db-native db) (port-native port) (options-native options) (tty-native tty)) (let ((connection (PQsetdbLogin host-native port-native options-native tty-native db-native user-native password-native))) (declare (type pgsql-conn-def connection)) (when (not (eq (PQstatus connection) pgsql-conn-status-type#connection-ok)) (let ((pqstatus (PQstatus connection)) (pqmessage (tidy-error-message (PQerrorMessage connection)))) (PQfinish connection) (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id pqstatus :message pqmessage))) (make-instance 'postgresql-database :name (database-name-from-spec connection-spec database-type) :database-type :postgresql :connection-spec connection-spec :conn-ptr connection))))) (defmethod database-disconnect ((database postgresql-database)) (PQfinish (database-conn-ptr database)) (setf (database-conn-ptr database) nil) t) (defmethod database-query (query-expression (database postgresql-database) result-types field-names) (let ((conn-ptr (database-conn-ptr database))) (declare (type pgsql-conn-def conn-ptr)) (uffi:with-cstring (query-native query-expression) (let ((result (PQexec conn-ptr query-native))) (when (uffi:null-pointer-p result) (error 'sql-database-data-error :database database :expression query-expression :message (tidy-error-message (PQerrorMessage conn-ptr) (encoding database)))) (unwind-protect (case (PQresultStatus result) ;; User gave a command rather than a query (#.pgsql-exec-status-type#command-ok nil) (#.pgsql-exec-status-type#empty-query nil) (#.pgsql-exec-status-type#tuples-ok (let ((num-fields (PQnfields result))) (when result-types (setq result-types (canonicalize-types result-types num-fields result))) (let ((res (loop for tuple-index from 0 below (PQntuples result) collect (loop for i from 0 below num-fields collect (if (zerop (PQgetisnull result tuple-index i)) (convert-raw-field (PQgetvalue result tuple-index i) (nth i result-types) :encoding (encoding database)) nil))))) (if field-names (values res (result-field-names num-fields result)) res)))) (t (error 'sql-database-data-error :database database :expression query-expression :error-id (PQresultErrorField result +PG-DIAG-SQLSTATE+) :message (tidy-error-message (PQresultErrorMessage result) (encoding database))))) (PQclear result)))))) (defun result-field-names (num-fields result) "Return list of result field names." (let ((names '())) (dotimes (i num-fields (nreverse names)) (declare (fixnum i)) (push (uffi:convert-from-cstring (PQfname result i)) names)))) (defmethod database-execute-command (sql-expression (database postgresql-database)) (let ((conn-ptr (database-conn-ptr database))) (declare (type pgsql-conn-def conn-ptr)) (uffi:with-cstring (sql-native sql-expression) (let ((result (PQexec conn-ptr sql-native))) (when (uffi:null-pointer-p result) (error 'sql-database-data-error :database database :expression sql-expression :message (tidy-error-message (PQerrorMessage conn-ptr) (encoding database)))) (unwind-protect (case (PQresultStatus result) (#.pgsql-exec-status-type#command-ok t) ((#.pgsql-exec-status-type#empty-query #.pgsql-exec-status-type#tuples-ok) (warn "Strange result...") t) (t (error 'sql-database-data-error :database database :expression sql-expression :error-id (PQresultErrorField result +PG-DIAG-SQLSTATE+) :message (tidy-error-message (PQresultErrorMessage result) (encoding database))))) (PQclear result)))))) (defstruct postgresql-result-set (res-ptr (uffi:make-null-pointer 'pgsql-result) :type pgsql-result-def) (types nil) (num-tuples 0 :type integer) (num-fields 0 :type integer) (tuple-index 0 :type integer)) (defmethod database-query-result-set ((query-expression string) (database postgresql-database) &key full-set result-types) (let ((conn-ptr (database-conn-ptr database))) (declare (type pgsql-conn-def conn-ptr)) (uffi:with-cstring (query-native query-expression) (let ((result (PQexec conn-ptr query-native))) (when (uffi:null-pointer-p result) (error 'sql-database-data-error :database database :expression query-expression :message (tidy-error-message (PQerrorMessage conn-ptr) (encoding database)))) (case (PQresultStatus result) ((#.pgsql-exec-status-type#empty-query #.pgsql-exec-status-type#tuples-ok) (let ((result-set (make-postgresql-result-set :res-ptr result :num-fields (PQnfields result) :num-tuples (PQntuples result) :types (canonicalize-types result-types (PQnfields result) result)))) (if full-set (values result-set (PQnfields result) (PQntuples result)) (values result-set (PQnfields result))))) (t (unwind-protect (error 'sql-database-data-error :database database :expression query-expression :error-id (PQresultErrorField result +PG-DIAG-SQLSTATE+) :message (tidy-error-message (PQresultErrorMessage result) (encoding database))) (PQclear result)))))))) (defmethod database-dump-result-set (result-set (database postgresql-database)) (let ((res-ptr (postgresql-result-set-res-ptr result-set))) (declare (type pgsql-result-def res-ptr)) (PQclear res-ptr) t)) (defmethod database-store-next-row (result-set (database postgresql-database) list) (let ((result (postgresql-result-set-res-ptr result-set)) (types (postgresql-result-set-types result-set))) (declare (type pgsql-result-def result)) (if (>= (postgresql-result-set-tuple-index result-set) (postgresql-result-set-num-tuples result-set)) nil (loop with tuple-index = (postgresql-result-set-tuple-index result-set) for i from 0 below (postgresql-result-set-num-fields result-set) for rest on list do (setf (car rest) (if (zerop (PQgetisnull result tuple-index i)) (convert-raw-field (PQgetvalue result tuple-index i) (nth i types) :encoding (encoding database)) nil)) finally (incf (postgresql-result-set-tuple-index result-set)) (return list))))) ;;; Large objects support (Marc B) (defmethod database-create-large-object ((database postgresql-database)) (lo-create (database-conn-ptr database) (logior pgsql::+INV_WRITE+ pgsql::+INV_READ+))) #+mb-original (defmethod database-write-large-object (object-id (data string) (database postgresql-database)) (let ((ptr (database-conn-ptr database)) (length (length data)) (result nil) (fd nil)) (with-transaction (:database database) (unwind-protect (progn (setf fd (lo-open ptr object-id pgsql::+INV_WRITE+)) (when (>= fd 0) (when (= (lo-write ptr fd data length) length) (setf result t)))) (progn (when (and fd (>= fd 0)) (lo-close ptr fd)) ))) result)) (defmethod database-write-large-object (object-id (data string) (database postgresql-database)) (let ((ptr (database-conn-ptr database)) (length (length data)) (result nil) (fd nil)) (database-execute-command "begin" database) (unwind-protect (progn (setf fd (lo-open ptr object-id pgsql::+INV_WRITE+)) (when (>= fd 0) (when (= (lo-write ptr fd data length) length) (setf result t)))) (progn (when (and fd (>= fd 0)) (lo-close ptr fd)) (database-execute-command (if result "commit" "rollback") database))) result)) ;; (MB) the begin/commit/rollback stuff will be removed when with-transaction wil be implemented ;; (KMR) Can't use with-transaction since that function is in high-level code (defmethod database-read-large-object (object-id (database postgresql-database)) (let ((ptr (database-conn-ptr database)) (buffer nil) (result nil) (length 0) (fd nil)) (unwind-protect (progn (database-execute-command "begin" database) (setf fd (lo-open ptr object-id pgsql::+INV_READ+)) (when (>= fd 0) (setf length (lo-lseek ptr fd 0 2)) (lo-lseek ptr fd 0 0) (when (> length 0) (setf buffer (uffi:allocate-foreign-string length :unsigned t)) (when (= (lo-read ptr fd buffer length) length) (setf result (uffi:convert-from-foreign-string buffer :length length :null-terminated-p nil :encoding (encoding database))))))) (progn (when buffer (uffi:free-foreign-object buffer)) (when (and fd (>= fd 0)) (lo-close ptr fd)) (database-execute-command (if result "commit" "rollback") database))) result)) (defmethod database-delete-large-object (object-id (database postgresql-database)) (lo-unlink (database-conn-ptr database) object-id)) ;;; Object listing (defmethod database-create (connection-spec (type (eql :postgresql))) (destructuring-bind (host name user password) connection-spec (let ((database (database-connect (list host "postgres" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "create database ~A" name) database) (database-disconnect database))))) (defmethod database-destroy (connection-spec (type (eql :postgresql))) (destructuring-bind (host name user password) connection-spec (let ((database (database-connect (list host "postgres" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "drop database ~A" name) database) (database-disconnect database))))) (defmethod database-probe (connection-spec (type (eql :postgresql))) (when (find (second connection-spec) (database-list connection-spec type) :test #'string-equal) t)) (defun %pg-database-connection (connection-spec) (check-connection-spec connection-spec :postgresql (host db user password &optional port options tty)) (macrolet ((coerce-string (var) `(unless (typep ,var 'simple-base-string) (setf ,var (coerce ,var 'simple-base-string))))) (destructuring-bind (host db user password &optional port options tty) connection-spec (coerce-string db) (coerce-string user) (let ((connection (PQsetdbLogin host port options tty db user password))) (declare (type pgsql::pgsql-conn-ptr connection)) (unless (eq (PQstatus connection) pgsql-conn-status-type#connection-ok) ;; Connect failed (error 'sql-connection-error :database-type :postgresql :connection-spec connection-spec :error-id (PQstatus connection) :message (PQerrorMessage connection))) connection)))) (defmethod database-reconnect ((database postgresql-database)) (let ((lock (database-lock database))) (with-process-lock (lock "Reconnecting") (with-slots (connection-spec conn-ptr) database (setf conn-ptr (%pg-database-connection connection-spec)) database)))) ;;; Database capabilities (when (clsql-sys:database-type-library-loaded :postgresql) (clsql-sys:initialize-database-type :database-type :postgresql)) cl-sql-6.7.2/db-postgresql/postgresql-api.lisp0000644000175000017500000001763011335067642020402 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql.cl ;;;; Purpose: Low-level PostgreSQL interface using UFFI ;;;; Programmers: Kevin M. Rosenberg based on ;;;; Original code by Pierre R. Mai ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:pgsql) ;;;; This file implements as little of the FFI bindings to the ;;;; PostgreSQL client libraries as we could get away with. ;;;; Especially all the PostgreSQL-specific goodies aren't there, and ;;;; we just use void pointers where we can get away with it, which ;;;; thanks to the design of the PostgreSQL client libraries is pretty ;;;; much everywhere, in contrast to the MySQL client libraries for ;;;; example. ;;;; Type definitions ;;; Basic Types (uffi:def-foreign-type pgsql-oid :unsigned-int) (uffi:def-enum pgsql-conn-status-type (:connection-ok :connection-bad)) (uffi:def-enum pgsql-exec-status-type (:empty-query :command-ok :tuples-ok :copy-out :copy-in :bad-response :nonfatal-error :fatal-error)) (uffi:def-foreign-type pgsql-conn :pointer-void) (uffi:def-foreign-type pgsql-result :pointer-void) (uffi:def-type pgsql-conn-ptr :pointer-void) (uffi:def-enum pgsql-ftype ((:bytea 17) (:int2 21) (:int4 23) (:int8 20) (:float4 700) (:float8 701))) ;;(declaim (inline PQsetdbLogin)) ;; causes compile error in LW 4.2.0 (uffi:def-function ("PQsetdbLogin" PQsetdbLogin) ((pghost :cstring) (pgport :cstring) (pgoptions :cstring) (pgtty :cstring) (dbName :cstring) (login :cstring) (pwd :cstring)) :module "postgresql" :returning pgsql-conn) (declaim (inline PQfinish)) (uffi:def-function ("PQfinish" PQfinish) ((conn pgsql-conn)) :module "postgresql" :returning :void) (declaim (inline PQstatus)) (uffi:def-function ("PQstatus" PQstatus) ((conn pgsql-conn)) :module "postgresql" :returning pgsql-conn-status-type) (declaim (inline PQerrorMessage)) (uffi:def-function ("PQerrorMessage" PQerrorMessage) ((conn pgsql-conn)) :module "postgresql" :returning :cstring) (declaim (inline PQexec)) (uffi:def-function ("PQexec" PQexec) ((conn pgsql-conn) (query :cstring)) :module "postgresql" :returning pgsql-result) (declaim (inline PQresultStatus)) (uffi:def-function ("PQresultStatus" PQresultStatus) ((res pgsql-result)) :module "postgresql" :returning pgsql-exec-status-type) ; From postgres_ext.h ; #define PG_DIAG_SEVERITY 'S' ; #define PG_DIAG_SQLSTATE 'C' ; #define PG_DIAG_MESSAGE_PRIMARY 'M' ; #define PG_DIAG_MESSAGE_DETAIL 'D' ; #define PG_DIAG_MESSAGE_HINT 'H' ; #define PG_DIAG_STATEMENT_POSITION 'P' ; #define PG_DIAG_INTERNAL_POSITION 'p' ; #define PG_DIAG_INTERNAL_QUERY 'q' ; #define PG_DIAG_CONTEXT 'W' ; #define PG_DIAG_SOURCE_FILE 'F' ; #define PG_DIAG_SOURCE_LINE 'L' ; #define PG_DIAG_SOURCE_FUNCTION 'R' (defconstant +PG-DIAG-SEVERITY+ (char-code #\S)) (defconstant +PG-DIAG-SQLSTATE+ (char-code #\C)) (defconstant +PG-DIAG-MESSAGE-PRIMARY+ (char-code #\M)) (defconstant +PG-DIAG-MESSAGE-DETAIL+ (char-code #\D)) (defconstant +PG-DIAG-MESSAGE-HINT+ (char-code #\H)) (defconstant +PG-DIAG-STATEMENT-POSITION+ (char-code #\P)) (defconstant +PG-DIAG-INTERNAL-POSITION+ (char-code #\p)) (defconstant +PG-DIAG-INTERNAL-QUERY+ (char-code #\q)) (defconstant +PG-DIAG-CONTEXT+ (char-code #\W)) (defconstant +PG-DIAG-SOURCE-FILE+ (char-code #\F)) (defconstant +PG-DIAG-SOURCE-LINE+ (char-code #\L)) (defconstant +PG-DIAG-SOURCE-FUNCTION+ (char-code #\R)) ; PQresultErrorField can return diagnostic information about an error (declaim (inline PQresultErrorField)) (uffi:def-function ("PQresultErrorField" PQresultErrorField) ((res pgsql-result) (field-code :int)) :module "postgresql" :returning :cstring) (declaim (inline PQresultErrorMessage)) (uffi:def-function ("PQresultErrorMessage" PQresultErrorMessage) ((res pgsql-result)) :module "postgresql" :returning :cstring) (declaim (inline PQntuples)) (uffi:def-function ("PQntuples" PQntuples) ((res pgsql-result)) :module "postgresql" :returning :int) (declaim (inline PQnfields)) (uffi:def-function ("PQnfields" PQnfields) ((res pgsql-result)) :module "postgresql" :returning :int) (declaim (inline PQfname)) (uffi:def-function ("PQfname" PQfname) ((res pgsql-result) (field-num :int)) :module "postgresql" :returning :cstring) (declaim (inline PQfnumber)) (uffi:def-function ("PQfnumber" PQfnumber) ((res pgsql-result) (field-name :cstring)) :module "postgresql" :returning :int) (declaim (inline PQftype)) (uffi:def-function ("PQftype" PQftype) ((res pgsql-result) (field-num :int)) :module "postgresql" :returning pgsql-oid) (declaim (inline PQfsize)) (uffi:def-function ("PQfsize" PQfsize) ((res pgsql-result) (field-num :int)) :module "postgresql" :returning :short) (declaim (inline PQcmdStatus)) (uffi:def-function ("PQcmdStatus" PQcmdStatus) ((res pgsql-result)) :module "postgresql" :returning :cstring) (declaim (inline PQoidStatus)) (uffi:def-function ("PQoidStatus" PQoidStatus) ((res pgsql-result)) :module "postgresql" :returning :cstring) (declaim (inline PQcmdTuples)) (uffi:def-function ("PQcmdTuples" PQcmdTuples) ((res pgsql-result)) :module "postgresql" :returning :cstring) (declaim (inline PQgetvalue)) (uffi:def-function ("PQgetvalue" PQgetvalue) ((res pgsql-result) (tup-num :int) (field-num :int)) :module "postgresql" :returning (* :unsigned-char)) (declaim (inline PQgetlength)) (uffi:def-function ("PQgetlength" PQgetlength) ((res pgsql-result) (tup-num :int) (field-num :int)) :module "postgresql" :returning :int) (declaim (inline PQgetisnull)) (uffi:def-function ("PQgetisnull" PQgetisnull) ((res pgsql-result) (tup-num :int) (field-num :int)) :module "postgresql" :returning :int) (declaim (inline PQclear)) (uffi:def-function ("PQclear" PQclear) ((res pgsql-result)) :module "postgresql" :returning :void) (declaim (inline PQisBusy)) (uffi:def-function ("PQisBusy" PQisBusy) ((conn pgsql-conn)) :module "postgresql" :returning :int) ;;; Large objects support (MB) (defconstant +INV_ARCHIVE+ 65536) ; fe-lobj.c (defconstant +INV_WRITE+ 131072) (defconstant +INV_READ+ 262144) (declaim (inline lo-creat)) (uffi:def-function ("lo_creat" lo-create) ((conn pgsql-conn) (mode :int)) :module "postgresql" :returning pgsql-oid) (declaim (inline lo-open)) (uffi:def-function ("lo_open" lo-open) ((conn pgsql-conn) (oid pgsql-oid) (mode :int)) :module "postgresql" :returning :int) (declaim (inline lo-write)) (uffi:def-function ("lo_write" lo-write) ((conn pgsql-conn) (fd :int) (data :cstring) (size :int)) :module "postgresql" :returning :int) (declaim (inline lo-read)) (uffi:def-function ("lo_read" lo-read) ((conn pgsql-conn) (fd :int) (data (* :unsigned-char)) (size :int)) :module "postgresql" :returning :int) (declaim (inline lo-lseek)) (uffi:def-function ("lo_lseek" lo-lseek) ((conn pgsql-conn) (fd :int) (offset :int) (whence :int)) :module "postgresql" :returning :int) (declaim (inline lo-close)) (uffi:def-function ("lo_close" lo-close) ((conn pgsql-conn) (fd :int)) :module "postgresql" :returning :int) (declaim (inline lo-unlink)) (uffi:def-function ("lo_unlink" lo-unlink) ((conn pgsql-conn) (oid pgsql-oid)) :module "postgresql" :returning :int) cl-sql-6.7.2/db-postgresql/postgresql-loader.lisp0000644000175000017500000000330611335067642021072 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-loader.sql ;;;; Purpose: PostgreSQL library loader using UFFI ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:pgsql) (defvar *postgresql-supporting-libraries* '("crypt" "c") "Used only by CMU. List of library flags needed to be passed to ld to load the PostgresSQL client library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *postgresql-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :postgresql))) *postgresql-library-loaded*) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :postgresql))) (clsql-uffi:find-and-load-foreign-library "libpq" :module "postgresql" :supporting-libraries *postgresql-supporting-libraries*) (setq *postgresql-library-loaded* t)) (clsql-sys:database-type-load-foreign :postgresql) cl-sql-6.7.2/db-postgresql/Makefile0000644000175000017500000000011510667176647016202 0ustar kevinkevinSUBDIRS := include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/INSTALL0000644000175000017500000000024510667176647013011 0ustar kevinkevinRefer to the main documentation file for installation instructions. Documentation is availabe as a PDF file in doc/clsql.pdf and as HTML files in doc/html.tar.gz. cl-sql-6.7.2/db-sqlite3/0000755000175000017500000000000014327126007013704 5ustar kevinkevincl-sql-6.7.2/db-sqlite3/sqlite3-api.lisp0000644000175000017500000003137112021503403016721 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite3-api.lisp ;;;; Purpose: Low-level SQLite3 interface using UFFI ;;;; Authors: Aurelio Bignoli ;;;; Created: Oct 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:sqlite3 (:use #:common-lisp #:uffi) (:export ;;; Conditions #:sqlite3-error #:sqlite3-error-code #:sqlite3-error-message ;;; API functions. #:sqlite3-open #:sqlite3-close #:sqlite3-prepare #:sqlite3-step #:sqlite3-finalize #:sqlite3-column-count #:sqlite3-column-name #:sqlite3-column-type #:sqlite3-column-text #:sqlite3-column-bytes #:sqlite3-column-blob ;;; Types. #:sqlite3-db #:sqlite3-db-type #:sqlite3-stmt-type #:unsigned-char-ptr-type #:null-stmt ;;; Columnt types. #:SQLITE-INTEGER #:SQLITE-FLOAT #:SQLITE-TEXT #:SQLITE-BLOB #:SQLITE-NULL)) (in-package #:sqlite3) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Return values for sqlite_exec() and sqlite_step() ;;;; (defconstant SQLITE-OK 0 "Successful result") (defconstant SQLITE-ERROR 1 "SQL error or missing database") (defconstant SQLITE-INTERNAL 2 "An internal logic error in SQLite") (defconstant SQLITE-PERM 3 "Access permission denied") (defconstant SQLITE-ABORT 4 "Callback routine requested an abort") (defconstant SQLITE-BUSY 5 "The database file is locked") (defconstant SQLITE-LOCKED 6 "A table in the database is locked") (defconstant SQLITE-NOMEM 7 "A malloc() failed") (defconstant SQLITE-READONLY 8 "Attempt to write a readonly database") (defconstant SQLITE-INTERRUPT 9 "Operation terminated by sqlite3_interrupt()") (defconstant SQLITE-IOERR 10 "Some kind of disk I/O error occurred") (defconstant SQLITE-CORRUPT 11 "The database disk image is malformed") (defconstant SQLITE-NOTFOUND 12 "(Internal Only) Table or record not found") (defconstant SQLITE-FULL 13 "Insertion failed because database is full") (defconstant SQLITE-CANTOPEN 14 "Unable to open the database file") (defconstant SQLITE-PROTOCOL 15 "Database lock protocol error") (defconstant SQLITE-EMPTY 16 "Database is empty") (defconstant SQLITE-SCHEMA 17 "The database schema changed") (defconstant SQLITE-TOOBIG 18 "Too much data for one row of a table") (defconstant SQLITE-CONSTRAINT 19 "Abort due to contraint violation") (defconstant SQLITE-MISMATCH 20 "Data type mismatch") (defconstant SQLITE-MISUSE 21 "Library used incorrectly") (defconstant SQLITE-NOLFS 22 "Uses OS features not supported on host") (defconstant SQLITE-AUTH 23 "Authorization denied") (defconstant SQLITE-FORMAT 24 "Auxiliary database format error") (defconstant SQLITE-RANGE 25 "2nd parameter to sqlite3_bind out of range") (defconstant SQLITE-NOTADB 26 "File opened that is not a database file") (defconstant SQLITE-ROW 100 "sqlite3_step() has another row ready") (defconstant SQLITE-DONE 101 "sqlite3_step() has finished executing") (defparameter error-codes (list (cons SQLITE-OK "not an error") (cons SQLITE-ERROR "SQL logic error or missing database") (cons SQLITE-INTERNAL "internal SQLite implementation flaw") (cons SQLITE-PERM "access permission denied") (cons SQLITE-ABORT "callback requested query abort") (cons SQLITE-BUSY "database is locked") (cons SQLITE-LOCKED "database table is locked") (cons SQLITE-NOMEM "out of memory") (cons SQLITE-READONLY "attempt to write a readonly database") (cons SQLITE-INTERRUPT "interrupted") (cons SQLITE-IOERR "disk I/O error") (cons SQLITE-CORRUPT "database disk image is malformed") (cons SQLITE-NOTFOUND "table or record not found") (cons SQLITE-FULL "database is full") (cons SQLITE-CANTOPEN "unable to open database file") (cons SQLITE-PROTOCOL "database locking protocol failure") (cons SQLITE-EMPTY "table contains no data") (cons SQLITE-SCHEMA "database schema has changed") (cons SQLITE-TOOBIG "too much data for one table row") (cons SQLITE-CONSTRAINT "constraint failed") (cons SQLITE-MISMATCH "datatype mismatch") (cons SQLITE-MISUSE "library routine called out of sequence") (cons SQLITE-NOLFS "kernel lacks large file support") (cons SQLITE-AUTH "authorization denied") (cons SQLITE-FORMAT "auxiliary database format error") (cons SQLITE-RANGE "bind index out of range") (cons SQLITE-NOTADB "file is encrypted or is not a database")) "Association list of error messages.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Column types. ;;;; (defconstant SQLITE-INTEGER 1) (defconstant SQLITE-FLOAT 2) (defconstant SQLITE-TEXT 3) (defconstant SQLITE-BLOB 4) (defconstant SQLITE-NULL 5) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Foreign types definitions. ;;;; (def-foreign-type sqlite3-db :pointer-void) (def-foreign-type sqlite3-stmt :pointer-void) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Lisp types definitions. ;;;; (def-type sqlite3-db-type sqlite3-db) (def-type sqlite3-db-ptr-type (* sqlite3-db)) (def-type sqlite3-stmt-type sqlite3-stmt) (def-type sqlite3-stmt-ptr-type (* sqlite3-stmt)) (def-type unsigned-char-ptr-type (* :unsigned-char)) (defparameter null-stmt (make-null-pointer :void)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Hash tables for db and statement pointers. ;;; (defvar *db-pointers* (make-hash-table)) (defvar *stmt-pointers* (make-hash-table)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Conditions. ;;;; (define-condition sqlite3-error () ((message :initarg :message :reader sqlite3-error-message :initform "") (code :initarg :code :reader sqlite3-error-code)) (:report (lambda (condition stream) (format stream "Sqlite3 error [~A]: ~A" (sqlite3-error-code condition) (sqlite3-error-message condition))))) (defgeneric signal-sqlite3-error (db)) (defmethod signal-sqlite3-error (db) (let ((condition (make-condition 'sqlite3-error :code (sqlite3-errcode db) :message (convert-from-cstring (sqlite3-errmsg db))))) (unless (signal condition) (invoke-debugger condition)))) (defmethod signal-sqlite3-error ((code number)) (let ((condition (make-condition 'sqlite3-error :code code :message (let ((s (cdr (assoc code error-codes)))) (if s s "unknown error"))))) (unless (signal condition) (invoke-debugger condition)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Library functions. ;;;; (defmacro def-sqlite3-function (name args &key (returning :void)) `(def-function ,name ,args :module "sqlite3" :returning ,returning)) (declaim (inline %errcode)) (def-sqlite3-function "sqlite3_errcode" ((db sqlite3-db)) :returning :int) (declaim (inline %errmsg)) (def-sqlite3-function "sqlite3_errmsg" ((db sqlite3-db)) :returning :cstring) (declaim (inline %open)) (def-sqlite3-function ("sqlite3_open" %open) ((dbname :cstring) (db (* sqlite3-db))) :returning :int) (declaim (inline %close)) (def-sqlite3-function ("sqlite3_close" %close) ((db sqlite3-db)) :returning :int) (declaim (inline %prepare)) (def-sqlite3-function ("sqlite3_prepare" %prepare) ((db sqlite3-db) (sql :cstring) (len :int) (stmt (* sqlite3-stmt)) (sql-tail (* (* :unsigned-char)))) :returning :int) (declaim (inline %step)) (def-sqlite3-function ("sqlite3_step" %step) ((stmt sqlite3-stmt)) :returning :int) (declaim (inline %finalize)) (def-sqlite3-function ("sqlite3_finalize" %finalize) ((stmt sqlite3-stmt)) :returning :int) (declaim (inline sqlite3-column-count)) (def-sqlite3-function "sqlite3_column_count" ((stmt sqlite3-stmt)) :returning :int) (declaim (inline %column-name)) (def-sqlite3-function ("sqlite3_column_name" %column-name) ((stmt sqlite3-stmt) (n-col :int)) :returning :cstring) (declaim (inline sqlite3-column-type)) (def-sqlite3-function "sqlite3_column_type" ((stmt sqlite3-stmt) (n-col :int)) :returning :int) (declaim (inline sqlite3-column-text)) (def-sqlite3-function "sqlite3_column_text" ((stmt sqlite3-stmt) (n-col :int)) :returning (* :unsigned-char)) (declaim (inline sqlite3-column-bytes)) (def-sqlite3-function "sqlite3_column_bytes" ((stmt sqlite3-stmt) (n-col :int)) :returning :int) (declaim (inline sqlite3-column-blob)) (def-sqlite3-function "sqlite3_column_blob" ((stmt sqlite3-stmt) (n-col :int)) :returning :pointer-void) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; wrapper functions. ;;;; (defun sqlite3-open (db &optional (mode 0) &aux (db-name (etypecase db (pathname (namestring db)) (string db)))) (declare (ignore mode) (type string db-name)) (let ((dbp (allocate-foreign-object 'sqlite3-db))) (declare (type sqlite3-db-ptr-type dbp)) (with-cstring (db-name-native db-name) (let ((result (%open db-name-native dbp))) (if (/= result 0) (progn ;; According to docs, the db must be closed even in case ;; of error. (%close (deref-pointer dbp 'sqlite3-db)) (free-foreign-object dbp) (signal-sqlite3-error result)) (let ((db (deref-pointer dbp 'sqlite3-db))) (declare (type sqlite3-db-type db)) (setf (gethash db *db-pointers*) dbp) db)))))) (declaim (ftype (function (sqlite3-db-type) t) sqlite3-close)) (defun sqlite3-close (db) (declare (type sqlite3-db-type db)) (let ((result (%close db))) (if (/= result 0) (signal-sqlite3-error result) (progn (free-foreign-object (gethash db *db-pointers*)) (remhash db *db-pointers*) t)))) (declaim (ftype (function (sqlite3-db-type string) sqlite3-stmt-type) sqlite3-prepare)) (defun sqlite3-prepare (db sql) (declare (type sqlite3-db-type db)) (with-cstring (sql-native sql) (let ((stmtp (allocate-foreign-object 'sqlite3-stmt))) (declare (type sqlite3-stmt-ptr-type stmtp)) (with-foreign-object (sql-tail '(* :unsigned-char)) (let ((result (%prepare db sql-native -1 stmtp sql-tail))) (if (/= result SQLITE-OK) (progn (unless (null-pointer-p stmtp) ;; There is an error, but a statement has been allocated: ;; finalize it (better safe than sorry). (%finalize (deref-pointer stmtp 'sqlite3-stmt))) (free-foreign-object stmtp) (signal-sqlite3-error db)) (let ((stmt (deref-pointer stmtp 'sqlite3-stmt))) (declare (type sqlite3-stmt-type stmt)) (setf (gethash stmt *stmt-pointers*) stmtp) stmt))))))) (declaim (ftype (function (sqlite3-stmt-type) t) sqlite3-step)) (defun sqlite3-step (stmt) (declare (type sqlite3-stmt-type stmt)) (let ((result (%step stmt))) (cond ((= result SQLITE-ROW) t) ((= result SQLITE-DONE) nil) (t (signal-sqlite3-error result))))) (declaim (ftype (function (sqlite3-stmt-type) t) sqlite3-finalize)) (defun sqlite3-finalize (stmt) (declare (type sqlite3-stmt-type stmt)) (let ((result (%finalize stmt))) (if (/= result SQLITE-OK) (signal-sqlite3-error result) (progn (free-foreign-object (gethash stmt *stmt-pointers*)) (remhash stmt *stmt-pointers*) t)))) (declaim (inline sqlite3-column-name)) (defun sqlite3-column-name (stmt n) (declare (type sqlite3-stmt-type stmt) (type fixnum n)) (convert-from-cstring (%column-name stmt n))) cl-sql-6.7.2/db-sqlite3/sqlite3-package.lisp0000644000175000017500000000151511335067642017561 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite-package.lisp ;;;; Purpose: Package definition for low-level SQLite3 interface ;;;; Programmer: Aurelio Bignoli ;;;; Date Started: Oct 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-sqlite3 (:use #:common-lisp #:clsql-sys) (:export #:sqlite3-database)) cl-sql-6.7.2/db-sqlite3/sqlite3-methods.lisp0000644000175000017500000000147412303270414017622 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- (in-package #:clsql-sys) (defmethod database-pkey-constraint ((class standard-db-class) (database clsql-sqlite3:sqlite3-database)) (let* ((keys (keyslots-for-class class)) (cons (when (= 1 (length keys)) (view-class-slot-db-constraints (first keys))))) ;; This method generates primary key constraints part of the table ;; definition. For Sqlite autoincrement primary keys to work properly ;; this part of the table definition must be left out (IFF autoincrement) . (when (or (null cons) ;; didnt have constraints to check ;; didnt have auto-increment (null (intersection +auto-increment-names+ (listify cons)))) (call-next-method)))) cl-sql-6.7.2/db-sqlite3/sqlite3-loader.lisp0000644000175000017500000000315111335067642017432 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite3-loader.lisp ;;;; Purpose: Sqlite3 library loader using UFFI ;;;; Programmer: Aurelio Bignoli ;;;; Date Started: Oct 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sqlite3) (defvar *sqlite3-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to load the Sqlite3 library succesfully. If this differs at your site, set to the right path before compiling or loading the system.") (defvar *sqlite3-library-loaded* nil "T if foreign library was able to be loaded successfully") (defmethod database-type-library-loaded ((database-type (eql :sqlite3))) "T if foreign library was able to be loaded successfully. " *sqlite3-library-loaded*) (defmethod database-type-load-foreign ((database-type (eql :sqlite3))) (clsql-uffi:find-and-load-foreign-library '("libsqlite3" "sqlite3") :module "sqlite3" :supporting-libraries *sqlite3-supporting-libraries*) (setq *sqlite3-library-loaded* t)) (clsql-sys:database-type-load-foreign :sqlite3) cl-sql-6.7.2/db-sqlite3/sqlite3-sql.lisp0000644000175000017500000003635612473715066017004 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: sqlite-sql.lisp ;;;; Purpose: High-level SQLite3 interface ;;;; Authors: Aurelio Bignoli & Kevin Rosenberg ;;;; Created: Oct 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004-2010 by Aurelio Bignoli & Kevin Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sqlite3) (defclass sqlite3-database (database) ((sqlite3-db :initarg :sqlite3-db :accessor sqlite3-db))) (defmethod database-type ((database sqlite3-database)) :sqlite3) (defmethod database-initialize-database-type ((database-type (eql :sqlite3))) t) (defun check-sqlite3-connection-spec (connection-spec) (check-connection-spec connection-spec :sqlite3 (name &optional init-foreign-func))) (defmethod database-name-from-spec (connection-spec (database-type (eql :sqlite3))) (check-sqlite3-connection-spec connection-spec) (princ-to-string (first connection-spec))) (defmethod database-connect (connection-spec (database-type (eql :sqlite3))) (check-sqlite3-connection-spec connection-spec) (handler-case (let ((db (sqlite3:sqlite3-open (first connection-spec))) (init-foreign-func (second connection-spec))) (declare (type sqlite3:sqlite3-db-type db)) (when init-foreign-func (handler-case (funcall init-foreign-func db) (condition (c) (progn (sqlite3:sqlite3-close db) (error c))))) (make-instance 'sqlite3-database :name (database-name-from-spec connection-spec :sqlite3) :database-type :sqlite3 :connection-spec connection-spec :sqlite3-db db)) (sqlite3:sqlite3-error (err) (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id (sqlite3:sqlite3-error-code err) :message (sqlite3:sqlite3-error-message err))))) (defmethod database-disconnect ((database sqlite3-database)) (sqlite3:sqlite3-close (sqlite3-db database)) (setf (sqlite3-db database) nil) t) (defmethod database-execute-command (sql-expression (database sqlite3-database)) (handler-case (let ((stmt (sqlite3:sqlite3-prepare (sqlite3-db database) sql-expression))) (declare (type sqlite3:sqlite3-stmt-type stmt)) (when stmt (unwind-protect (sqlite3:sqlite3-step stmt) (sqlite3:sqlite3-finalize stmt)))) (sqlite3:sqlite3-error (err) (error 'sql-database-data-error :database database :expression sql-expression :error-id (sqlite3:sqlite3-error-code err) :message (sqlite3:sqlite3-error-message err)))) t) (defstruct sqlite3-result-set (stmt sqlite3:null-stmt :type sqlite3:sqlite3-stmt-type) (n-col 0 :type fixnum) (col-names '()) (result-types '())) (declaim (ftype (function (sqlite3:sqlite3-stmt-type fixnum t) list) get-result-types)) (defun get-result-types (stmt n-col result-types) (declare (type sqlite3:sqlite3-stmt-type stmt) (type fixnum n-col)) (if (eq :auto result-types) (loop for n from 0 below n-col collect (let ((column-type (sqlite3:sqlite3-column-type stmt n))) (cond ((= column-type sqlite3:SQLITE-INTEGER) :int64) ((= column-type sqlite3:SQLITE-FLOAT) :double) ((= column-type sqlite3:SQLITE-TEXT) :string) ((= column-type sqlite3:SQLITE-BLOB) :blob) ((= column-type sqlite3:SQLITE-NULL) :string) (t :string)))) (loop for type in result-types collect (case type ((:int :integer :tinyint) :int32) (:long #+(or x86-64 64bit) :int64 #-(or x86-64 64bit) :int32) (:bigint :int64) ((:float :double) :double) ((:numeric) :number) (otherwise :string))))) (defmethod database-query-result-set ((query-expression string) (database sqlite3-database) &key result-types full-set) (let ((stmt sqlite3:null-stmt)) (declare (type sqlite3:sqlite3-stmt-type stmt)) (handler-case (progn (setf stmt (sqlite3:sqlite3-prepare (sqlite3-db database) query-expression)) (let* ((n-col (if (sqlite3:sqlite3-step stmt) ;; Non empty result set. (sqlite3:sqlite3-column-count stmt) ;; Empty result set. 0)) (result-set (make-sqlite3-result-set :stmt stmt :n-col n-col :col-names (loop for n from 0 below n-col collect (sqlite3:sqlite3-column-name stmt n)) :result-types (when (> n-col 0) (get-result-types stmt n-col result-types))))) (if full-set (values result-set n-col nil) (values result-set n-col)))) (sqlite3:sqlite3-error (err) (progn (unless (eq stmt sqlite3:null-stmt) (ignore-errors (sqlite3:sqlite3-finalize stmt))) (error 'sql-database-data-error :database database :expression query-expression :error-id (sqlite3:sqlite3-error-code err) :message (sqlite3:sqlite3-error-message err))))))) (defmethod database-dump-result-set (result-set (database sqlite3-database)) (handler-case (sqlite3:sqlite3-finalize (sqlite3-result-set-stmt result-set)) (sqlite3:sqlite3-error (err) (error 'sql-database-error :message (format nil "Error finalizing SQLite3 statement: ~A" (sqlite3:sqlite3-error-message err)))))) (defmethod database-store-next-row (result-set (database sqlite3-database) list) (let ((n-col (sqlite3-result-set-n-col result-set))) (if (= n-col 0) ;; empty result set. nil ;; Non-empty set. (let ((stmt (sqlite3-result-set-stmt result-set))) (declare (type sqlite3:sqlite3-stmt-type stmt)) ;; Store row in list. (loop for i = 0 then (1+ i) for rest on list for types = (sqlite3-result-set-result-types result-set) then (rest types) do (setf (car rest) (if (eq (first types) :blob) (clsql-uffi:convert-raw-field (sqlite3:sqlite3-column-blob stmt i) (car types) :length (sqlite3:sqlite3-column-bytes stmt i) :encoding (encoding database)) (clsql-uffi:convert-raw-field (sqlite3:sqlite3-column-text stmt i) (car types) :encoding (encoding database))))) ;; Advance result set cursor. (handler-case (unless (sqlite3:sqlite3-step stmt) (setf (sqlite3-result-set-n-col result-set) 0)) (sqlite3:sqlite3-error (err) (error 'sql-database-error :message (format nil "Error in sqlite3-step: ~A" (sqlite3:sqlite3-error-message err))))) t)))) (defmethod database-query (query-expression (database sqlite3-database) result-types field-names) (declare (optimize (speed 3) (safety 0) (debug 0) (space 0))) (handler-case (let ((stmt (sqlite3:sqlite3-prepare (sqlite3-db database) query-expression)) (rows '()) (col-names '())) (declare (type sqlite3:sqlite3-stmt-type stmt)) (unwind-protect (when (sqlite3:sqlite3-step stmt) (let ((n-col (sqlite3:sqlite3-column-count stmt))) (flet ((extract-row-data () (loop for i from 0 below n-col for types = (get-result-types stmt n-col result-types) then (rest types) collect (if (eq (first types) :blob) (clsql-uffi:convert-raw-field (sqlite3:sqlite3-column-blob stmt i) (car types) :length (sqlite3:sqlite3-column-bytes stmt i) :encoding (encoding database)) (clsql-uffi:convert-raw-field (sqlite3:sqlite3-column-text stmt i) (car types) :encoding (encoding database)))))) (when field-names (setf col-names (loop for n from 0 below n-col collect (sqlite3:sqlite3-column-name stmt n)))) (push (extract-row-data) rows) (do* () (nil) (if (sqlite3:sqlite3-step stmt) (push (extract-row-data) rows) (return)))))) (sqlite3:sqlite3-finalize stmt)) (values (nreverse rows) col-names)) (sqlite3:sqlite3-error (err) (error 'sql-database-data-error :database database :expression query-expression :error-id (sqlite3:sqlite3-error-code err) :message (sqlite3:sqlite3-error-message err))))) ;;; Object listing (defmethod database-list-tables-and-sequences ((database sqlite3-database) &key owner) (declare (ignore owner)) ;; Query is copied from .table command of sqlite3 command line utility. (mapcar #'car (database-query "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name" database nil nil))) (defmethod database-list-tables ((database sqlite3-database) &key owner) (remove-if #'(lambda (s) (and (>= (length s) 11) (string-equal (subseq s 0 11) "_CLSQL_SEQ_"))) (database-list-tables-and-sequences database :owner owner))) (defmethod database-list-views ((database sqlite3-database) &key (owner nil)) (declare (ignore owner)) (mapcar #'car (database-query "SELECT name FROM sqlite_master WHERE type='view' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='view' ORDER BY name" database nil nil))) (defmethod database-list-indexes ((database sqlite3-database) &key (owner nil)) (declare (ignore owner)) (mapcar #'car (database-query "SELECT name FROM sqlite_master WHERE type='index' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' ORDER BY name" database nil nil))) (defmethod database-list-table-indexes (table (database sqlite3-database) &key (owner nil)) (declare (ignore owner)) (let ((*print-circle* nil)) (mapcar #'car (database-query (format nil "SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='~A' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' AND tbl_name='~A' ORDER BY name" table table) database nil nil)))) (declaim (inline sqlite3-table-info)) (defun sqlite3-table-info (table database) (let ((sql (format nil "PRAGMA table_info('~A')" (clsql-sys::unescaped-database-identifier table)))) (database-query sql database nil nil))) (defmethod database-list-attributes (table (database sqlite3-database) &key (owner nil)) (declare (ignore owner)) (mapcar #'(lambda (table-info) (second table-info)) (sqlite3-table-info table database))) (defmethod database-attribute-type (attribute table (database sqlite3-database) &key (owner nil)) (declare (ignore owner)) (loop for field-info in (sqlite3-table-info table database) when (string= (clsql-sys::unescaped-database-identifier attribute) (second field-info)) return (let* ((raw-type (third field-info)) (start-length (position #\( raw-type)) (type (string-trim clsql-sys::+whitespace-chars+ (if start-length (subseq raw-type 0 start-length) raw-type))) (length (if start-length (parse-integer (subseq raw-type (1+ start-length)) :junk-allowed t) nil))) (values (when type (ensure-keyword type)) length nil (if (string-equal (fourth field-info) "0") 1 0))))) (defmethod database-last-auto-increment-id ((database sqlite3-database) table column) (declare (ignore table column)) (car (query "SELECT LAST_INSERT_ROWID();" :flatp t :field-names nil :database database))) (defmethod database-create (connection-spec (type (eql :sqlite3))) (declare (ignore connection-spec)) ;; databases are created automatically by Sqlite3 t) (defmethod database-destroy (connection-spec (type (eql :sqlite3))) (destructuring-bind (name) connection-spec (if (probe-file name) (delete-file name) nil))) (defmethod database-probe (connection-spec (type (eql :sqlite3))) (destructuring-bind (name) connection-spec ;; TODO: Add a test that this file is a real sqlite3 database (or (string-equal ":memory:" name) (and (probe-file name) t)))) (defmethod database-get-type-specifier ((type (eql 'integer)) args database (db-type (eql :sqlite3))) (declare (ignore database)) (if args (format nil "INTEGER(~A)" (car args)) "INTEGER")) (defmethod database-get-type-specifier ((type (eql 'integer)) args database (db-type (eql :sqlite3))) (declare (ignore database)) (if args (format nil "INTEGER(~A)" (car args)) "INTEGER")) ;;; Database capabilities (defmethod db-type-has-boolean-where? ((db-type (eql :sqlite3))) nil) (defmethod db-type-has-auto-increment? ((db-type (eql :sqlite3))) t) cl-sql-6.7.2/doc/0000755000175000017500000000000014327126007012502 5ustar kevinkevincl-sql-6.7.2/doc/ref-fddl.xml0000644000175000017500000025102412303270414014705 0ustar kevinkevin %myents; ]> Functional Data Definition Language (FDDL) &clsql; provides a functional DDL which supports the creation and destruction of a variety of database objects including tables, views, indexes and sequences. Functions which return information about currently defined database objects are also provided. In addition, the FDDL includes functionality for examining table attributes and attribute types. CREATE-TABLE CREATE-TABLE Create a database table. Function Syntax create-table name description &key database constraints transactions => Arguments and Values name The name of the table as a string, symbol or SQL expression. database A database object which defaults to *default-database*. description A list. constraints A string, a list of strings or &nil;. transactions A Boolean. The default value is &t;. Description Creates a table called name, which may be a string, symbol or SQL table identifier, in database which defaults to *default-database*. description is a list whose elements are lists containing the attribute names, types, and other constraints such as not-null or primary-key for each column in the table. constraints is a string representing an SQL table constraint expression or a list of such strings. With MySQL databases, if transactions is &t; an InnoDB table is created which supports transactions. Examples (create-table [foo] '(([id] integer) ([height] float) ([name] (string 24)) ([comments] text))) => (table-exists-p [foo]) => T (create-table [foo] '(([bar] integer :not-null :unique :primary-key) ([baz] string :not-null :unique))) => (table-exists-p [foo]) => T (create-table [foo] '(([bar] integer :not-null) ([baz] string :not-null)) :constraints '("UNIQUE (bar,baz)" "PRIMARY KEY (bar)")) => (table-exists-p [foo]) => T Side Effects A table is created in database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if a relation called name already exists. See Also drop-table list-tables table-exists-p Notes The constraints and transactions keyword arguments to create-table are &clsql; extensions. The transactions keyword argument is for compatibility with MySQL databases. DROP-TABLE DROP-TABLE Drop a database table. Function Syntax drop-table name &key if-does-not-exist database => Arguments and Values name The name of the table as a string, symbol or SQL expression. database A database object which defaults to *default-database*. if-does-not-exist A symbol. Meaningful values are :ignore or :error (the default). Description Drops the table called name from database which defaults to *default-database*. If the table does not exist and if-does-not-exist is :ignore then drop-table returns &nil; whereas an error is signalled if if-does-not-exist is :error. Examples (table-exists-p [foo]) => T (drop-table [foo] :if-does-not-exist :ignore) => (table-exists-p [foo]) => NIL Side Effects A table is dropped database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if name doesn't exist and if-does-not-exist has a value of :error. See Also create-table list-tables table-exists-p Notes The if-does-not-exist keyword argument to drop-table is a &clsql; extension. LIST-TABLES LIST-TABLES Returns a list of database tables. Function Syntax list-tables &key owner database => result Arguments and Values owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A list of strings. Description Returns a list of strings representing table names in database which defaults to *default-database*. owner is &nil; by default which means that only tables owned by users are listed. If owner is a string denoting a user name, only tables owned by owner are listed. If owner is :all then all tables are listed. Examples (list-tables :owner "fred") => ("type_table" "type_bigint" "employee" "company" "addr" "ea_join" "big") (list-tables :owner :all) => ("pg_description" "pg_group" "pg_proc" "pg_rewrite" "pg_type" "pg_attribute" "pg_class" "pg_inherits" "pg_index" "pg_operator" "pg_opclass" "pg_am" "pg_amop" "pg_amproc" "pg_language" "pg_largeobject" "pg_aggregate" "pg_trigger" "pg_listener" "pg_cast" "pg_namespace" "pg_shadow" "pg_conversion" "pg_depend" "pg_attrdef" "pg_constraint" "pg_database" "type_table" "type_bigint" "employee" "company" "pg_statistic" "addr" "ea_join" "big") Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-table drop-table table-exists-p Notes None. TABLE-EXISTS-P TABLE-EXISTS-P Tests for the existence of a database table. Function Syntax table-exists-p name &key owner database => result Arguments and Values name The name of the table as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A Boolean. Description Tests for the existence of an SQL table called name in database which defaults to *default-database*. owner is &nil; by default which means that only tables owned by users are examined. If owner is a string denoting a user name, only tables owned by owner are examined. If owner is :all then all tables are examined. Examples (table-exists-p [foo]) => T Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-table drop-table list-tables Notes None. CREATE-VIEW CREATE-VIEW Create a database view. Function Syntax create-view name &key as column-list with-check-option database => Arguments and Values name The name of the view as a string, symbol or SQL expression. database A database object which defaults to *default-database*. as A symbolic SQL query expression. column-list A list. with-check-option A Boolean. Description Creates a view called name in database which defaults to *default-database*. The view is created using the query as and the columns of the view may be specified using the column-list parameter. The with-check-option is &nil; by default but if it has a non-&nil; value, then all insert/update commands on the view are checked to ensure that the new data satisfy the query as. Examples (create-view [lenins-group] :as [select [first-name] [last-name] [email] :from [employee] :where [= [managerid] 1]]) => (select [*] :from [lenins-group]) => (("Josef" "Stalin" "stalin@soviet.org") ("Leon" "Trotsky" "trotsky@soviet.org") ("Nikita" "Kruschev" "kruschev@soviet.org") ("Leonid" "Brezhnev" "brezhnev@soviet.org") ("Yuri" "Andropov" "andropov@soviet.org") ("Konstantin" "Chernenko" "chernenko@soviet.org") ("Mikhail" "Gorbachev" "gorbachev@soviet.org") ("Boris" "Yeltsin" "yeltsin@soviet.org") ("Vladimir" "Putin" "putin@soviet.org")), ("first_name" "last_name" "email") Side Effects A view is created in database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if a relation called name already exists. See Also drop-view list-views view-exists-p Notes None. DROP-VIEW DROP-VIEW Drops a database view. Function Syntax drop-view name &key if-does-not-exist database => Arguments and Values name The name of the view as a string, symbol or SQL expression. database A database object which defaults to *default-database*. if-does-not-exist A symbol. Meaningful values are :ignore or :error (the default). Description Drops the view called name from database which defaults to *default-database*. If the view does not exist and if-does-not-exist is :ignore then drop-view returns &nil; whereas an error is signalled if if-does-not-exist is :error. Examples (view-exists-p [foo]) => T (drop-view [foo] :if-does-not-exist :ignore) => (view-exists-p [foo]) => NIL Side Effects A view is dropped database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if name doesn't exist and if-does-not-exist has a value of :error. See Also create-view list-views view-exists-p Notes The if-does-not-exist keyword argument to drop-view is a &clsql; extension. LIST-VIEWS LIST-VIEWS Returns a list of database views. Function Syntax list-views &key owner database => result Arguments and Values owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A list of strings. Description Returns a list of strings representing view names in database which defaults to *default-database*. owner is &nil; by default which means that only views owned by users are listed. If owner is a string denoting a user name, only views owned by owner are listed. If owner is :all then all views are listed. Examples (list-views :owner "fred") => ("lenins_group") (list-views :owner :all) => ("pg_user" "pg_rules" "pg_views" "pg_tables" "pg_indexes" "pg_stats" "pg_stat_all_tables" "pg_stat_sys_tables" "pg_stat_user_tables" "pg_statio_all_tables" "pg_statio_sys_tables" "pg_statio_user_tables" "pg_stat_all_indexes" "pg_stat_sys_indexes" "pg_stat_user_indexes" "pg_statio_all_indexes" "pg_statio_sys_indexes" "pg_statio_user_indexes" "pg_statio_all_sequences" "pg_statio_sys_sequences" "pg_statio_user_sequences" "pg_stat_activity" "pg_stat_database" "pg_locks" "pg_settings" "lenins_group") Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-view drop-view view-exists-p Notes list-views is a &clsql; extension. VIEW-EXISTS-P VIEW-EXISTS-P Tests for the existence of a database view. Function Syntax view-exists-p name &key owner database => result Arguments and Values name The name of the view as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A Boolean. Description Tests for the existence of an SQL view called name in database which defaults to *default-database*. owner is &nil; by default which means that only views owned by users are examined. If owner is a string denoting a user name, only views owned by owner are examined. If owner is :all then all views are examined. Examples (view-exists-p [lenins-group]) => T Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-view drop-view list-views Notes view-exists-p is a &clsql; extension. CREATE-INDEX CREATE-INDEX Create a database index. Function Syntax create-index name &key on unique attributes database => Arguments and Values name The name of the index as a string, symbol or SQL expression. on The name of a table as a string, symbol or SQL expression. unique A Boolean. attributes A list of attribute names. database A database object which defaults to *default-database*. Description Creates an index called name on the table specified by on in database which default to *default-database*. The table attributes to use in constructing the index name are specified by attributes. The unique argument is &nil; by default but if it has a non-&nil; value then the indexed attributes must have unique values. Examples (create-index [bar] :on [employee] :attributes '([first-name] [last-name] [email]) :unique t) => (index-exists-p [bar]) => T Side Effects An index is created in database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if a relation called name already exists. See Also drop-index list-indexes index-exists-p Notes None. DROP-INDEX DROP-INDEX Drop a database index. Function Syntax drop-index name &key if-does-not-exist on database => Arguments and Values name The name of the index as a string, symbol or SQL expression. on The name of a table as a string, symbol or SQL expression. database A database object which defaults to *default-database*. if-does-not-exist A symbol. Meaningful values are :ignore or :error (the default). Description Drops the index called name in database which defaults to *default-database*. If the index does not exist and if-does-not-exist is :ignore then drop-index returns &nil; whereas an error is signalled if if-does-not-exist is :error. The argument on allows the optional specification of a table to drop the index from. This is required for compatability with MySQL. Examples (index-exists-p [foo]) => T (drop-index [foo] :if-does-not-exist :ignore) => (index-exists-p [foo]) => NIL Side Effects An index is dropped in database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if name doesn't exist and if-does-not-exist has a value of :error. See Also create-index list-indexes index-exists-p Notes The if-does-not-exist and on keyword arguments to drop-index are &clsql; extensions. The keyword argument on is provided for compatibility with MySQL. LIST-INDEXES LIST-INDEXES Returns a list of database indexes. Function Syntax list-indexes &key onowner database => result Arguments and Values owner A string, &nil; or :all. database A database object which defaults to *default-database*. on The name of a table as a string, symbol or SQL expression, a list of such names or &nil;. result A list of strings. Description Returns a list of strings representing index names in database which defaults to *default-database*. owner is &nil; by default which means that only indexes owned by users are listed. If owner is a string denoting a user name, only indexes owned by owner are listed. If owner is :all then all indexes are listed. The keyword argument on limits the results to indexes on the specified tables. Meaningful values for on are &nil; (the default) which means that all tables are considered, a string, symbol or SQL expression representing a table name in database or a list of such table identifiers. Examples (list-indexes) => ("employeepk" "companypk" "addrpk" "bar") (list-indexes :on '([addr] [company])) => ("addrpk" "companypk") Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-index drop-index index-exists-p Notes list-indexes is a &clsql; extension. INDEX-EXISTS-P INDEX-EXISTS- Tests for the existence of a database index. Function Syntax index-exists-p name &key owner database => result Arguments and Values name The name of the index as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A Boolean. Description Tests for the existence of an SQL index called name in database which defaults to *default-database*. owner is &nil; by default which means that only indexes owned by users are examined. If owner is a string denoting a user name, only indexes owned by owner are examined. If owner is :all then all indexes are examined. Examples (index-exists-p [bar]) => T Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-index drop-index list-indexes Notes index-exists-p is a &clsql; extension. ATTRIBUTE-TYPE ATTRIBUTE-TYPE Returns the type of the supplied attribute. Function Syntax attribute-type attribute table &key owner database => type, precision, scale, nulls-accepted Arguments and Values attribute The name of the index as a string, symbol or SQL expression. table The name of a table as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. type A keyword symbol denoting a vendor-specific SQL type. precision An integer denoting the precision of the attribute type or &nil;. scale An integer denoting the scale of the attribute type or &nil;. nulls-accepted 0 or 1. Description Returns a keyword symbol representing the vendor-specific field type of the supplied attribute attribute in the table specified by table in database which defaults to *default-database*. owner is &nil; by default which means that the attribute specified by attribute, if it exists, must be user owned else &nil; is returned. If owner is a string denoting a user name, the attribute, if it exists, must be owned by owner else &nil; is returned, whereas if owner is :all then the attribute, if it exists, will be returned regardless of its owner. Other information is also returned. The second value is the type precision, the third is the scale and the fourth represents whether or not the attribute accepts null values (a value of 0) or not (a value of 1). Examples (attribute-type [emplid] [employee]) => :INT4, 4, NIL, 0 Side Effects None. Affected by *default-database* Exceptional Situations None. See Also list-attributes list-attribute-types Notes None. LIST-ATTRIBUTE-TYPES LIST-ATTRIBUTE-TYPES Returns information about the attribute types of a table. Function Syntax list-attribute-types table &key owner database => result Arguments and Values table The name of a table as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A list. Description Returns a list containing information about the SQL types of each of the attributes in the table specified by table in database which has a default value of *default-database*. owner is &nil; by default which means that only attributes owned by users are listed. If owner is a string denoting a user name, only attributes owned by owner are listed. If owner is :all then all attributes are listed. The elements of the returned list are lists where the first element is the name of the attribute, the second element is its SQL type, the third is the type precision, the fourth is the scale of the attribute and the fifth is 1 if the attribute accepts null values and otherwise 0. Examples (list-attribute-types [employee]) => (("emplid" :INT4 4 NIL 0) ("groupid" :INT4 4 NIL 0) ("first_name" :VARCHAR 30 NIL 1) ("last_name" :VARCHAR 30 NIL 1) ("email" :VARCHAR 100 NIL 1) ("ecompanyid" :INT4 4 NIL 1) ("managerid" :INT4 4 NIL 1) ("height" :FLOAT8 8 NIL 1) ("married" :BOOL 1 NIL 1) ("birthday" :TIMESTAMP 8 NIL 1) ("bd_utime" :INT8 8 NIL 1)) Side Effects None. Affected by *default-database* Exceptional Situations None. See Also attribute-type list-attribute-types Notes None. LIST-ATTRIBUTES LIST-ATTRIBUTES Returns the attributes of a table as a list. Function Syntax list-attributes name &key owner database => result Arguments and Values name The name of a table as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A list. Description Returns a list of strings representing the attributes of table name in database which defaults to *default-database*. owner is &nil; by default which means that only attributes owned by users are listed. If owner is a string denoting a user name, only attributes owned by owner are listed. If owner is :all then all attributes are listed. Examples (list-attributes [employee]) => ("emplid" "groupid" "first_name" "last_name" "email" "ecompanyid" "managerid" "height" "married" "birthday" "bd_utime") Side Effects None. Affected by *default-database* Exceptional Situations None. See Also attribute-type list-attribute-types Notes None. CREATE-SEQUENCE CREATE-SEQUENCE Create a database sequence. Function Syntax create-sequence name &key database => Arguments and Values name The name of the sequence as a string, symbol or SQL expression. database A database object which defaults to *default-database*. Description Creates a sequence called name in database which defaults to *default-database*. Examples (create-sequence [foo]) => (sequence-exists-p [foo]) => T Side Effects A sequence is created in database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if a relation called name already exists. See Also drop-sequence list-sequences sequence-exists-p sequence-last sequence-next set-sequence-position Notes create-sequence is a &clsql; extension. DROP-SEQUENCE DROP-SEQUENCE Drop a database sequence. Function Syntax drop-sequence name &key if-does-not-exist database => Arguments and Values name The name of the sequence as a string, symbol or SQL expression. database A database object which defaults to *default-database*. if-does-not-exist A symbol. Meaningful values are :ignore or :error (the default). Description Drops the sequence called name from database which defaults to *default-database*. If the sequence does not exist and if-does-not-exist is :ignore then drop-sequence returns &nil; whereas an error is signalled if if-does-not-exist is :error. Examples (sequence-exists-p [foo]) => T (drop-sequence [foo] :if-does-not-exist :ignore) => (sequence-exists-p [foo]) => NIL Side Effects A sequence is dropped from database. Affected by *default-database* Exceptional Situations An error is signalled if name is not a string, symbol or SQL expression. An error of type sql-database-data-error is signalled if name doesn't exist and if-does-not-exist has a value of :error. See Also create-sequence list-sequences sequence-exists-p sequence-last sequence-next set-sequence-position Notes drop-sequence is a &clsql; extension. LIST-SEQUENCES LIST-SEQUENCES Returns a list of database sequences. Function Syntax list-sequences &key owner database => result Arguments and Values owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A list of strings. Description Returns a list of strings representing sequence names in database which defaults to *default-database*. owner is &nil; by default which means that only sequences owned by users are listed. If owner is a string denoting a user name, only sequences owned by owner are listed. If owner is :all then all sequences are listed. Examples (list-sequences) => ("foo") Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-sequence drop-sequence sequence-exists-p sequence-last sequence-next set-sequence-position Notes list-sequences is a &clsql; extension. SEQUENCE-EXISTS-P SEQUENCE-EXISTS-P Tests for the existence of a database sequence. Function Syntax sequence-exists-p name &key owner database => result Arguments and Values name The name of the sequence as a string, symbol or SQL expression. owner A string, &nil; or :all. database A database object which defaults to *default-database*. result A Boolean. Description Tests for the existence of an SQL sequence called name in database which defaults to *default-database*. owner is &nil; by default which means that only sequences owned by users are examined. If owner is a string denoting a user name, only sequences owned by owner are examined. If owner is :all then all sequences are examined. Examples (sequence-exists-p [foo]) => NIL Side Effects None. Affected by *default-database* Exceptional Situations None. See Also create-sequence drop-sequence list-sequences sequence-last sequence-next set-sequence-position Notes sequence-exists-p is a &clsql; extension. SEQUENCE-LAST SEQUENCE-LAST Return the last element in a database sequence. Function Syntax sequence-last name &key database => result Arguments and Values name The name of the sequence as a string, symbol or SQL expression. database A database object which defaults to *default-database*. result An integer. Description Return the last value allocated in the sequence called name in database which defaults to *default-database*. Examples (sequence-last [foo]) => 1 Side Effects None. Affected by The current value stored in database sequence name. *default-database* Exceptional Situations Will signal an error of type sql-database-data-error if a sequence called name does not exist in database. See Also create-sequence drop-sequence list-sequences sequence-exists-p sequence-next set-sequence-position Notes sequence-last is a &clsql; extension. SEQUENCE-NEXT SEQUENCE-NEXT Increment the value of a database sequence. Function Syntax sequence-next name &key database => result Arguments and Values name The name of the sequence as a string, symbol or SQL expression. database A database object which defaults to *default-database*. result An integer. Description Increment and return the value of the sequence called name in database which defaults to *default-database*. Examples (sequence-last [foo]) => 3 (sequence-next [foo]) => 4 (sequence-next [foo]) => 5 (sequence-next [foo]) => 6 Side Effects Modifies the value of the sequence name in database. Affected by The current value stored in database sequence name. *default-database* Exceptional Situations Will signal an error of type sql-database-data-error if a sequence called name does not exist in database. See Also create-sequence drop-sequence list-sequences sequence-exists-p sequence-last set-sequence-position Notes sequence-next is a &clsql; extension. SET-SEQUENCE-POSITION SET-SEQUENCE-POSITION Sets the position of a database sequence. Function Syntax set-sequence-position name position &key database => result Arguments and Values name The name of the sequence as a string, symbol or SQL expression. position An integer. database A database object which defaults to *default-database*. result An integer. Description Explicitly set the position of the sequence called name in database, which defaults to *default-database*, to position which is returned. Examples (sequence-last [foo]) => 4 (set-sequence-position [foo] 50) => 50 (sequence-next [foo]) => 51 Side Effects Modifies the value of the sequence name in database. Affected by *default-database* Exceptional Situations Will signal an error of type sql-database-data-error if a sequence called name does not exist in database. See Also create-sequence drop-sequence list-sequences sequence-exists-p sequence-last sequence-next Notes set-sequence-position is a &clsql; extension. TRUNCATE-DATABASE TRUNCATE-DATABASE Drop all tables, views, indexes and sequences in a database. Function Syntax truncate-database &key database => Arguments and Values database A database object. This will default to the value of *default-database*. Description Drop all tables, views, indexes and sequences in database which defaults to *default-database*. Examples (list-tables) => ("type_table" "type_bigint" "employee" "company" "addr" "ea_join" "big") (list-indexes) => ("employeepk" "companypk" "addrpk") (list-views) => ("lenins_group") (list-sequences) => ("foo" "bar") (truncate-database) => (list-tables) => NIL (list-indexes) => NIL (list-views) => NIL (list-sequences) => NIL Side Effects Modifications are made to the underlying database. Affected by None. Exceptional Situations Signals an error of type sql-database-error if database is not a database object. See Also drop-table drop-view drop-index drop-sequence Notes truncate-database is a &clsql; extension. cl-sql-6.7.2/doc/bookinfo.xml0000644000175000017500000000401711335067642015041 0ustar kevinkevin %myents; ]> &clsql; Users' Guide Kevin M. Rosenberg Maintainer of &clsql; Marcus T. Pearce Contributor to &clsql; Pierre R. Mai Author of Original MaiSQL Code onShore Development, Inc. Author of UncommonSQL Package &clsql; is Copyright © 2002-2010 by Kevin M. Rosenberg, Copyright © 1999-2001 by Pierre R. Mai, and Copyright © 1999-2003 onShore Development, Inc. Allegro CL® is a registered trademark of Franz Inc. Common SQL, LispWorks are trademarks or registered trademarks of LispWorks Ltd. Oracle® is a registered trademark of Oracle Inc. Microsoft Windows® is a registered trademark of Microsoft Inc. Other brand or product names are the registered trademarks or trademarks of their respective holders. cl-sql-6.7.2/doc/ref-lob.xml0000644000175000017500000001474610667176647014610 0ustar kevinkevin %myents; ]> Large Object Support CREATE-LARGE-OBJECT Function Syntax (CREATE-LARGE-OBJECT &KEY (DATABASE *DEFAULT-DATABASE*)) [function] => Arguments and Values Description Creates a new large object in the database and returns the object identifier Examples Side Effects Affected by Exceptional Situations See Also Notes DELETE-LARGE-OBJECT Function Syntax (DELETE-LARGE-OBJECT OBJECT-ID &KEY (DATABASE *DEFAULT-DATABASE*)) [function] => Arguments and Values Description Deletes the large object in the database Examples Side Effects Affected by Exceptional Situations See Also Notes READ-LARGE-OBJECT Function Syntax (READ-LARGE-OBJECT OBJECT-ID &KEY (DATABASE *DEFAULT-DATABASE*)) [function] => Arguments and Values Description Reads the large object content Examples Side Effects Affected by Exceptional Situations See Also Notes WRITE-LARGE-OBJECT Function Syntax (WRITE-LARGE-OBJECT OBJECT-ID DATA &KEY (DATABASE *DEFAULT-DATABASE*)) [function] => Arguments and Values Description Writes data to the large object Examples Side Effects Affected by Exceptional Situations See Also Notes cl-sql-6.7.2/doc/clsql.xml0000644000175000017500000000351410667176647014367 0ustar kevinkevin %myents; %xinclude; ]> cl-sql-6.7.2/doc/catalog-mandrake.xml0000644000175000017500000000262610667176647016446 0ustar kevinkevin cl-sql-6.7.2/doc/threading-warnings.txt0000644000175000017500000001004511746263021017036 0ustar kevinkevin============= suggested addition to documentation =============== == Threads and thread safety In a Lisp in which threading is internal, rather than done using OS threads, CLSQL should be threadsafe. Thus what follows will consider the case of Lisp threads also being OS threads. CLSQL attempts to be thread-safe, with important exceptions. The database pool used by CONNECT and WITH-DATABASE performs appropriate locking, so that it is possible to use pooled connections from different threads. As long as database objects (representing connections) are not passed among threads, WITH-DATABASE and CONNECT may be used by multiple threads. However, the database object contained in the VIEW-DATABASE slot of a STANDARD-DB-OBJECT persists even after the database is returned to the pool. Thus it is possible for one thread to read an object, return the database to pool, and then still possess a copy of the database inside the VIEW-DATABASE slot. Then UPDATE-RECORDS-FOR-INSTANCE, UPDATE-RECORD-FROM-SLOT, and UPDATE-RECORD-FROM-SLOTS (which always use the VIEW-DATABASE slot, if not NIL, rather than any supplied keyword argument DATABASE) can use the database even as a second thread as retrieved it from a pool, resulting in serious problems. Automatic updating using the internal VIEW-DATABASE slot also may be triggered by the global variable *DB-AUTO-SYNC*. This problem may been addressed by defining a new object class, and changing the method used to select the database during UPDATE-RECORDS-FOR-INSTANCE, etc. ;; define a threadsafe child class of STANDARD-DB-OBJECT (defclass clsql::threadsafe-db-obj (clsql-sys:standard-db-object) nil (:metaclass clsql-sys::standard-db-class)) ;; for this class, define threadsafe database chooser method that never uses the ;; internal VIEW-DATABASE slot (defmethod clsql-sys::choose-database-for-instance ((object clsql::threadsafe-db-obj) &optional database) (or database clsql-sys:*default-database* (signal-no-database-error nil))) ;; define a new sql database table that should be threadsafely UPDATE-able (clsql-sys:def-view-class my-table (clsql::threadsafe-db-obj) (…)) Alternatively, users may redefine *DB-POOL* and *DB-POOL-LOCK* on a per-thread basis using LET before entering the thread, which will prevent any cross-thread sharing of connections, possibly at the cost of having more connections. [** is this a valid approach **] *DB-POOL-LOCK* no longer necessary, however, if connection pools are per-thread. ==== Thread safety issues for the back-ends [** my best understanding **] * sqlite2 - sqlite2 is not threadsafe. * sqlite3 - sqlite3 after and including 3.3.1 is threadsafe if compiled in the default manner. According to sqlite3 documentation, connections may be moved across threads if and only if no transaction is pending and all statements have been finalized. * mysql - the mysql interface is missing initializations required for thread safety: 1) mysql_library_init() is not called in a multithreaded environment; 2) mysql_thread_init() is not called on a per-thread basis; and 3) mysql_thread_end() is not called before a thread terminates. The second item may lead to corruption according to mysql documentation, and the third item leads to memory leaks. Another issue with mysql is that it resets sigpipe in a way that renders SBCL unresponsive to interrupts, requiring additional saving and restoring of the signal handler. [** an example? **] Nevertheless, the present version of the mysql back end often works successfully even in a threaded environment, albeit with subtle problems. * postgreSQL - is probably threadsafe [No information] * postgreSQL socket - Is probably threadsafe -- has been used for a while without any observed errors. * ODBC - the Clsql side doesn't have additional issues beyond what's documented above. But this depends on what odbc driver your using. It appears to work with unixodbc and freetds. * AODBC - no information * Oracle - no information ============= end of suggested addition to documentation =============== cl-sql-6.7.2/doc/ref-transaction.xml0000644000175000017500000006710710667176647016360 0ustar kevinkevin %myents; ]> Transaction Handling This section describes the interface provided by &clsql; for handling database transactions. The interface allows for opening transaction blocks, committing or rolling back changes made and controlling autocommit behaviour. In contrast to &commonsql;, &clsql;, by default, starts in transaction AUTOCOMMIT mode (see set-autocommit). To begin a transaction in autocommit mode, start-transaction has to be called explicitly. START-TRANSACTION START-TRANSACTION Open a transaction block. Function Syntax start-transaction &key database => &nil; Arguments and Values database A database object. This will default to the value of *default-database*. Description Starts a transaction block on database which defaults to *default-database* and which continues until rollback or commit are called. Examples (in-transaction-p) => NIL (select [*] :from [foo] :field-names nil) => NIL (start-transaction) => NIL (in-transaction-p) => T (insert-records :into [foo] :av-pairs '(([bar] 1) ([baz] "one"))) => (select [*] :from [foo] :field-names nil) => ((1 "one")) (rollback) => NIL (in-transaction-p) => NIL (select [*] :from [foo] :field-names nil) => NIL Side Effects Autocommit mode is disabled and if database is currently within the scope of a transaction, all commit and rollback hooks are removed and the transaction level associated with database is modified. Affected by None. Exceptional Situations Signals an error of type sql-database-error if database is not a database object. See Also commit rollback in-transaction-p set-autocommit with-transaction Notes start-transaction is a &clsql; extension. COMMIT COMMIT Commit modifications made in the current transaction. Function Syntax commit &key database => &nil; Arguments and Values database A database object. This will default to the value of *default-database*. Description If database, which defaults to *default-database*, is currently within the scope of a transaction, commits changes made since the transaction began. Examples (in-transaction-p) => NIL (select [*] :from [foo] :field-names nil) => NIL (start-transaction) => NIL (in-transaction-p) => T (insert-records :into [foo] :av-pairs '(([bar] 1) ([baz] "one"))) => (select [*] :from [foo] :field-names nil) => ((1 "one")) (commit) => NIL (in-transaction-p) => NIL (select [*] :from [foo] :field-names nil) => ((1 "one")) Side Effects Changes made within the scope of the current transaction are committed in the underlying database and the transaction level of database is reset. Affected by The transaction level of database which indicates whether a transaction has been initiated by a call to start-transaction since the last call to rollback or commit. Exceptional Situations Signals an error of type sql-database-error if database is not a database object. A warning of type sql-warning is signalled if there is no transaction in progress. See Also start-transaction rollback in-transaction-p add-transaction-commit-hook set-autocommit with-transaction Notes None. ROLLBACK ROLLBACK Roll back modifications made in the current transaction. Function Syntax rollback &key database => &nil; Arguments and Values database A database object. This will default to the value of *default-database*. Description If database, which defaults to *default-database*, is currently within the scope of a transaction, rolls back changes made since the transaction began. Examples (in-transaction-p) => NIL (select [*] :from [foo] :field-names nil) => NIL (start-transaction) => NIL (in-transaction-p) => T (insert-records :into [foo] :av-pairs '(([bar] 1) ([baz] "one"))) => (select [*] :from [foo] :field-names nil) => ((1 "one")) (rollback) => NIL (in-transaction-p) => NIL (select [*] :from [foo] :field-names nil) => NIL Side Effects Changes made within the scope of the current transaction are reverted in the underlying database and the transaction level of database is reset. Affected by The transaction level of database which indicates whether a transaction has been initiated by a call to start-transaction since the last call to rollback or commit. Exceptional Situations Signals an error of type sql-database-error if database is not a database object. A warning of type sql-warning is signalled if there is no transaction in progress. See Also start-transaction commit in-transaction-p add-transaction-rollback-hook set-autocommit with-transaction Notes None. IN-TRANSACTION-P IN-TRANSACTION-P A predicate for testing whether a transaction is currently in progress. Function Syntax in-transaction-p &key database => result Arguments and Values database A database object. This will default to the value of *default-database*. result A Boolean. Description A predicate to test whether database, which defaults to *default-database*, is currently within the scope of a transaction. Examples (in-transaction-p) => NIL (start-transaction) => NIL (in-transaction-p) => T (commit) => NIL (in-transaction-p) => NIL Side Effects None. Affected by None. Exceptional Situations None. See Also start-transaction commit rollback set-autocommit Notes in-transaction-p is a &clsql; extension. ADD-TRANSACTION-COMMIT-HOOK ADD-TRANSACTION-COMMIT-HOOK Specify hooks to be run when committing changes. Function Syntax add-transaction-commit-hook commit-hook &key database => result Arguments and Values commit-hook A designator for a function with no required arguments. database A database object. This will default to the value of *default-database*. result The list of currently defined commit hooks for database. Description Adds commit-hook, which should a designator for a function with no required arguments, to the list of hooks run when commit is called on database which defaults to *default-database*. Examples (start-transaction) => NIL (add-transaction-commit-hook #'(lambda () (print "Successfully committed."))) => (#<Interpreted Function (LAMBDA # #) {48E2E689}>) (commit) "Successfully committed." => NIL Side Effects commit-hook is added to the list of commit hooks for database. Affected by None. Exceptional Situations If commit-hook has one or more required arguments, an error will be signalled when commit is called. See Also commit rollback add-transaction-rollback-hook with-transaction Notes add-transaction-commit-hook is a &clsql; extension. ADD-TRANSACTION-ROLLBACK-HOOK ADD-TRANSACTION-ROLLBACK-HOOK Specify hooks to be run when rolling back changes. Function Syntax add-transaction-rollback-hook rollback-hook &key database => result Arguments and Values rollback-hook A designator for a function with no required arguments. database A database object. This will default to the value of *default-database*. result The list of currently defined rollback hooks for database. Description Adds rollback-hook, which should a designator for a function with no required arguments, to the list of hooks run when rollback is called on database which defaults to *default-database*. Examples (start-transaction) => NIL (add-transaction-rollback-hook #'(lambda () (print "Successfully rolled back."))) => (#<Interpreted Function (LAMBDA # #) {48E37C31}>) (rollback) "Successfully rolled back." => NIL Side Effects rollback-hook is added to the list of rollback hooks for database. Affected by None. Exceptional Situations If rollback-hook has one or more required arguments, an error will be signalled when rollback is called. See Also commit rollback add-transaction-commit-hook Notes add-transaction-rollback-hook is a &clsql; extension. SET-AUTOCOMMIT SET-AUTOCOMMIT Turn on or off autocommit for a database. Function Syntax set-autocommit value &key database => result Arguments and Values value A Boolean specifying the desired autocommit behaviour for database. database A database object. This will default to the value of *default-database*. result The previous autocommit value for database. Description Turns autocommit off for database if value is &nil;, and otherwise turns it on. Returns the old value of autocommit flag. For RDBMS (such as Oracle) which don't automatically commit changes, turning autocommit on has the effect of explicitly committing changes made whenever SQL statements are executed. Autocommit is turned on by default. Examples Side Effects database is associated with the specified autocommit mode. Affected by None. Exceptional Situations None. See Also start-transaction commit add-transaction-commit-hook with-transaction Notes set-autocommit is a &clsql; extension. WITH-TRANSACTION WITH-TRANSACTION Execute a body of code within a transaction. Macro Syntax with-transaction &key database &rest body => result Arguments and Values database A database object. This will default to the value of *default-database*. body A body of Lisp code. result The result of executing body. Description Starts a transaction in the database specified by database, which is *default-database* by default, and executes body within that transaction. If body aborts or throws, database is rolled back and otherwise the transaction is committed. Examples (in-transaction-p) => NIL (select [email] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil) => ("lenin@soviet.org") (with-transaction () (update-records [employee] :av-pairs '((email "lenin-nospam@soviet.org")) :where [= [emplid] 1])) => NIL (select [email] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil) => ("lenin-nospam@soviet.org") (in-transaction-p) => NIL Side Effects Changes specified in body may be made to the underlying database if body completes successfully. Affected by None. Exceptional Situations Signals an error of type sql-database-error if database is not a database object. See Also start-transaction commit rollback add-transaction-commit-hook add-transaction-rollback-hook Notes None. cl-sql-6.7.2/doc/catalog-darwin.xml0000644000175000017500000000263110667176647016144 0ustar kevinkevin cl-sql-6.7.2/doc/mysql-macosx-notes.txt0000644000175000017500000000405310667176647017052 0ustar kevinkevinInstructions: ---------------- 1. Install MySQL from Fink, not from mysql.com It is sufficient to install the binaries from Fink. CLSQL requires the MySQL library libmysqlclient.dylib; this library is not provided with the mysql binary install. This library is in /sw/lib/mysql . However, it is actually called libmysqlclient.14.0.0.dylib . ----------------- 2. After installing MySQL, do the following at the shell. (Assuming that you do not want to have to load CLSQL as root user every time you use it.) 2a. Create a symbolic link from libmysqlclient.14.0.0.dylib to the name libmysqlclient.dylib . 2b. Change ownership to yourself along the path /sw/lib/mysql/ libmysqlclient.dylib . ----------------- 3. Either install CocoaMySQL or download the source of MySQL (e.g. 5.0) from mysql.com. CLSQL requires MySQL's header files. These files are not provided with Fink's binary MySQL install. In CocoaMySQL the headers are found at: /Applications/CocoaMySQL.app/ Contents/Frameworks/SMySQL.framework/Versions/A/Headers In MySQL 5.0 sources, the headers are found at: ~/Desktop/ mysql-5.0.15/include 3a. Copy the directory full of headers to /sw/include/mysql 3b. Make yourself the owner of these files. You may now dispose of CocoaMySQL or the MySQL sources, if you desire. ----------------- 4. In the CLSQL sources, modify db-mysql/makefile to read as follows: ... CFLAGS="-I /sw/include/mysql" LDFLAGS=" -L/sw/lib/mysql/ ... ----------------- 5. In Lisp, do the following: Assuming asdf and the CLSQL & UFFI sources are in the same directory; substitute the appropriate path for ~ . The code below is right out of the CLSQL docs, but note particularly the commented expression. (load "~/asdf.lisp") (progn (push "~/uffi-1.5.5/" asdf:*central-registry*) (asdf:operate 'asdf:load-op :uffi) (push "~/clsql-3.3.4/" asdf:*central-registry*) (asdf:operate 'asdf:load-op :clsql)) (progn (in-package :clsql) (setf *default-database-type* :mysql) (clsql:push-library-path "/sw/lib/mysql/") ; !! (asdf:operate 'asdf:load-op 'clsql-mysql)) cl-sql-6.7.2/doc/COPYING.GFDL0000644000175000017500000004076010667176647014301 0ustar kevinkevin GNU Free Documentation License Version 1.1, March 2000 Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 0. PREAMBLE The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. 1. APPLICABILITY AND DEFINITIONS This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque". Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only. The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. 2. VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. 3. COPYING IN QUANTITY If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. 4. MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five). C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. H. Include an unaltered copy of this License. I. Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version. N. Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements." 6. COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. 7. AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate. 8. TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail. 9. TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 10. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation 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. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. cl-sql-6.7.2/doc/ref-conditions.xml0000644000175000017500000007541210667176647016202 0ustar kevinkevin %myents; ]> CLSQL Condition System &clsql; provides and uses a condition system in which all errors and warnings are of type sql-condition. This section describes the various subclasses of sql-condition defined by &clsql;. Details are also provided for how they are used in &clsql; and intended to be signalled in user code. Finally, slot accessors for some of the condition types are described. *BACKEND-WARNING-BEHAVIOR* *BACKEND-WARNING-BEHAVIOR* Controls behaviour on warnings from underlying RDBMS. Variable Value Type Meaningful values are :warn, :error, :ignore and &nil;. Initial Value :warn Description Action to perform on warning messages from backend. Default is to :warn. May also be set to :error to signal an error or :ignore or &nil; to silently ignore the warning. Examples Affected By None. See Also None. Notes *backend-warning-behaviour* is a &clsql; extension. SQL-CONDITION SQL-CONDITION the super-type of all &clsql;-specific conditions Condition Type Class Precedence List sql-condition condition t Description This is the super-type of all &clsql;-specific conditions defined by &clsql;, or any of it's database-specific interfaces. There are no defined initialization arguments nor any accessors. Notes sql-condition is a &clsql; extension. SQL-ERROR SQL-ERROR the super-type of all &clsql;-specific errors Condition Type Class Precedence List sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This is the super-type of all &clsql;-specific conditions that represent errors, as defined by &clsql;, or any of it's database-specific interfaces. There are no defined initialization arguments nor any accessors. Notes sql-error is a &clsql; extension. SQL-WARNING SQL-WARNING the super-type of all &clsql;-specific warnings Condition Type Class Precedence List sql-warning warning sql-condition condition t Description This is the super-type of all &clsql;-specific conditions that represent warnings, as defined by &clsql;, or any of it's database-specific interfaces. There are no defined initialization arguments nor any accessors. Notes sql-warning is a &clsql; extension. SQL-DATABASE-WARNING SQL-DATABASE-WARNING Used to warn while accessing a &clsql; database. Condition Type Class Precedence List sql-database-warning sql-warning warning sql-condition condition t Description This condition represents warnings signalled while accessing a database. The following initialization arguments and accessors exist: Initarg Accessor Description :database sql-warning-database The database object that was involved in the incident. Notes sql-database-warning is a &clsql; extension. SQL-USER-ERROR SQL-USER-ERROR condition representing errors because of invalid parameters from the library user. Condition Type Class Precedence List sql-user-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors that occur because the user supplies invalid data to &clsql;. This includes errors such as an invalid format connection specification or an error in the syntax for the LOOP macro extensions. The following initialization arguments and accessors exist: Initarg Accessor Description :message sql-user-error-message The error message. Notes The slot accessor sql-user-error-message is a &clsql; extension. SQL-DATABASE-ERROR SQL-DATABASE-ERROR condition representing errors during query or command execution Condition Type Class Precedence List sql-database-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors that occur while executing SQL statements, either as part of query operations or command execution, either explicitly or implicitly, as caused e.g. by with-transaction. The following initialization arguments and accessors exist: Initarg Accessor Description :database sql-error-database The database object that was involved in the incident. :error-id sql-error-error-id The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :secondary-error-id sql-error-secondary-error-id The secondary numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :message sql-error-database-message A string describing the problem that occurred, possibly one returned by the database back-end. Notes The slot accessor sql-error-database is a &clsql; extension. SQL-CONNECTION-ERROR SQL-CONNECTION-ERROR condition representing errors during connection Condition Type Class Precedence List sql-connection-error sql-database-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors that occur while trying to connect to a database. The following initialization arguments and accessors exist: Initarg Accessor Description :database-type sql-error-database-type Database type for the connection attempt :connection-spec sql-error-connection-spec The connection specification used in the connection attempt. :database sql-error-database The database object that was involved in the incident. :error-id sql-error-error-id The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :secondary-error-id sql-error-secondary-error-id The secondary numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :message sql-database-error-error A string describing the problem that occurred, possibly one returned by the database back-end. Notes The slot accessors sql-error-database, sql-error-database-type and sql-error-connection-spec are &clsql; extensions. SQL-DATABASE-DATA-ERROR SQL-DATABASE-DATA-ERROR Used to signal an error with the SQL data passed to a database. Condition Type Class Precedence List sql-database-data-error sql-database-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors that occur while executing SQL statements, specifically as a result of malformed SQL expressions. The following initialization arguments and accessors exist: Initarg Accessor Description :expression sql-error-expression The SQL expression whose execution caused the error. :database sql-error-database The database object that was involved in the incident. :error-id sql-error-error-id The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :secondary-error-id sql-error-secondary-error-id The secondary numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :message sql-error-database-message A string describing the problem that occurred, possibly one returned by the database back-end. Notes The slot accessors sql-error-database and sql-error-expression are &clsql; extensions. SQL-TEMPORARY-ERROR SQL-TEMPORARY-ERROR Used to signal a temporary error in the database backend. Condition Type Class Precedence List sql-temporary-error sql-database-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors occurring when the database cannot currently process a valid interaction because, for example, it is still executing another command possibly issued by another user. The following initialization arguments and accessors exist: Initarg Accessor Description :database sql-error-database The database object that was involved in the incident. :error-id sql-error-error-id The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :secondary-error-id sql-error-secondary-error-id The secondary numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :message sql-error-database-message A string describing the problem that occurred, possibly one returned by the database back-end. Notes The slot accessor sql-error-database is a &clsql; extension. SQL-TIMEOUT-ERROR SQL-TIMEOUT-ERROR condition representing errors when a connection times out. Condition Type Class Precedence List sql-connection-error sql-database-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors that occur when the database times out while processing some operation. The following initialization arguments and accessors exist: Initarg Accessor Description :database-type sql-error-database-type Database type for the connection attempt :connection-spec sql-error-connection-spec The connection specification used in the connection attempt. :database sql-error-database The database object that was involved in the incident. :error-id sql-error-error-id The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :secondary-error-id sql-error-secondary-error-id The secondary numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :message sql-error-database-message A string describing the problem that occurred, possibly one returned by the database back-end. Notes The slot accessors sql-error-database, sql-error-database-type and sql-error-connection-spec are &clsql; extensions. SQL-FATAL-ERROR SQL-FATAL-ERROR condition representing a fatal error in a database connection Condition Type Class Precedence List sql-connection-error sql-database-error sql-error simple-error simple-condition error serious-condition sql-condition condition t Description This condition represents errors occurring when the database connection is no longer usable. The following initialization arguments and accessors exist: Initarg Accessor Description :database-type sql-error-database-type Database type for the connection attempt :connection-spec sql-error-connection-spec The connection specification used in the connection attempt. :database sql-error-database The database object that was involved in the incident. :error-id sql-error-error-id The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :secondary-error-id sql-error-secondary-error-id The secondary numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :message sql-error-database-message A string describing the problem that occurred, possibly one returned by the database back-end. Notes The slot accessors sql-error-database, sql-error-database-type and sql-error-connection-spec are &clsql; extensions. cl-sql-6.7.2/doc/csql.xml0000644000175000017500000005750111345753563014210 0ustar kevinkevin %myents; ]> &commonsql; Tutorial Based on the &usql; Tutorial Introduction The goal of this tutorial is to guide a new developer thru the process of creating a set of &clsql; classes providing a Object-Oriented interface to persistent data stored in an &sql; database. We will assume that the reader is familiar with how &sql; works, how relations (tables) should be structured, and has created at least one &sql; application previously. We will also assume a minor level of experience with Common Lisp. &clsql; provides two different interfaces to &sql; databases, a Functional interface, and an Object-Oriented interface. The Functional interface consists of a special syntax for embedded &sql; expressions in Lisp, and provides lisp functions for &sql; operations like SELECT and UPDATE. The object-oriented interface provides a way for mapping Common Lisp Objects System (CLOS) objects into databases and includes functions for inserting new objects, querying objects, and removing objects. Most applications will use a combination of the two. &clsql; is based on the CommonSQL package from LispWorks Ltd, so the documentation that LispWorks makes available online is useful for &clsql; as well. It is suggested that developers new to &clsql; read their documentation as well, as any differences between CommonSQL and &clsql; are minor. LispWorks makes the following documents available: &lw; User Guide - The &commonsql; Package &lw; Reference Manual - The SQL Package &commonsql; Tutorial by Nick Levine Data Modeling with &clsql; Before we can create, query and manipulate &clsql; objects, we need to define our data model as noted by Philip Greenspun Philip Greenspun's "SQL For Web Nerds" - Data Modeling When data modeling, you are telling the relational database management system (RDBMS) the following: What elements of the data you will store. How large each element can be. What kind of information each element can contain. What elements may be left blank. Which elements are constrained to a fixed range. Whether and how various tables are to be linked. With &sql; database one would do this by defining a set of relations, or tables, followed by a set of queries for joining the tables together in order to construct complex records. However, with &clsql; we do this by defining a set of CLOS classes, specifying how they will be turned into tables, and how they can be joined to one another via relations between their attributes. The &sql; tables, as well as the queries for joining them together are created for us automatically, saving us from dealing with some of the tedium of &sql;. Let us start with a simple example of two &sql; tables, and the relations between them. CREATE TABLE EMPLOYEE ( emplid NOT NULL number(38), first_name NOT NULL varchar2(30), last_name NOT NULL varchar2(30), email varchar2(100), companyid NOT NULL number(38), managerid number(38)) CREATE TABLE COMPANY ( companyid NOT NULL number(38), name NOT NULL varchar2(100), presidentid NOT NULL number(38)) This is of course the canonical &sql; tutorial example, "The Org Chart". In &clsql;, we would have two "view classes" (a fancy word for a class mapped into a database). They would be defined as follows: (clsql:def-view-class employee () ((emplid :db-kind :key :db-constraints :not-null :type integer :initarg :emplid) (first-name :accessor first-name :type (string 30) :initarg :first-name) (last-name :accessor last-name :type (string 30) :initarg :last-name) (email :accessor employee-email :type (string 100) :nulls-ok t :initarg :email) (companyid :type integer :initarg :companyid) (managerid :type integer :nulls-ok t :initarg :managerid)) (:base-table employee)) (clsql:def-view-class company () ((companyid :db-kind :key :db-constraints :not-null :type integer :initarg :companyid) (name :type (string 100) :initarg :name) (presidentid :type integer :initarg :presidentid)) (:base-table company)) The DEF-VIEW-CLASS macro is just like the normal CLOS DEFCLASS macro, except that it handles several slot options that DEFCLASS doesn't. These slot options have to do with the mapping of the slot into the database. We only use a few of the slot options in the above example, but there are several others. :column - The name of the &sql; column this slot is stored in. Defaults to the slot name. If the slot name is not a valid &sql; identifier, it is escaped, so foo-bar becomes foo_bar. :db-kind - The kind of database mapping which is performed for this slot. :base indicates the slot maps to an ordinary column of the database view. :key indicates that this slot corresponds to part of the unique keys for this view, :join indicates a join slot representing a relation to another view and :virtual indicates that this slot is an ordinary CLOS slot. Defaults to :base. :db-reader - If a string, then when reading values from the database, the string will be used for a format string, with the only value being the value from the database. The resulting string will be used as the slot value. If a function then it will take one argument, the value from the database, and return the value that should be put into the slot. :db-writer - If a string, then when reading values from the slot for the database, the string will be used for a format string, with the only value being the value of the slot. The resulting string will be used as the column value in the database. If a function then it will take one argument, the value of the slot, and return the value that should be put into the database. :db-type - A string which will be used as the type specifier for this slots column definition in the database. :void-value - The Lisp value to return if the field is &null;. The default is &nil;. :db-info - A join specification. In our example each table as a primary key attribute, which is required to be unique. We indicate that a slot is part of the primary key (&clsql; supports multi-field primary keys) by specifying the :db-kind key slot option. The &sql; type of a slot when it is mapped into the database is determined by the :type slot option. The argument for the :type option is a Common Lisp datatype. The &clsql; framework will determine the appropriate mapping depending on the database system the table is being created in. If we really wanted to determine what &sql; type was used for a slot, we could specify a :db-type option like "NUMBER(38)" and we would be guaranteed that the slot would be stored in the database as a NUMBER(38). This is not recomended because it could makes your view class unportable across database systems. DEF-VIEW-CLASS also supports some class options, like :base-table. The :base-table option specifies what the table name for the view class will be when it is mapped into the database. Another class option is :normalizedp, which signals &clsql; to use a normalized schema for the mapping from slots to &sql; columns. By default &clsql; includes all the slots of a parent class that map to &sql; columns into the child class. This option tells &clsql; to normalize the schema, so that a join is done on the primary keys of the concerned tables to get a complete column set for the classes. For more information, see def-view-class. Class Relations In an &sql; only application, the EMPLOYEE and COMPANY tables can be queried to determine things like, "Who is Vladimir's manager?", "What company does Josef work for?", and "What employees work for Widgets Inc.". This is done by joining tables with an &sql; query. Who works for Widgets Inc.? SELECT first_name, last_name FROM employee, company WHERE employee.companyid = company.companyid AND company.company_name = "Widgets Inc." Who is Vladimir's manager? SELECT managerid FROM employee WHERE employee.first_name = "Vladimir" AND employee.last_name = "Lenin" What company does Josef work for? SELECT company_name FROM company, employee WHERE employee.first_name = "Josef" AND employee.last-name = "Stalin" AND employee.companyid = company.companyid With &clsql; however we do not need to write out such queries because our view classes can maintain the relations between employees and companies, and employees to their managers for us. We can then access these relations like we would any other attribute of an employee or company object. In order to do this we define some join slots for our view classes. What company does an employee work for? If we add the following slot definition to the employee class we can then ask for it's COMPANY slot and get the appropriate result. ;; In the employee slot list (company :accessor employee-company :db-kind :join :db-info (:join-class company :home-key companyid :foreign-key companyid :set nil)) Who are the employees of a given company? And who is the president of it? We add the following slot definition to the company view class and we can then ask for it's EMPLOYEES slot and get the right result. ;; In the company slot list (employees :reader company-employees :db-kind :join :db-info (:join-class employee :home-key companyid :foreign-key companyid :set t)) (president :reader president :db-kind :join :db-info (:join-class employee :home-key presidentid :foreign-key emplid :set nil)) And lastly, to define the relation between an employee and their manager: ;; In the employee slot list (manager :accessor employee-manager :db-kind :join :db-info (:join-class employee :home-key managerid :foreign-key emplid :set nil)) &clsql; join slots can represent one-to-one, one-to-many, and many-to-many relations. Above we only have one-to-one and one-to-many relations, later we will explain how to model many-to-many relations. First, let's go over the slot definitions and the available options. In order for a slot to be a join, we must specify that it's :db-kind :join, as opposed to :base or :key. Once we do that, we still need to tell &clsql; how to create the join statements for the relation. This is what the :db-info option does. It is a list of keywords and values. The available keywords are: :join-class - The view class to which we want to join. It can be another view class, or the same view class as our object. :home-key - The slot(s) in the immediate object whose value will be compared to the foreign-key slot(s) in the join-class in order to join the two tables. It can be a single slot-name, or it can be a list of slot names. :foreign-key - The slot(s) in the join-class which will be compared to the value(s) of the home-key. :set - A boolean which if false, indicates that this is a one-to-one relation, only one object will be returned. If true, than this is a one-to-many relation, a list of objects will be returned when we ask for this slots value. There are other :join-info options available in &clsql;, but we will save those till we get to the many-to-many relation examples. Object Oriented Class Relations &clsql; provides an Object Oriented Data Definition Language, which provides a mapping from &sql; tables to CLOS objects. By default class inheritance is handled by including all the columns from parent classes into the child class. This means your database schema becomes very much denormalized. The class option :normalizedp can be used to disable the default behaviour and have &clsql; normalize the database schemas of inherited classes. See def-view-class for more information. Object Creation Now that we have our model laid out, we should create some object. Let us assume that we have a database connect set up already. We first need to create our tables in the database: Note: the file examples/clsql-tutorial.lisp contains view class definitions which you can load into your list at this point in order to play along at home. (clsql:create-view-from-class 'employee) (clsql:create-view-from-class 'company) Then we will create our objects. We create them just like you would any other CLOS object: (defvar company1 (make-instance 'company :companyid 1 :presidentid 1 :name "Widgets Inc.")) (defvar employee1 (make-instance 'employee :emplid 1 :first-name "Vladimir" :last-name "Lenin" :email "lenin@soviet.org" :companyid 1)) (defvar employee2 (make-instance 'employee :emplid 2 :first-name "Josef" :last-name "Stalin" :email "stalin@soviet.org" :companyid 1 :managerid 1)) In order to insert an objects into the database we use the UPDATE-RECORDS-FROM-INSTANCE function as follows: (clsql:update-records-from-instance employee1) (clsql:update-records-from-instance employee2) (clsql:update-records-from-instance company1) After you make any changes to an object, you have to specifically tell &clsql; to update the &sql; database. The UPDATE-RECORDS-FROM-INSTANCE method will write all of the changes you have made to the object into the database. Since &clsql; objects are just normal CLOS objects, we can manipulate their slots just like any other object. For instance, let's say that Lenin changes his email because he was getting too much spam from the German Socialists. ;; Print Lenin's current email address, change it and save it to the ;; database. Get a new object representing Lenin from the database ;; and print the email ;; This lets us use the functional &clsql; interface with [] syntax (clsql:locally-enable-sql-reader-syntax) (format t "The email address of ~A ~A is ~A" (first-name employee1) (last-name employee1) (employee-email employee1)) (setf (employee-email employee1) "lenin-nospam@soviets.org") ;; Update the database (clsql:update-records-from-instance employee1) (let ((new-lenin (car (clsql:select 'employee :where [= [slot-value 'employee 'emplid] 1])))) (format t "His new email is ~A" (employee-email new-lenin))) Everything except for the last LET expression is already familiar to us by now. To understand the call to CLSQL:SELECT we need to discuss the Functional &sql; interface and it's integration with the Object Oriented interface of &clsql;. Finding Objects Now that we have our objects in the database, how do we get them out when we need to work with them? &clsql; provides a functional interface to &sql;, which consists of a special Lisp reader macro and some functions. The special syntax allows us to embed &sql; in lisp expressions, and lisp expressions in &sql;, with ease. Once we have turned on the syntax with the expression: (clsql:locally-enable-sql-reader-syntax) We can start entering fragments of &sql; into our lisp reader. We will get back objects which represent the lisp expressions. These objects will later be compiled into &sql; expressions that are optimized for the database backed we are connected to. This means that we have a database independent &sql; syntax. Here are some examples: ;; an attribute or table name [foo] => #<CLSQL-SYS::SQL-IDENT-ATTRIBUTE FOO> ;; a attribute identifier with table qualifier [foo bar] => #<CLSQL-SYS::SQL-IDENT-ATTRIBUTE FOO.BAR> ;; a attribute identifier with table qualifier [= "Lenin" [first_name]] => #<CLSQL-SYS::SQL-RELATIONAL-EXP ('Lenin' = FIRST_NAME)> [< [emplid] 3] => #<CLSQL-SYS::SQL-RELATIONAL-EXP (EMPLID < 3)> [and [< [emplid] 2] [= [first_name] "Lenin"]] => #<CLSQL-SYS::SQL-RELATIONAL-EXP ((EMPLID < 2) AND (FIRST_NAME = 'Lenin'))> ;; If we want to reference a slot in an object we can us the ;; SLOT-VALUE sql extension [= [slot-value 'employee 'emplid] 1] => #<CLSQL-SYS::SQL-RELATIONAL-EXP (EMPLOYEE.EMPLID = 1)> [= [slot-value 'employee 'emplid] [slot-value 'company 'presidentid]] => #<CLSQL-SYS::SQL-RELATIONAL-EXP (EMPLOYEE.EMPLID = COMPANY.PRESIDENTID)> The SLOT-VALUE operator is important because it let's us query objects in a way that is robust to any changes in the object->table mapping, like column name changes, or table name changes. So when you are querying objects, be sure to use the SLOT-VALUE &sql; extension. Since we can now formulate &sql; relational expression which can be used as qualifiers, like we put after the WHERE keyword in &sql; statements, we can start querying our objects. &clsql; provides a function SELECT which can return use complete objects from the database which conform to a qualifier, can be sorted, and various other &sql; operations. The first argument to SELECT is a class name. it also has a set of keyword arguments which are covered in the documentation. For now we will concern ourselves only with the :where keyword. Select returns a list of objects, or nil if it can't find any. It's important to remember that it always returns a list, so even if you are expecting only one result, you should remember to extract it from the list you get from SELECT. ;; all employees (clsql:select 'employee) ;; all companies (clsql:select 'company) ;; employees named Lenin (clsql:select 'employee :where [= [slot-value 'employee 'last-name] "Lenin"]) (clsql:select 'company :where [= [slot-value 'company 'name] "Widgets Inc."]) ;; Employees of Widget's Inc. (clsql:select 'employee :where [and [= [slot-value 'employee 'companyid] [slot-value 'company 'companyid]] [= [slot-value 'company 'name] "Widgets Inc."]]) ;; Same thing, except that we are using the employee ;; relation in the company view class to do the join for us, ;; saving us the work of writing out the &sql;! (company-employees company1) ;; President of Widgets Inc. (president company1) ;; Manager of Josef Stalin (employee-manager employee2) Deleting Objects Now that we know how to create objects in our database, manipulate them and query them (including using our predefined relations to save us the trouble writing alot of &sql;) we should learn how to clean up after ourself. It's quite simple really. The function DELETE-INSTANCE-RECORDS will remove an object from the database. However, when we remove an object we are responsible for making sure that the database is left in a correct state. For example, if we remove a company record, we need to either remove all of it's employees or we need to move them to another company. Likewise if we remove an employee, we should make sure to update any other employees who had them as a manager. Conclusion There are many nooks and crannies to &clsql;, some of which are covered in the Xanalys documents we refered to earlier, some are not. The best documentation at this time is still the source code for &clsql; itself and the inline documentation for its various functions. cl-sql-6.7.2/doc/catalog-suse.xml0000644000175000017500000000262210667176647015637 0ustar kevinkevin cl-sql-6.7.2/doc/ref-clsql.xml0000644000175000017500000024046111251607553015126 0ustar kevinkevin %myents; ]> <symbol>CLSQL</symbol> This part gives a reference to the symbols exported from the CLSQL package. These symbols constitute the normal user-interface of &clsql;. Currently, the symbols of the &commonsql;-API are not documented here. SQL-CONDITION the super-type of all &clsql;-specific conditions Condition Type Class Precedence List sql-condition condition t Description This is the super-type of all &clsql;-specific conditions defined by &clsql;, or any of it's database-specific interfaces. There are no defined initialization arguments nor any accessors. SQL-ERROR the super-type of all &clsql;-specific errors Condition Type Class Precedence List sql-error error serious-condition sql-condition condition t Description This is the super-type of all &clsql;-specific conditions that represent errors, as defined by &clsql;, or any of it's database-specific interfaces. There are no defined initialization arguments nor any accessors. SQL-WARNING the super-type of all &clsql;-specific warnings Condition Type Class Precedence List sql-warning warning sql-condition condition t Description This is the super-type of all &clsql;-specific conditions that represent warnings, as defined by &clsql;, or any of it's database-specific interfaces. There are no defined initialization arguments nor any accessors. CLSQL-USER-ERROR condition representing errors because of invalid parameters from the library user. Condition Type Class Precedence List sql-error sql-condition condition t Description This condition represents errors that occur because the user supplies invalid data to &clsql;. This includes errors such as an invalid format connection specification or an error in the syntax for the LOOP macro extensions. SQL-CONNECTION-ERROR condition representing errors during connection Condition Type Class Precedence List sql-connection-error sql-database-error sql-error sql-condition condition t Description This condition represents errors that occur while trying to connect to a database. The following initialization arguments and accessors exist: Initarg Accessor Description :database-type sql-connection-error-database-type Database type for the connection attempt :connection-spec sql-connection-error-connection-spec The connection specification used in the connection attempt. :errno sql-connection-error-errno The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :error sql-connection-error-error A string describing the problem that occurred, possibly one returned by the database back-end. SQL-DATABASE-ERROR condition representing errors during query or command execution Condition Type Class Precedence List sql-database-error sql-error error serious-condition sql-condition condition t Description This condition represents errors that occur while executing SQL statements, either as part of query operations or command execution, either explicitly or implicitly, as caused e.g. by with-transaction. The following initialization arguments and accessors exist: Initarg Accessor Description :database sql-database-error-database The database object that was involved in the incident. :expression sql-database-error-expression The SQL expression whose execution caused the error. :errno sql-database-error-errno The numeric or symbolic error specification returned by the database back-end. The values and semantics of this are interface specific. :error sql-database-error-error A string describing the problem that occurred, possibly one returned by the database back-end. *DEFAULT-DATABASE-TYPE* The default database type to use Variable Value Type Any keyword representing a valid database back-end of &clsql;, or nil. Initial Value nil Description The value of this variable is used in calls to initialize-database-type and connect as the default value of the database-type parameter. If the value of this variable is nil, then all calls to initialize-database-type or connect will have to specify the database-type to use, or a general-purpose error will be signalled. Examples (setf *default-database-type* :mysql) => :mysql (initialize-database-type) => t Affected By None. See Also None. Notes None. *INITIALIZED-DATABASE-TYPES* List of all initialized database types Variable Value Type A list of all initialized database types, each of which represented by it's corresponding keyword. Initial Value nil Description This variable is updated whenever initialize-database-type is called for a database type which hasn't already been initialized before, as determined by this variable. In that case the keyword representing the database type is pushed onto the list stored in *INITIALIZED-DATABASE-TYPES*. Attempts to modify the value of this variable will result in undefined behaviour. Examples (setf *default-database-type* :mysql) => :mysql (initialize-database-type) => t *initialized-database-types* => (:MYSQL) Affected By initialize-database-type See Also None. Notes Direct access to this variable is primarily provided because of compatibility with Harlequin's Common SQL. INITIALIZE-DATABASE-TYPE Initializes a database type Function Syntax initialize-database-type &key database-type => result Arguments and Values database-type The database type to initialize, i.e. a keyword symbol denoting a known database back-end. Defaults to the value of *default-database-type*. result Either nil if the initialization attempt fails, or t otherwise. Description If the back-end specified by database-type has not already been initialized, as seen from *initialized-database-types*, an attempt is made to initialize the database. If this attempt succeeds, or the back-end has already been initialized, the function returns t, and places the keyword denoting the database type onto the list stored in *initialized-database-types*, if not already present. If initialization fails, the function returns nil, and/or signals an error of type clsql-error. The kind of action taken depends on the back-end and the cause of the problem. Examples *initialized-database-types* => NIL (setf *default-database-type* :mysql) => :MYSQL (initialize-database-type) >> Compiling LAMBDA (#:G897 #:G898 #:G901 #:G902): >> Compiling Top-Level Form: >> => T *initialized-database-types* => (:MYSQL) (initialize-database-type) => T *initialized-database-types* => (:MYSQL) Side Effects The database back-end corresponding to the database type specified is initialized, unless it has already been initialized. This can involve any number of other side effects, as determined by the back-end implementation (like e.g. loading of foreign code, calling of foreign code, networking operations, etc.). If initialization is attempted and succeeds, the database-type is pushed onto the list stored in *initialized-database-types*. Affected by *default-database-type* *initialized-database-types* Exceptional Situations If an error is encountered during the initialization attempt, the back-end may signal errors of kind clsql-error. See Also None. Notes None. *CONNECT-IF-EXISTS* Default value for the if-exists parameter of connect. Variable Value Type A valid argument to the if-exists parameter of connect, i.e. one of :new :warn-new :error :warn-old :old . Initial Value :error Description The value of this variable is used in calls to connect as the default value of the if-exists parameter. See connect for the semantics of the valid values for this variable. Examples None. Affected By None. See Also connect Notes None. CONNECTED-DATABASES Return the list of active database objects. Function Syntax connected-databases => databases Arguments and Values databases The list of active database objects. Description This function returns the list of active database objects, i.e. all those database objects created by calls to connect, which have not been closed by calling disconnect on them. The consequences of modifying the list returned by connected-databases are undefined. Examples (connected-databases) => NIL (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {4830BC65}> (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {4830C5AD}> (connected-databases) => (#<CLSQL-MYSQL:MYSQL-DATABASE {4830C5AD}> #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {4830BC65}>) (disconnect) => T (connected-databases) => (#<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {4830BC65}>) (disconnect) => T (connected-databases) => NIL Side Effects None. Affected By connect disconnect Exceptional Situations None. See Also None. Notes None. *DEFAULT-DATABASE* The default database object to use Variable Value Type Any object of type database, or nil to indicate no default database. Initial Value nil Description Any function or macro in &clsql; that operates on a database uses the value of this variable as the default value for it's database parameter. The value of this parameter is changed by calls to connect, which sets *default-database* to the database object it returns. It is also changed by calls to disconnect, when the database object being disconnected is the same as the value of *default-database*. In this case disconnect sets *default-database* to the first database that remains in the list of active databases as returned by connected-databases, or nil if no further active databases exist. The user may change *default-database* at any time to a valid value of his choice. If the value of *default-database* is nil, then all calls to &clsql; functions on databases must provide a suitable database parameter, or an error will be signalled. Examples (connected-databases) => NIL (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48385F55}> (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {483868FD}> (connect '("dent" "newesim" "dent" "dent") :database-type :mysql :if-exists :new) => #<CLSQL-MYSQL:MYSQL-DATABASE {48387265}> *default-database* => #<CLSQL-MYSQL:MYSQL-DATABASE {48387265}> (disconnect) => T *default-database* => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {483868FD}> (disconnect) => T *default-database* => #<CLSQL-MYSQL:MYSQL-DATABASE {48385F55}> (disconnect) => T *default-database* => NIL (connected-databases) => NIL Affected By connect disconnect See Also connected-databases Notes This variable is intended to facilitate working with &clsql; in an interactive fashion at the top-level loop, and because of this, connect and disconnect provide some fairly complex behaviour to keep *default-database* set to useful values. Programmatic use of &clsql; should never depend on the value of *default-database* and should provide correct database objects via the database parameter to functions called. DATABASE The super-type of all &clsql; databases Class Class Precedence List database standard-object t Description This class is the superclass of all &clsql; databases. The different database back-ends derive subclasses of this class to implement their databases. No instances of this class are ever created by &clsql;. CLOSED-DATABASE The class representing all closed &clsql; databases Class Class Precedence List closed-database standard-object t Description &clsql; database instances are changed to this class via change-class after they are closed via disconnect. All functions and generic functions that take database objects as arguments will signal errors of type clsql-closed-error when they are called on instances of closed-database, with the exception of database-name, which will continue to work as for instances of database. DATABASE-NAME Get the name of a database object Generic Function Syntax database-name database => name Arguments and Values database A database object, either of type database or of type closed-database. name A string describing the identity of the database to which this database object is connected to. Description This function returns the database name of the given database. The database name is a string which somehow describes the identity of the database to which this database object is or has been connected. The database name of a database object is determined at connect time, when a call to database-name-from-spec derives the database name from the connection specification passed to connect in the connection-spec parameter. The database name is used via find-database in connect to determine whether database connections to the specified database exist already. Usually the database name string will include indications of the host, database name, user, or port that where used during the connection attempt. The only important thing is that this string shall try to identify the database at the other end of the connection. Connection specifications parts like passwords and credentials shall not be used as part of the database name. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48391DCD}> (database-name *default-database*) => "dent/newesim/dent" (database-name-from-spec '(nil "template1" "dent" nil) :postgresql) => "/template1/dent" (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-name *default-database*) => "/template1/dent" (database-name-from-spec '("www.pmsf.de" "template1" "dent" nil) :postgresql) => "www.pmsf.de/template1/dent" Side Effects None. Affected By database-name-from-spec Exceptional Situations Will signal an error if the object passed as the database parameter is neither of type database nor of type closed-database. See Also connect find-database Notes None. FIND-DATABASE Locate a database object through it's name. Function Syntax find-database database &optional errorp => result Arguments and Values database A database object or a string, denoting a database name. errorp A generalized boolean. Defaults to t. result Either a database object, or, if errorp is nil, possibly nil. Description find-database locates an active database object given the specification in database. If database is an object of type database, find-database returns this. Otherwise it will search the active databases as indicated by the list returned by connected-databases for a database whose name (as returned by database-name is equal as per string= to the string passed as database. If it succeeds, it returns the first database found. If it fails to find a matching database, it will signal an error of type clsql-error if errorp is true. If errorp is nil, it will return nil instead. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48391DCD}> (database-name *default-database*) => "dent/newesim/dent" (database-name-from-spec '(nil "template1" "dent" nil) :postgresql) => "/template1/dent" (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-name *default-database*) => "/template1/dent" (database-name-from-spec '("www.pmsf.de" "template1" "dent" nil) :postgresql) => "www.pmsf.de/template1/dent" (find-database "dent/newesim/dent") => #<CLSQL-MYSQL:MYSQL-DATABASE {484E91C5}> (find-database "/template1/dent") => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (find-database "www.pmsf.de/template1/dent" nil) => NIL (find-database **) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> Side Effects None. Affected By connected-databases Exceptional Situations Will signal an error of type clsql-error if no matching database can be found, and errorp is true. Will signal an error if the value of database is neither an object of type database nor a string. See Also database-name database-name-from-spec Notes None. CONNECT create a connection to a database Function Syntax connect connection-spec &key if-exists database-type pool => database Arguments and Values connection-spec A connection specification if-exists This indicates the action to take if a connection to the same database exists already. See below for the legal values and actions. It defaults to the value of *connect-if-exists*. database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* pool A boolean flag. If &t;, acquire connection from a pool of open connections. If the pool is empty, a new connection is created. The default is &nil;. database The database object representing the connection. Description This function takes a connection specification and a database type and creates a connection to the database specified by those. The type and structure of the connection specification depend on the database type. The parameter if-exists specifies what to do if a connection to the database specified exists already, which is checked by calling find-database on the database name returned by database-name-from-spec when called with the connection-spec and database-type parameters. The possible values of if-exists are: :new Go ahead and create a new connection. :warn-new This is just like :new, but also signals a warning of type clsql-exists-warning, indicating the old and newly created databases. :error This will cause connect to signal a correctable error of type clsql-exists-error. The user may choose to proceed, either by indicating that a new connection shall be created, via the restart create-new, or by indicating that the existing connection shall be used, via the restart use-old. :old This will cause connect to use an old connection if one exists. :warn-old This is just like :old, but also signals a warning of type clsql-exists-warning, indicating the old database used, via the slots old-db and new-db The database name of the returned database object will be the same under string= as that which would be returned by a call to database-name-from-spec with the given connection-spec and database-type parameters. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48036F6D}> (database-name *) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) >> In call to CONNECT: >> There is an existing connection #<CLSQL-MYSQL:MYSQL-DATABASE {48036F6D}> to database dent/newesim/dent. >> >> Restarts: >> 0: [CREATE-NEW] Create a new connection. >> 1: [USE-OLD ] Use the existing connection. >> 2: [ABORT ] Return to Top-Level. >> >> Debug (type H for help) >> >> (CONNECT ("dent" "newesim" "dent" "dent") :IF-EXISTS NIL :DATABASE-TYPE ...) >> Source: >> ; File: /prj/CLSQL/sql/sql.cl >> (RESTART-CASE (ERROR 'CLSQL-EXISTS-ERROR :OLD-DB OLD-DB) >> (CREATE-NEW NIL :REPORT "Create a new connection." >> (SETQ RESULT #)) >> (USE-OLD NIL :REPORT "Use the existing connection." >> (SETQ RESULT OLD-DB))) >> 0] 0 => #<CLSQL-MYSQL:MYSQL-DATABASE {480451F5}> Side Effects A database connection is established, and the resultant database object is registered, so as to appear in the list returned by connected-databases. Affected by *default-database-type* *connect-if-exists* Exceptional Situations If the connection specification is not syntactically or semantically correct for the given database type, an error of type clsql-invalid-spec-error is signalled. If during the connection attempt an error is detected (e.g. because of permission problems, network trouble or any other cause), an error of type sql-connection-error is signalled. If a connection to the database specified by connection-spec exists already, conditions are signalled according to the if-exists parameter, as described above. See Also connected-databases disconnect Notes None. DISCONNECT close a database connection Function Syntax disconnect &key database pool => t Arguments and Values pool A boolean flag indicating whether to put the database into a pool of opened databases. If &t;, rather than terminating the database connection, the connection is left open and the connection is placed into a pool of connections. Subsequent calls to connect can then reuse this connection. The default is &nil;. database The database to disconnect, which defaults to the database indicated by *default-database*. Description This function takes a database object as returned by connect, and closes the connection. The class of the object passed is changed to closed-database after the disconnection succeeds, thereby preventing further use of the object as an argument to &clsql; functions, with the exception of database-name. If the user does pass a closed database object to any other &clsql; function, an error of type clsql-closed-error is signalled. Examples (disconnect :database (find-database "dent/newesim/dent")) => T Side Effects The database connection is closed, and the database object is removed from the list of connected databases as returned by connected-databases. The class of the database object is changed to closed-database. If the database object passed is the same under eq as the value of *default-database*, then *default-database* is set to the first remaining database from connected-databases or to nil if no further active database exists. Affected by *default-database* Exceptional Situations If during the disconnection attempt an error is detected (e.g. because of network trouble or any other cause), an error of type clsql-error might be signalled. See Also connect closed-database Notes None. DISCONNECT-POOLED closes all pooled database connections Function Syntax disconnect-pool => t Description This function disconnects all database connections that have been placed into the pool. Connections are placed in the pool by calling disconnection. Examples (disconnect-pool) => T Side Effects Database connections will be closed and entries in the pool are removed. Affected by disconnect Exceptional Situations If during the disconnection attempt an error is detected (e.g. because of network trouble or any other cause), an error of type clsql-error might be signalled. See Also connect closed-database Notes None. CREATE-DATABASE create a database Function Syntax create-database connection-spec &key database-type => success Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* success A boolean flag. If &t;, a new database was successfully created. Description This function creates a database in the database system specified by database-type. Examples (create-database '("localhost" "new" "dent" "dent") :database-type :mysql) => T (create-database '("localhost" "new" "dent" "badpasswd") :database-type :mysql) => Error: While trying to access database localhost/new/dent using database-type MYSQL: Error database-create failed: mysqladmin: connect to server at 'localhost' failed error: 'Access denied for user: 'root@localhost' (Using password: YES)' has occurred. [condition type: CLSQL-ACCESS-ERROR] Side Effects A database will be created on the filesystem of the host. Exceptional Situations An exception will be thrown if the database system does not allow new databases to be created or if database creation fails. Notes This function may invoke the operating systems functions. Thus, some database systems may require the administration functions to be available in the current PATH. At this time, the :mysql backend requires mysqladmin and the :postgresql backend requires createdb. DESTROY-DATABASE destroys a database Function Syntax destroy-database connection-spec &key database-type => success Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* success A boolean flag. If &t;, the database was successfully destroyed. Description This function destroy a database in the database system specified by database-type. Examples (destroy-database '("localhost" "new" "dent" "dent") :database-type :postgresql) => T (destroy-database '("localhost" "new" "dent" "dent") :database-type :postgresql) => Error: While trying to access database localhost/test2/root using database-type POSTGRESQL: Error database-destroy failed: dropdb: database removal failed: ERROR: database "test2" does not exist has occurred. [condition type: CLSQL-ACCESS-ERROR] Side Effects A database will be removed from the filesystem of the host. Exceptional Situations An exception will be thrown if the database system does not allow databases to be removed, the database does not exist, or if database removal fails. Notes This function may invoke the operating systems functions. Thus, some database systems may require the administration functions to be available in the current PATH. At this time, the :mysql backend requires mysqladmin and the :postgresql backend requires dropdb. PROBE-DATABASE tests for existence of a database Function Syntax probe-database connection-spec &key database-type => success Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* success A boolean flag. If &t;, the database exists in the database system. Description This function tests for the existence of a database in the database system specified by database-type. Examples (probe-database '("localhost" "new" "dent" "dent") :database-type :postgresql) => T Side Effects None Exceptional Situations An exception maybe thrown if the database system does not receive administrator-level authentication since function may need to read the administrative database of the database system. Notes None. DATABASE-NAME-FROM-SPEC Return the database name string corresponding to the given connection specification. Generic Function Syntax database-name-from-spec connection-spec database-type => name Arguments and Values connection-spec A connection specification, whose structure and interpretation are dependent on the database-type. database-type A database type specifier, i.e. a keyword. name A string denoting a database name. Description This generic function takes a connection specification and a database type and returns the database name of the database object that would be created had connect been called with the given connection specification and database types. This function is useful in determining a database name from the connection specification, since the way the connection specification is converted into a database name is dependent on the database type. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48391DCD}> (database-name *default-database*) => "dent/newesim/dent" (database-name-from-spec '(nil "template1" "dent" nil) :postgresql) => "/template1/dent" (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-name *default-database*) => "/template1/dent" (database-name-from-spec '("www.pmsf.de" "template1" "dent" nil) :postgresql) => "www.pmsf.de/template1/dent" (find-database "dent/newesim/dent") => #<CLSQL-MYSQL:MYSQL-DATABASE {484E91C5}> (find-database "/template1/dent") => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (find-database "www.pmsf.de/template1/dent" nil) => NIL (find-database **) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> Side Effects None. Affected by None. Exceptional Situations If the value of connection-spec is not a valid connection specification for the given database type, an error of type clsql-invalid-spec-error might be signalled. See Also connect Notes None. EXECUTE-COMMAND Execute an SQL command which returns no values. Function Syntax execute-command sql-expression &key database => t Arguments and Values sql-expression An sql expression that represents an SQL statement which will return no values. database A database object. This will default to the value of *default-database*. Description This will execute the command given by sql-expression in the database specified. If the execution succeeds it will return t, otherwise an error of type sql-database-error will be signalled. Examples (execute-command "create table eventlog (time char(30),event char(70))") => T (execute-command "create table eventlog (time char(30),event char(70))") >> >> While accessing database #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {480B2B6D}> >> with expression "create table eventlog (time char(30),event char(70))": >> Error NIL: ERROR: amcreate: eventlog relation already exists >> has occurred. >> >> Restarts: >> 0: [ABORT] Return to Top-Level. >> >> Debug (type H for help) >> >> (CLSQL-POSTGRESQL::|(PCL::FAST-METHOD DATABASE-EXECUTE-COMMAND (T POSTGRESQL-DATABASE))| >> #<unused-arg> >> #<unused-arg> >> #<unavailable-arg> >> #<unavailable-arg>) >> Source: (ERROR 'SQL-DATABASE-ERROR :DATABASE DATABASE :EXPRESSION ...) >> 0] 0 (execute-command "drop table eventlog") => T Side Effects Whatever effects the execution of the SQL statement has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL statement leads to any errors, an error of type sql-database-error is signalled. See Also query Notes None. QUERY Execute an SQL query and return the tuples as a list Function Syntax query query-expression &key database result-types field-names => result Arguments and Values query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set. database A database object. This will default to the value of *default-database*. result-types A field type specifier. The default is &nil;. The purpose of this argument is cause &clsql; to import SQL numeric fields into numeric Lisp objects rather than strings. This reduces the cost of allocating a temporary string and the &clsql; users' inconvenience of converting number strings into number objects. A value of :auto causes &clsql; to automatically convert SQL fields into a numeric format where applicable. The default value of &nil; causes all fields to be returned as strings regardless of the SQL type. Otherwise a list is expected which has a element for each field that specifies the conversion. If the list is shorter than the number of fields, the a value of t is assumed for the field. If the list is longer than the number of fields, the extra elements are ignored. :int Field is imported as a signed integer, from 8-bits to 64-bits depending upon the field type. :double Field is imported as a double-float number. t Field is imported as a string. field-names A boolean with a default value of &t;. When &t;, this function results a second value of a list of field names. When &nil;, this function only returns one value - the list of rows. result A list representing the result set obtained. For each tuple in the result set, there is an element in this list, which is itself a list of all the attribute values in the tuple. Description This will execute the query given by query-expression in the database specified. If the execution succeeds it will return the result set returned by the database, otherwise an error of type sql-database-error will be signalled. Examples (execute-command "create table simple (name char(50), salary numeric(10,2))") => T (execute-command "insert into simple values ('Mai, Pierre',10000)") => T (execute-command "insert into simple values ('Hacker, Random J.',8000.50)") => T (query "select * from simple") => (("Mai, Pierre" "10000.00") ("Hacker, Random J." "8000.50")) (query "select salary from simple") => (("10000.00") ("8000.50")) (query "select salary from simple where salary > 10000") => NIL (query "select salary,name from simple where salary > 10000") => NIL (query "select salary,name from simple where salary > 9000") => (("10000.00" "Mai, Pierre")) (query "select salary,name from simple where salary > 8000") => (("10000.00" "Mai, Pierre") ("8000.50" "Hacker, Random J.")) ;; MySQL-specific: (query "show tables") => (("demo") ("log") ("newlog") ("simple") ("spacetrial")) Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. See Also execute-command Notes None. MAP-QUERY Map a function over all the tuples from a query Function Syntax map-query output-type-spec function query-expression &key database result-types => result Arguments and Values output-type-spec A sequence type specifier or nil. function A function designator. function takes a single argument which is the atom value for a query single with a single column or is a list of values for a multi-column query. query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set. database A database object. This will default to the value of *default-database*. result-types A field type specifier. The default is &nil;. See query for the semantics of this argument. result If output-type-spec is a type specifier other than nil, then a sequence of the type it denotes. Otherwise nil is returned. Description Applies function to the successive tuples in the result set returned by executing the SQL query-expression. If the output-type-spec is nil, then the result of each application of function is discarded, and map-query returns nil. Otherwise the result of each successive application of function is collected in a sequence of type output-type-spec, where the jths element is the result of applying function to the attributes of the jths tuple in the result set. The collected sequence is the result of the call to map-query. If the output-type-spec is a subtype of list, the result will be a list. If the result-type is a subtype of vector, then if the implementation can determine the element type specified for the result-type, the element type of the resulting array is the result of upgrading that element type; or, if the implementation can determine that the element type is unspecified (or *), the element type of the resulting array is t; otherwise, an error is signaled. Examples (map-query 'list #'(lambda (tuple) (multiple-value-bind (salary name) tuple (declare (ignorable name)) (read-from-string salary))) "select salary,name from simple where salary > 8000") => (10000.0 8000.5) (map-query '(vector double-float) #'(lambda (tuple) (multiple-value-bind (salary name) tuple (declare (ignorable name)) (let ((*read-default-float-format* 'double-float)) (coerce (read-from-string salary) 'double-float)) "select salary,name from simple where salary > 8000"))) => #(10000.0d0 8000.5d0) (type-of *) => (SIMPLE-ARRAY DOUBLE-FLOAT (2)) (let (list) (values (map-query nil #'(lambda (tuple) (multiple-value-bind (salary name) tuple (push (cons name (read-from-string salary)) list)) "select salary,name from simple where salary > 8000") list)) => NIL => (("Hacker, Random J." . 8000.5) ("Mai, Pierre" . 10000.0)) Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. An error of type type-error must be signaled if the output-type-spec is not a recognizable subtype of list, not a recognizable subtype of vector, and not nil. An error of type type-error should be signaled if output-type-spec specifies the number of elements and the size of the result set is different from that number. See Also query do-query Notes None. DO-QUERY Iterate over all the tuples of a query Macro Syntax do-query ((&rest args) query-expression &key database result-types) &body body => nil Arguments and Values args A list of variable names. query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set, where each tuple has as many attributes as function takes arguments. database A database object. This will default to *default-database*. result-types A field type specifier. The default is &nil;. See query for the semantics of this argument. body A body of Lisp code, like in a destructuring-bind form. Description Executes the body of code repeatedly with the variable names in args bound to the attributes of each tuple in the result set returned by executing the SQL query-expression on the database specified. The body of code is executed in a block named nil which may be returned from prematurely via return or return-from. In this case the result of evaluating the do-query form will be the one supplied to return or return-from. Otherwise the result will be nil. The body of code appears also is if wrapped in a destructuring-bind form, thus allowing declarations at the start of the body, especially those pertaining to the bindings of the variables named in args. Examples (do-query ((salary name) "select salary,name from simple") (format t "~30A gets $~2,5$~%" name (read-from-string salary))) >> Mai, Pierre gets $10000.00 >> Hacker, Random J. gets $08000.50 => NIL (do-query ((salary name) "select salary,name from simple") (return (cons salary name))) => ("10000.00" . "Mai, Pierre") Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. If the number of variable names in args and the number of attributes in the tuples in the result set don't match up, an error is signalled. See Also query map-query Notes None. LOOP-FOR-AS-TUPLES Iterate over all the tuples of a query via a loop clause Loop Clause Compatibility loop-for-as-tuples only works with &cmucl;. Syntax var [type-spec] being {each | the} {record | records | tuple | tuples} {in | of} query [from database] Arguments and Values var A d-var-spec, as defined in the grammar for loop-clauses in the ANSI Standard for Common Lisp. This allows for the usual loop-style destructuring. type-spec An optional type-spec either simple or destructured, as defined in the grammar for loop-clauses in the ANSI Standard for Common Lisp. query An sql expression that represents an SQL query which is expected to return a (possibly empty) result set, where each tuple has as many attributes as function takes arguments. database An optional database object. This will default to the value of *default-database*. Description This clause is an iteration driver for loop, that binds the given variable (possibly destructured) to the consecutive tuples (which are represented as lists of attribute values) in the result set returned by executing the SQL query expression on the database specified. Examples (defvar *my-db* (connect '("dent" "newesim" "dent" "dent")) "My database" => *MY-DB* (loop with time-graph = (make-hash-table :test #'equal) with event-graph = (make-hash-table :test #'equal) for (time event) being the tuples of "select time,event from log" from *my-db* do (incf (gethash time time-graph 0)) (incf (gethash event event-graph 0)) finally (flet ((show-graph (k v) (format t "~40A => ~5D~%" k v))) (format t "~&Time-Graph:~%===========~%") (maphash #'show-graph time-graph) (format t "~&~%Event-Graph:~%============~%") (maphash #'show-graph event-graph)) (return (values time-graph event-graph))) >> Time-Graph: >> =========== >> D => 53000 >> X => 3 >> test-me => 3000 >> >> Event-Graph: >> ============ >> CLOS Benchmark entry. => 9000 >> Demo Text... => 3 >> doit-text => 3000 >> C Benchmark entry. => 12000 >> CLOS Benchmark entry => 32000 => #<EQUAL hash table, 3 entries {48350A1D}> => #<EQUAL hash table, 5 entries {48350FCD}> Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. Otherwise, any of the exceptional situations of loop applies. See Also query map-query do-query Notes None. cl-sql-6.7.2/doc/catalog-suse91.xml0000644000175000017500000000326610667176647016016 0ustar kevinkevin cl-sql-6.7.2/doc/ref-prepared.xml0000644000175000017500000001640410667176647015627 0ustar kevinkevin %myents; ]> Prepared Statements PREPARE-SQL >PREPARE-SQL Create a prepared statement. Function Syntax prepare-sql sql-stmt types &key database result-types field-names => result Arguments and Values Description Prepares a SQL statement sql-stmt for execution. types contains a list of types corresponding to the input parameters. Returns a prepared-statement object. A type can be :int :double :null (:string n) Examples Side Effects Affected by Exceptional Situations See Also Notes RUN-PREPARED-SQL RUN-PREPARED-SQL Execute a prepared statement. Function Syntax run-prepared-sql prepared-stmt => Arguments and Values Description Execute the prepared sql statment. All input parameters must be bound. Examples Side Effects Affected by Exceptional Situations See Also Notes FREE-PREPARED-SQL FREE-PREPARED-SQL Delete a prepared statement object. Function Syntax free-prepared-sql prepared-stmt => Arguments and Values Description Delete the objects associated with a prepared statement. Examples Side Effects Affected by Exceptional Situations See Also Notes BIND-PARAMETER BIND-PARAMETER Bind a parameter in a prepared statement. Function Syntax bind-parameter prepared-stmt position value => Arguments and Values Description Sets the value of a parameter in a prepared statement. Examples Side Effects Affected by Exceptional Situations See Also Notes cl-sql-6.7.2/doc/catalog-debian.xml0000644000175000017500000000266210667176647016106 0ustar kevinkevin cl-sql-6.7.2/doc/html.tar.gz0000644000175000017500000037262112570445315014614 0ustar kevinkevin‹ÍJâUì=írÛF’þ>Å·6¡]â7õi™[”HǺ’%­H'Îmm¥†ÀDJâ^]Õ=Ä=@ž%rOrÝó/‚$@R¶’«‹ÄLOOwOOÍ`âOÍê«§ýÔàs¸¿ÿÖ÷kÑÕçU½±Xkµö›uhW¯×ZWdÿÕøÌ<Ÿº„¼ºc÷†µ¢ÝºçÐÏùož_öéÐd^xþ´ZKø_o4šÍÿ¡]½Ußo¾"µþ?ùçôoS“Ü3×3lë]±^© ³4[7¬ñ»â§ÁûòQ‘‰,š¶ÅÞ-»ø·váôߺ×烟nzå…Ü|:»¼8'Årµúcó¼Zíºäó‡ÁÇKÉÀ¥–gø05«ÕÞU‘'¾ïœT«•‡fÅvÇÕÁmõaÕ±³ü³ìGzVt_/¶Oùx€³å½KR?>>±)£zûtÊ|J°e™ý:3îßÏmËg–_ÌV$šøö®è³G¿Š=ßmB]ùïäô«íSßðMÖ¾¼èʃÎÙe¯Z? ðiÆÌb.õm7µkkg¶}G>÷/Iߟà ›0æ{ä‡zåð¨RçÀMú#.3aBöPš¸lô®hX:{ä˱HøX€ùeÿï—ä“ÜúŽ|?3t–è?sToø_y¤ëfÀû™¥ j’.¼»ldXœ¾ä’Zã3Rzßí^¾Nv\v¯@ë®ímÞ½½¾ÔIt¶€²ª3ïWf q¼²Àû–{ŸÊýò R<Úú¼}ª÷D3©œ·è=>a.°™ƒ$†îO@€kµ¿‚ÀΦSêÎ߯è½1¦|‚a{þ›‹LÏ¡ óÍ"¡¦1†¿4`6‰óyhð>øŸ®jà8²ŸÉF>¦„jó¼;#;ËÈÕ¾ZžViû÷ß®Îq‘0"0.ÙY&PMÇÐ5Æ@†Œ!i­bKû ø†ˆ 49 ª¼!,-—s8c À´Ý9'†¡eÂ~CX‘ÖœíL ˜ Wü‚+¹Ñ¾‚/ ö©åùßÿþrËü™ky„Ø#¢©†ÔcDîj§žïÚÖ8 æiUþpZuÒ÷˜æ×ƒyºsØj·jÇr€InùôQ"å2ÕÙ›[¶ã0ááŸSP§ÁÓ‘Ä ØŽÐæ´ŠMÚä[:uÞgÈ)›†¸8&Õ¶ƒ¡y;ûìsZeÓöšöб.ï¾ûoÉ)®°+Òñžš3èê2ofÿ±’Ée9uxPªãŽgS ॓¾'ÈuO]‘F²@WÝ\öÀodžU2…ŸC8ÔYá‹g ¹‚I!,]G‘’¬RŸìy.l{qæZǽиº¸TL³Ý8½ùthÃò9¡¦)Gª|)tú&“Iãe–ù+Âþ#C›(pÙ#¾è‘:¥7²}YA{£&¸³ù)±Ë7;µî×¼eèTuS qFQnÖŽšP”»ÌÓ\Ã:Dh£Eí#±€ÝV‚ß„&â–‚G K©†œœ^ʶœì"¹Ö‹Ãð2¬†á\a'q2°áˆ?¡@ËœKLp[ÏМ‘#PТHD¦WÈÅ(’ˆ•¤,©®àòQ8ñ÷ұ؄[b»Šsݤcìã¦Â92l!&àÙºÞ¬íGtsïöSéãè6¦¹ŒÁ6U(E6*rÂgBŠ#—éÅ×±‰”Š>ØÒ?ó&`Üó/Ccl€h"ðöœá͞ŒæðÕuŸÑŸ± °BŠÐÀ¥Ž…´GrÆ?ëᄞðÃØµÑòÅ?×ÖÄ_.{p Ÿ‰/>·õñ/ꃄ gð€âO k Wð Lpñ§í(Ó^|‹ô¡ÓÚŽú5DÅ”†šú掙вéxì2°R#(Žã1“£qf[ê›F=ÙëözñÕ›PÝ~ˆL˶¤_'žëÌa–R–iQ5„eC»°¡ÔT^Þ"*>ØÜžohŠÕR’Ýôæ°-šõýÆA+b„Dz£´T2nWà²{o¾UrpP;ŠX0|®*ɧz7Bæ¨U«E—¬Æéô Æý›Nþø°%1c¤cz¶AìcCäÇ}W¬Eœ­¾š„ë¦b@þ›4Ý„…cɧè#*Ô ,4Çòü¶×ô¤kÙ^bMG»Š6滬=ƒS»lä°ëãæð‡—‘ŽƒòÛ²J@c¿^‹HÀ•í³ì¶0xë#ÛÛ¡ð3úìA¯¸ïÝÚïê-+ß;u–[irBb§ã¸+ï{ ȽüæÃ&Ô%w“ÉNRÂPí6úàYæGå÷ß⢼T0«"ÐÃÃpíW/Ÿ/ÿç<~šØÿúø­yØh%ò?ÍæáþKüÿ%þÿÌâÿ¸Nž{ä“ÞÑð¾÷«YÑj–™ëÚnÀ)¿ï :—åÞííõíŠ@¿f" d:¦3¡CΘ¯œ¢°Í»ü˜;Œes\¿bì_ñx˨*s†þy«Cú Ø0žï‚:ÀHò’À½ê0ê±ç¡E)vaMJòNêqcqÉø>xÐhrªðý€³Û¹†½x?Œ‹ŽÉè£JO„ø-#U!¤±ÉÄ(ÎÌulp Û<=qnÐ 1çC þή¢ o® P~5+:£,¯´.[µv-˹¬ã„"{&r6‘ÛµáÌí?$.{ÄX5Z;7×ÔìךµdýÇa£ñbÿ½ØÏÌþC¥Ñû|sÛë÷/®¯þ% OQ'ÂJFú|ï14‚ÐD{µI¸`®0ýPˆx¹Ò&1ûñú¦wÛ¿¢•·ÀÉíͽL¼%¼ØÆîK¡þ.*9â{Ä‹9â¬OHÌ4^0ÀÉŽLF®=ö;Ži0ÀÜlW'T•ì¤Ô£Ù8¬×;+õˆ/(óP9ÓU™C‘Ð\Vì±Ð<‡^×DŠzÙ[«ÔYvl@Å~¡¢`Ùa½ù|ŠNù–RÇ ÊL*ÛTL,°<} ®eâ% 4Q'ÄÄ'#ƒ¹[a´ V©‰!yÛíFKËì4°H`WóOŠ}úô¡ñ¦e/ëšIJ–ü€ßÉCG+(¡ T•È…3ÍÆq=–D\U8³ ã5µ€†çúÞ‡}Réü úB­oYgBçdº×ž ,ê øO¦i?x'"8bløljü‹érqÏÌÔ°6çh³ð’þw‰uB`wµ4ÃÕLö–Ñ {ž –wÝŠ 5LùÕ.(µÌ’òø6ZŽ&˜lO„l7“¯†ÌÂÞ‡…|¹¶Ö<<øq1…pÙ'±{"~-:,Leïÿ¡0ü™ùë‰Fd®Uñl¦±[D2ã±hWRñ¨ÎòšÍúþAë(W cÂ;¶çw#Û&'¡ù÷ݺªÒð/ßšþ[m)÷êŸà¿ÝÞÕ Ü n/Î> zäýõuå¬s‹Í ‹CÄÀþ+سÎpTÇi[5Õq¼l'3ܬd,†ãÀóל5›Z=êp¯®qëX„§"B“6µ¸ Y‚…¿Ë2™Ÿú½[™Èl¯ðÜC‘⪰&Ú3Æ€¥ ô0FhËÎ,´Tm)$¬Qž\¢Ø_BR®€¾IÍЯq-ëý25{©Á¤Ü @.s0q[!&Bbü5¤ºï¢68}T‹®‰Õæ%×ö³J"îº/ÜÞA^ÆÀiÞ4ã3H-ÆÊKñÝË'‘ÿ´~éú¿z«Öl%ò¿Íüó’ÿ}Éÿ>¯üo®³Øú"Á FÑŠòÀl§=¾^†8ï¹ûm‹ãÔü²•‚ ¼øZ¥‚j#Ömd,(t¨ë–ïÚ Ñ"p`c©Šù ;>ö„M åyßS6mËÒ¬h¢GœÜt\ûÖžKEæÒ½”) é'z<½Á¹- a¼ ºò,ˆô)Á¬$óç±DrÏkæLϼŠC”{äÞ`ð¬Âäp=ЄÈ*¯BUEd–”sklw*–Ú3Ÿh3˜ì›ü/O³,àÇS)xž†¤‘ ºÎù·ÇgŒ¬“hb!… ˜á(ˆ)³G:¶'¨ƒ¸Š˜KfÁ@€'çdÆçK’.®¤¨:Ë^1Êá,äg+ñì^F¤A…'ƒ2#Ô;B'yÙT⺕Œe¸òcäROb%/eDq«×ã5œ(ì&.:±’wAI)m¸ÀãÂöÃEïÇ-dÜ\Ô"øpIË… š·d¸ qí•3Äf'b& o„vM âõT2¶9 ¥ˆEÃRÆ.®º½Ï[™¹¹”EQâb–¡¤BÛ.gÑ#tRÒ8B»Qi úFøñÎIqãÈ=•¼mAÌ`;ç™'uCåFÊèræ&(¢Ê³˜-ˆ’„¶ÃŒ#€8ÚùaÑüBì ý¶ûqhT¥N ¿Í#–Zˆ$Öå ßJ#)6®”ú½¿ê]och€7WM ܸvÊYRAm‡—Èèf„Ç ±è©p„°TÝ“ÊJáøTúj;ÚXC3?‰ñe§?ÈIYŽ*Â"Ìd˜%EðØb4&‰íUïsvl/,X‹?D˜#¡È–a\#’—é÷BÉ-ß\÷/Df##æ}&}nu§xƒËni¨£<åFÜ~º:G-Õí€GÑéçÕÁ P«}ú¸´TV/|^‡ ×ÅÀžò„a¦Xî#†*ú ’€ñ@ÄKðåäÿÔ]U¢d«l2kìOv— \sÿÇÁa½™¸ÿã Þ:xÉÿ½äÿžYþïM·÷¾óéLð‹®¾/_ö®¾|xóG8jÛ —_‹S!×®Û¾"Çr}½æJp! ®^Ö‡e‘H$«nç¶[îž•¯Ïþ½w>XŸäA2<üQæ¦Ij’ÍÞß^,Ÿƒ¡ÝÿŠéÂ墱mnp isfó2{ùÄTîâ(jêvµÃ©Kx)Lqy·­ý\†êÚa•^úAžÜèšñãúÁqôä?ºH¼à_VÛ~óÞx´fÓüu¢úqó z}æòŸšâ|¤‚¿ª¬»±¿?Ú–gìýVôRÍ”#a…o.ÐóLÛ>$‡óÂ7Ëna%Ç%Ž?Q'k Oý0Xó´µÝÕ]î©‹{EòüÑmðÃ,˜Ã„ÞctIHKá› ÆwOÜêsœý `«Î"æ3Oc +|#²X~\«å+—7™OJ¥7© í 9ª½Æ»[Kq’ï¨FJâR×R‰’qÀ‘w•W½–†ò×’¼¦YBÂGš|$Iú>Ñ’ù¾RƒÝaùœׇáþ³uTë´šõîÉ"ütÕC¾Ü$¸B)žã#ÿ€gÿTc âU÷(xDŸí{Ÿ M®}Âp ÷ÿµI­áÕ_çþÏÆAíð âÿ7±þ·örÿÓ‹ÿÿìüî4}„ÝÌDã…oôêZ¶gÐÎiO¨Úì÷ßP:ÁÎ5˜Âà¬põ·…óô1è¿&àq“í–™âÌßWtêSø½ÓÑí£Ú¦Oض|R;UI«âêVñÛ7ˆ(Ûm}q#^g¬8k&£î Ú*8âE:7Ã4ò=z6ž3 ^t¤²£ùVEÒz¿q|œ:Eã¡£Üà-`3g¡YûõÂ3'<Ž+ü+E¾ÑñäoóšÛ3^ ì3“s wWjjYS  ÅSÜÞÜóÁ×)ÝvÏ>ö_ó~âv€r’Zr¼å%3ºáiË®—ÁIþˆ/T’AƒÏçø`à³°T•´äÄ?Bú`?þN¨6 ŠP憺sDî`ƒB$¢%K Ðp¤†•d07y±êA24©u—€Ž-JÒƒ—ÜA¦dd<Ÿ``Œ3M’}]¾ì&@/ ÓØ3/úJ&ÀŽé•Ôë BÉ\­K"ê6¬®‡U÷`ÏLŒ-‰HÑPÖà‹‹¼À\úKøJ¢acå‹,ò*V©êÀµ‰ÁD‰ ¾›'r~`¢J©ajc1}Ã"ü 9N6¸£ ƒŽÉaX ž/_¹b`Xî=êD¸Š`–]÷%0Î_ßæØYš‹ulú<Ào¡3/é%y’c.×'”#d u„Ĺ7hHyhæ?0â3ÔQ†H•!WÊ$>LÛäÚyáœ/ù‡O§!ϸðËØr¤–Â&Ž‹T£¦9€q°ó·tFÃ}ÏÃx ¤2ݘMñ[ì+)Šùxàãå øÀ7q±I>Öƒ“>À/@0¹¢œ˜FÑ ãpŽk]:å+ÞÛ…X@®÷ñæòú§^”¾ïÊÐÅE×rõéò’X³é¹¥æÑë½Äk ÃÏÈp=Ÿ¿¯+ì'ÃcR³¶¢'Ö‰Žy{²)5ÌÄoAO0Wt•ïò™暦Ø/]I!i9ý^ât=¿þxÓ¹ú È/×€‚.$ÎlsÄ{ZÄmzÚ¯ aXEþ@&50|ðÌÆ„›d¶ÅïêÎ&¤ÒnV¾Gø=¼×)îúÅJA-’ k·ÊÍ8¹wðt.,~A©Æ")ÁvH- ô!ÞN‚ZBf^ S])ưªìµÐ_s T¢ÊÐDnÝ+¬]f%~¯ûI" ^*'’ ¥’Xtœ‘'ú°ÌMð(‚_Â÷×yä”qÙš™¦xÊS ð€XŠ_0á Æ9`yú¡Ä×gÅI4^ !ù –½€å—€6pqõ¦Mü¾jÐZå ;PѬyƒŠ‹AüŒÄñÊöñ]ÅÁ‚\KÅ ¥èh€e—Žô¹¥3QŽL5HºÈH,”Ä$Ðß¡Ð$¦»„…!±ƒŽ!û"šgíp‘¶‹d‘¸Ät•4+ÒS¤ÝÞ{Y–Ae‘"R͵Q¿ý2ó|°_ï˜ÜE-´äMnJ­€¸kt^Þ$Þùj £'°7£!é¡A0E~×û3o–m…©Uë;_( ¬Õ‚úÍFÛ0HáC¦¨Ãо@¤¥']&^( f9ï†y˜³‚Œô Æ0,I‘ ôùPœÏÀÓ¯. fÊMCO*÷/ç–½WV³ÍÙT]ðJÊ\\ø6*§ši3@„ùÍiƒÿ¢³‰…0±ºáŠCâ@@ç‹Qü'ìŽÉEʳ!z&ø áu½{ g†yu0½îÙ˜-+© »¬n(Û?ÃwÄo­¿GV¾œW*”8• ¸lJðøÁêðº0‡¹è#Kk< aeÙ`âÐb$iÁ¼ˆÆÉcqRSî uçŠK‘Ð@xpåôøÍä‰Å* 9žè&ÇÆÜpðj<]¯Æ›Yx(xã™NÇÞ[2*z/ñw¤†ƒSîÛˆ‘7X+;_Ì^ybì!rŒþäÞpý,Æ¥³1¼å¸ÊãL‘P¢Ò¼–K•õâµNº\£åKÅÈ7ÒóÊ‘ü6 =7^Hâ…÷%+Ž‹ÃörkR/¯-†žˆØ¨[èä úäQÔ¨ ™ ™‰ï #)r xT o¥Æi#K–ŸjJjs5|ÑÙ§w"¢®ÏÛKAFB'à†kDkÎo¢¬Wgæ‡;B”ñ[s’¿ƒz[Nr2©CLkÙªhan.¶Š¬äA¨¦Ì•JG@ ^sŸØh9òð8J—覜»iÈlÍ`q¯bo'  @¦PH!»ý=¾xŠŠzXŸ)¬Ž…•¶ú÷¶¡—ïEå_t+»4ûI:8ž¼œrÝó“É_÷hѧ&>_mOèí?þ€ËYîÙ1¦sEËú<¾éyt’ø“SøŠ“ú…o£Ô€Ü=v …øë3Z`j÷Ê7œR˜.xö*eÃÑ©©Á¯ZófÆRÀï”ô ÏxŽÉqM÷jÚ‡'±ÿ–ÛÞ…ÉÉlé0´²—QJ»WiNè •"½?ij“¬J—RØ› ËòÊ1.´m84hZ`Û6+Lކ˜;¼m Ç<9æÌ t1 —ªvo@Ôyº'gÏ·f¡¯iÉKˆ‘<ìD#ú\5ªVª~8LÐ$‘In6hñ¸ èÖ)†í<¸Ü|…1Bgzý{ ¢ìª'týïIOÝ›v>ŸiuŒõ‚B!$5PSUD\IÔ£“®†Ðo~m|֤ؑ¿7r'²øÂ†´ÔîyHKŒp¦¾¥SåÁ%¼!’bý§Ãß0¢·r ÄÈÏÈ –ÁãdÞx`gâ@ÿdLµÃ{‡äô aHP D¢ÔLð`˜ùî›ÏJFü–Ê+!²<5-W,ù¶Ñt»y®F]îþ@ùÿ°øªú¨»6Wg/ÿ•ÿßéµ[ûøÿ}üÿò?sðžêOƒ»›Ë›¾…ä"ÅÝõ¢Š9ç¿jc¼b¦À~ËúAAýf’B ‘çu©¡#¹ˆo¥çòÆëGÕ¶<ÑÁÁ(‹(:¸™”LÌÌÿäQ#T w4¢@³©ŸðY¾}7Ëó÷ˆæëçOÿïž6º®”§Kfd¶ÌŒ9b×]™Þ:”±«Ú4d§XR£È_YÁ~vLŸ?6Xžè+ýýIAWª>I¬4²®˜çÕg“d 3,Õùèæâ’N%È%JÈ$Yðéø'<¿ùÓ¦»§Íf¿_OFaà³ ­,B8ßõîi¬/eö³Àš…èÑ^+™Óp"§Sh&Ť0ÿÁ O"oòæQ4Ç3¹H%Eè~‰H'œÀ[ùIr&©? „xuA÷ìÚ~IC³Î4¢ž†iÖr…/”Ê”^ç€59¢ÒxÎ16@U_f¼)"4GÂBLd£8£šFXõMû«c}Ös)×´g¿S‹°_džÊ}‘­JØ/ ª¨ó¦Ô-B0´€%gK;Ež=K"jËrrÉÖÈvœalóOÃÏÿ?7À]5Ñ?3ª<‘§$@ ÿW³ÝèñÿÚíúþþ¿¿ÿïZþÿðjˆÔ€r>¬Þ ÏGwãoÿo™ÿïšç‡@á®%ݱp¡asµ2©Ï>Þ Ç?/ì›Õp_˜¢Ð/¼µØO·€—‚B¦ðª^8 v¢liFˆëæ2Ї~KCúp–ƒ ¹‰•hzˆU† ˆN\X“¬bÿ¶ÄSnýûæ½åxÄÊð.Â/È„Ãîøÿ’¯‡2"Ÿÿîû¿AˆÄ9uÍâÉSÐR3t'~¬ç,_E ÓfGåGÚÝ0zÜ“í¬ð<̯dq>åÈqâa*RKIZúÌ€iÀ1Åh»H1 ÜP‡ˆE `<ôÏã9ÀÒH›ûíS‰dy ÜA,‘]4¤¢8v¿rZq?€äé`&A©…›­"ÓÏ)Tí÷D‹ÒÎ¥‘Ï2ïxmêô«Ñ¯ÙôšG Χw}«©°ÍGØ'èbózCÔj«¤ÃÓEL%á%‡Í­9Q\8´\#å:3ÓýËW[ÆÑ“F˜=AüH@="ü]Ãk’ÂT_nŒK·Ñëæ‚‘ dé‘´£c­Âð!E–›®æÀ© {ø<"GŠç§*¶dPädðAû¯öé‡z£ßîP ÈXœH""/ Å'+t©&1§UHžêñÙ[mÍÑ+ÅGØ't–íë€Ð‡~¼þ¡/ôèß+G˜ _¥1 3LC¹gm<ŒY¤Hå 2’Žúþ{­Y¯·«õ^µÑÓ³zï¬q ÖwSÝ%ÿ÷¦-éN¦Áq G姇wCøTÓµ?i,A_ÿI›pÉØÌÌ3ªßìH3jL±Úa)=–/vÄ6)°ÑFÃg­û´#k†9õÑ0n!šÕó0íïÞÕùN¬Ÿç¸M‚Û¹Ääøo³pÌyF9ÛõÓÓ¦¼ê µ’¢ÕŒÍõ†Gkp‘‰ò7ø#9….{°ÁRÁ|ÑPv"´‚[ëm sGDˆiûjZdubäÚ’\O¬Ž]9 š´%Ì]u“ ßðiÉôæ›’Í…‚»›í À³ƒ*‘È¥“F~5¶›0íV«‹6J·‰)‚£üé°.] ÆØ‚¦sFùgèM ÆO£“î>‡qÆ`µ)†/d){Jˆ:'Rv$N“A-¢€ %ݳõ‘Z|´´ª.Ãìé÷šq–êÊÁ%«‹" *åpÌùô‰'‡‰ ôÊ<Á“.< 1ÿ7gùùãÿ­V/ÄÿÓlìùööÿ]³ÿÇ¢sÿÁéâùÃDm1œ* N€,¯gè[Úùzt‡‰¢†¬ Ó~ôþT¢e?zU†`Ÿï/cÎ/Å‚_o´Ýv¿4 ~ôpd3àû½€ˆfÊþ?ôåê{¸È$Šh‚w“_Á}DŸ1[É3;HwwºÝq$ty‚A†zQ½$>èznØXZØ·ÎuÌŸèphäïÿ¨ùšÒñ9»[XÔ¨U,®Ï}AxWƒõ€ÖJ3Ö—ê;n㤄¸4”! ÐDbjóä¯ d–È0HA$Å%x+Ða·îݸ¥Ðà žŠB"%ª³t_Æö„€Ø]ÜüÁ fÙõš,“„C%8ÈêM¢aÚ)4jtÛò„ÔºL¢F-^Â}PP1áÌÌ»¨Š˜uëM•/¿Wká8àÕò)Ïdr³4ßÔÇÑIÌz{ç)¾)R‘à0C@@šJÎk8:$…òÄÔƒ.þHOÌ9§>‹¢=c–Êmý2õf·×ê¦øe®o­z`8ýG?‚äù\p™+(.ÇiY“wVè(@[¥°L2Œ,¶?Üu ºž*”5ŽBà6AdnÁì2ÙúN–“ÊÁ06CÎáf¢yÿÝ“ Z [­^³×Éã4’bü¹]6è4bR‘N{¯?ð•ƒrFžÝVüËA:7–ìþ\ž–禹{à\!N±{Ü:øž`ß&‰w«ÃŸI7«·¯èÖ ô¶Îœ@åôàd³m|7QãR†ïFÞ[JôØÈ#„~š;4ÛƒujT€øùÎVJ6D£Ûoöš¥ùRäîá†ÇŒ~h€dïL~öÑ6Ü“HKš³„„Ê·hôj8î+ç[»+Êš¬F~Æzºe™Ü¬¢átËèªJù/á¶'˜ÓÏlÞ>B༦ÿ²ÚX©-S=[¤7@*;ŒÙm/¿Cš‰‡è›¾ªAë”éáØ¦œ—Öv¾äò¬ìʼn“ß5Ñè7ë)Ø"a=ͤP‰=P%².4ygyì”Í9Uµ\ºÂ§zI×S™—ʺ4tN‰„Ö2¶5hP ZvÀâÌé_ XzјCÔo>))ÖsUÌ ÛYû˜-:Me€Þ?‰£Hl)n"迯95xÌ…–ê ¡ >ÆòßqÀ-»Ö!å/͵§BœÐʼn¢ÿ¨­Ü÷pcæ5w2‹Å¼ýbÀ—ChmúÄ;Zû¤ Ç Eð8ú“}’[(‹Ü:\ XJU˜¾® ’öȦKÛ!÷úF´xE S72#¢¼"Þ¨Æi½ÛkæòÊ:ß5Ç)ìV_Èå—·ág}>wñÃTw¹ØµíŒtᛣ_ááÏÚ¯ìýÏÇ~ù¢¿ìbžÀÆi³™ê œ›ŽmÔ´BýÚjõR¼|ÅŽ…„iŸ6²{ËJh|·.»œ_&“ˆy•£Œ 4ø^Üß'Ç|áëE=[É&ƒD/VÑzsXâêW‹(%¨Y¯÷±31ñ³ßËÇ­’«´vͤÚVŠúceºc²ZWr¹cüųu5í=0ßþwPíåü?õ^«ÄÿjwÛ½½ÿgïÿÙAüo•ï…ü]08 \EH(n0Á•/ <º7wï$&œÂ”O‚ä„Ä~øC#¢g=¡í4zÖÓ[nxôàé~GpÒÕ[ÂÞòTÌþC´”¡/Ÿ!ú7ÿ½Ù­í?õfcoÿÙÛvÐþ3žÜ ×ß‚íG@‰†®*Ú廑vÇN±úˆb‚þ3è µ¹ · ¶}>¯tŒ(epqQõûõ•mj¬¤#WáÑ«lLfÌͱÕ0>÷ë=Å’!Ô25Ÿ å#çû;mÜ3ÑòALã1>LáVÂ/³–òwÉ ,nIZÝïwŸ;ܲÛoÔ›õ~¶pË-*it:ùÃ(Qü:’gå1ìwQh±¥—mñšÜvçåÁã#ÖGà7ÜMªÊ=.6 2¢°ñ˜9n‚q‚¨EdzƒAÚg$TPa0šÓ/!¦Y޾$ñP/ÁbÊSíö›F+5L5Naì–-?Ãm¼¨?°¸J°âg½­ç¶àKæš0Þ« ~o¸5û¿i¯]g¾™‰¸†µÿ×›ä7ßþßû»³çÝÛÿwÿýA_µø¯6jÿú祴hvÝPämÙ@>/ô ÓÎ-ý2Áîÿ`KÍ“úÚôË×mOÆ- ÿJGå4øãS…-üJ_0íÏh§Æšðù ¤„†ò»h”º’žzú¡‘ù²vf‡pÐäfû gbdë×Sí÷¾µ˜¾4Óùç[¾${Þw«»r<Òœ[úöŸl¨K)R6Ïs—B¦¢½gxþDò¿ —VI+ºäfbÉßÁ9¿Q'—ÓV3Ì£„ù Æ¥pÅÔödªµS Hpѧ/#b‹Ê®ÞlÖiŽf~n \|öf95\z¦9ЈFeQÔ+õšËÛÃã:›’Ó‡…¥£9Û€Š ÚÁËè8aÎÁLÔ¶JÚ5Vúì ÀÕ1‚nhêOŽûÅÓ®Ö ›e' ˆ)§úD Zø©v™§ú\&@vcÛÓŸ8ïm~;ÿ+¢/àC¹‰à©üÍfÿ±ÕÚÛÿöö¿]ŒÿÙðášîçÅÅ办nn†ç )ånÇ'‚‹9¶qåM†×·£»ÁÝ/;‘ =JˆŽîØÈ ¢²Bˆ#6Ÿ’ã‰#† ƒ‹?ÁA–œ÷ƒœA‚ˆŸºÉÙÕ#Ï2?7yC÷ÙnÊË ïÕ›ŽìsÆœðˆNϳ!›yãûìô}vºº2ZõN7[6OR:Öˆ\Tc¶Yó€FrÚYãÝÛ;ñÓ¾-뉂Ó`0r«æÑžºÙ⽟û—žó‡Èãö[ÿò©Ü4{Y–à9¹Õ±&“Éñ >È߈w0Çýƒª«8“ÆKŽŽ'ý:cŠÓ~–‘ ¢–ã’Ôc±¾ ‚>)NÞ´gˆ»£DûÊœ¿Ú õ?ç(ÙDǹæ bÆiËÉgzðR€6¤AáèŒÝLŒóTŸ}©ö¼F+EOF’5ÿeÏXêöÚœy4§Ç¤æSßàË+݉@ö>hBŸª¯=¢$yÎY!êÛÏ]DKQÕøó#¦ |xzxjŠÙ.dW®Cn˜Ké4xäÒp®²-Oɉ òÒ'Fa–^½ÝUÈ`¢#¤C€,^Æo즉‡Âìo‡ŽC0¯£oå{µ]ÏjfÙ1`—Ì&˜ÜqáAsÝŽ »¬~{oÑ3ùvùu¤øÚ­n7àÿiuë½ÿgïÿÙ1ÿÏlü»‡{“Mff¢½GøÝ+:^¤ÎßÒÓ"7ï™b´3»C¸êÝ&îZ*ƒ4Äï§Ôk›¥D|›{Ó®BÏiõZÇ´¿×ØwØ.þ%,¬V@8÷’úZÂËE¬Þ5À0çoؤVÎjcék$"çY B×-·î!³ÓàYœÚƒþ•œÚ ÆÀÊpII0ÉÑžßæffâAÑ܃# Ã@â”°Ø€Y—¬vû^-65Ef…)feC5 >•ú¾ª¯ÉEeºY³H6åø,…‚ øcˆVåѹ±8TíÅÖÞõ\O©] ºÕq©5Ë÷DQú£š&*¢ÙŠIfqè30•[›¥íiGä^½0 kîÓòX1•4ä¹mä<ýÕ¿]E \@Òs ¬Î3Œ\ˆ ¼#†÷¡'!sHÒ‹ÿÎ CPŠPÒ$”&ZHyÞÎçVòŒ'œý¿µÖ~ìOòʹ²¿Þ³Õ“>ÝÕÛòfJö_˜í°k à‰9  bDk¿ëKú—lÍUâ%mäTVºb™¥+®uÛDÝ•µ3®Ÿ­3L›lækä_ÃDtü´Y‘³…,Œõìí(ÐEaä[㯽¸•ñ ¡¥ŒRtú lîA“ `~¨¨?èÕ tH¶%ÿ4ík­xTóUÞKî2”ãŒTr,9Ƈ€EÌ…¨N @ià~@5°ÿ.W&ÀpÛ9›¸æš\ _Äå![ÿ½«/—ÀÎy`1ã@_2·ôyºrÃNî¿Â#¹téÅ]Î0—\AðÊ´Ê¥jî.>\ó‰£ÝT13¢ô°à‰Â&ý…âÑ8(ñ|üœ`u‹YÁ¨RÅúNS<ˆ”ðŠ÷‰S5ù,fÚ¬G¸ÕÊÁ- ¾ä¶JöO:¼âëx]¡§3×y¤Aü˜æó§8¥HrŠ,™³“=r‹Æ@$†+îUI:“æ}ç±É{·4Q5ÒŽ„þó³Å\ÃÕ"): æ[ÈBÜŒ/™Æk\ à„>çg"²ö\ Ut¯¯ønŒ\Ë#û±} ‹Ò?D #B@â›84QÇ b¦)I,¥bPT̉Ö¤gÙŸUéN©m_3Í„&cRrÎD–³ÅX%ˆè¨¨žÕ[I~ Õ >ÕÄÀÑ"á‘Y3j'!õq\ËÐb°·éRwl»ýóNe}í,Í™¶!7 ¼ÎTQ¤¤¹è+ø•v “glxV¹Ïzìz§á7 •GÕL #_^Ù|5Çä.þy"çÌ¢F·99€Xú Jò/Dt. i{qn¸æW³Ë©âó6ƒ+.VXÞWSg´ô) «¢œéÍÓ0º5÷…ÐâqÊPIVçÓ*G¥®O2ƒ(.œ¯ÁŒ²™bFÔ%:òÕ|—ɆËRÒÐ :©ux܆{a!ü'X53ƒ¨°… NŠy©žÀTþ‡fÿ¡Óîu÷þ¿½ÿoÇü—7ãÉàæ|X½~¼Ž^| ©_Ž3_Zg=9Èe}I¶ÍÑèâúê8Á[ÈÁ“ÑöÈíq^u©ÿ^µŒ@&ÂÛ‹áÇÁ§«IõÓíÎ>üyx>W¯?W¯†7oòÄÚ¦¤«à˜åE‚wJ€‡ãWt[FΙ-˜Yz<§c3ÿŒØ&¡,q,ËH* ïh%æ“…‡”§’¹Ú¬òµ£ÍðÎ"î¨L ‘)öèr ZlÁEÑ韞*$ [rQ„ûŒŸœ“¹%”Sv6f‰"œÓ:EbÙN‰p³£PýükKNHå"‰,"_¡8À›o 05à"çŸëÊ¢ £Ñí5“Ó±n]ç« „›:]B¨ù=X¦|KÓ>œ$Ö`±ÄÜô KºÝ¡»_AÕ6-æƒw½dzìœ}€ÁÀM^bÐøÊË lÄb{Ð=A·ƒ¹ .fÅù¾¾FÊzpæÔ-Ct5Eq‰â`ö³ˆË´YÑá³q1lÎE`PûšvzfymÎÈÖâj~‡03lÒVÈ†çæ¢é‰L”' â &:˜lƒ>3…@‘9.`¬^,ï`OÈÊ#IxŸ™6N7™)"ì+€ß9%ž^3Ñ嬫tFäYçÉ0Úc©›' Û´ÿ§G†ÄXÃQø°rDŽ l¼Ãª];:ò ;F£ôc½]k‡ÿYˆ.È™Ö$]Væÿ=€ÿî7A’-fÙ¡¬bѵ7 ÓõÖUØXž"Íg+Ü c>é¤Ò"öá£áõíÕè—áðXû¯v¿Ñk_œ^ü7ãpÀƒn£ÖÎÈ"'½ý럴_¥úýßñ“9ÿ¬5>kg r Zik.Ï Ä+úÚäêÑÁºŽ•;š‘Iþö8Ãx±ã; i¿rIHõú×êJ'§½9:ú ú¬~­… 9>ÖD2šÜN¿E1ÆÎ÷K)eÎ}VžÙ³ô¹¹4]í jÎ4ÅKklÄ¡!:¥Ýo53ÒˆL 7Ý”¹f#ê󉿭j¼Í5x! ×m´Û™™@A P=½v?–UC†G€BŸegg áž\CÏ'ñ\òsÓY½/Ò#Íz¿^ÿöŠ]p‹¦ëH’2urßmsÚÓ (;`‚±Áì-ó;kÿgËLLYØñ”yû¼öÿN«°ÿ÷ÚÍöÞþ¿·ÿï˜ýŸé\¡Ù>Þ®%õö‡÷(ªEà °Ñ³^¤ýFûp|5šŒlÿ¬`ù,´uÀÈÚ:úÆÎmÍ‘ Oš`Jq¥ÐQ×OëýÆ¿uÞ{ûn¸5r_Ùs¹5âlB;àΈY˜ÿ&î ´ÿÏ,H”ó»ëEñ¿ZN¯°ÿ·ݽýoÿß5ûÿÀZ=èSc ‰÷Ú%,Œ á á óÀ3<¶%Á°Ÿù%ÙhO®à†=7¢Ø·ÿúç ö¯ `Ž ŒÕ{Es}ÆáÝÒl¯ôeN+= µá]“2,íÒÞQ¢a=ËP ýÜ2ÉW0P´ƒZörÜ ín»%3¯ˆ#äs^ ƒ˜ HõQw!ë½:5ÈÔ ò›¼ý08ÿËðæ¢úÓàîæòæ‡ê‡áƒ¿]ŽîÞ¾ÿM>îÄT"V9¢C`y_]Ž'Õñ𯟆7çCrÜWÿÎsÁ˜é³ƒfÓ#‰ixUfs ´ó|pþã°:|¸VIEw—Ãq•¼@S“~ÎÜZ2[½5¹@.#Ûû׫êxr7\‹ûßäj3«š‹*¦S{Á–RÄÝêåÇêðgRÏÛú2k«°s£„ÅÛBÿÈÓŒù´ªoÖNÕ{²gÁL®ÕÁ§É¨:þåæ„WþÎ*7˜£ÄþÛåð'.5~Î%tÀž“‚Æ™ŠÞJQUâ», p§:7=œÚ0³\Üm »Öz`ã»®®~©^\ŽqÃÄ"Óêbx]6üLš›öÈ6½€ O)]Q…#]TÐrtŠaçé“áMZ—Ä=Q¤GJITLÄËÔYΪJ‘<‚ý2º…¶n«GwÕÁ¸:ùt›wé²ÖRhháýú!¦‘DÁÁÖAÄþaò£Ü6õ‡ MZê+Š6¥Öt=¸EýËá{ñ1OcI’1W'tP¯^Þ\N.W—ÿkx¡N^T° ¿fhð1Zåönôa(Ê$ç:åïQú_ú"_+¶Àpz›X˜©9"ܼÑíðnào@âÏMKjQ°!Eä*/þWáãÌL^Ùòú*c+hÿ€Ajní08ÝÒ¶H_äk$Q<Å‚/È-ønô‹t ~“±-Q]%÷QTçd>›99ÁŒœÁ|œØ®HžA¹^>ÚÒY_®&G^ICÄÑÿœµæÒp6ëØ6\^GŸ&J 䯊ÉO.ŽeÌãšAn£«á…ÜöUÆFnC\‹>É@KÍñÿÎÕ'Ê~{1âæ[þ)£À±'å Rä|â:«¨ûáÅÝè–ßýÏY¤]ë言ԓÁݤª¨%"}øËÜ­ˆ¾¢ðþPù3ss$+fTc$Ó$oŠôUî†DÜQlvkô?g“½ñBBO>QRòonñ—C”ˆ^ ÅÇL²Á¨%Í«àD ~WHþØ ¡_¹F}›¡ÔLm*¤ÆPßN¨þ§QÙ|„ñ¾ÁtŸ`|Ý=‹·“Mî>Ýœ«–²ÐW¹ZJ¡éÑG¢ÛíaøóðŒã`%ÜÍ!ðE†æ¤8C¹#3VÓ–³·wAsL×~$úXêVåÏì-ͬõm>¤â ¬‰ËÅËs °¯ê7Ù›Œ Ï”<A¯d7Yõ¸‹J«^ý»xë²bÄFˆó"'EEøNâjÀ4÷KÞæ'5:ØÔœ N¸èZÈ„’ý]Ô¢þ» t¹ÆIj,®S‚ÍSÍÙØ(Ôz¹ÁxÀh4æ¬ /˜¿›?½¥*¥z\£‚¦T?+Ÿ |›¡½xΈVx”ðµ€ògñ%6&ÔŽ,M€ؘ è§ËÉÒ¤ü™» œ:$,?µ„ðì¯Ì’'F°Q‘Z¼%¯s·(Æ Š­üŸêßYÛ{AÙ•ÛHð›Ü ‰ŒYG±qï`)MHâÙ™<²”@ò"icj‘Û'¥‡›çÊÃ@ðH KËaø†rÃ0ÿkaÂm/é6öœøo^³)åµÿ­³çÙçíZþ×ÇK°tÄZv.ʾpÀcL—1g@Ñ£²ÁJ JŒÏ‹Œhy½ì°´Áß2-,S§æL‹ÚmÈÄ ”‘;–¸ï”˜M–8t˜FV9Ú_‘þ¾”š© ÉYkJ¥Q©0 á6Ô›Ìqo -’‚a¸]ékD·V³ÑìõË£vIìhéö¤-¤!f·_mõ¡òõR7ñ ÷2ºƒG(öÀ‚¡ŒmMûd[æ«Lsuò¥ŒBgA—=—Ó8YºØòeñâ“û(-_ cE>“%Dy\ `ú­àú¢+Ið–ЦϠ“ÕC‰oÕ"àMÇšãQO®Eª7éR\D›´ÿOr´n®5ò=A„¹ àǬÞEK‚=êOP)Ym@Cö—T¶‚2€_™JêWÇѰˆx°—ç=|‹ü;Èd‚$̰éYà÷u ¡ø!ª [âìFZéCGÇýâÕfÎòÝÜ™áR¶¿³;wçW?Žß} ûâ»Åo–££‰Š ¾îÞ“ÓÌáox}ï#fS)uΖ«ßfT­Œê¾ íÇÚqWc$.0´oa\qXßR”=„ùá4È ²Ÿá lH5n.uÑlöºýXÄ0r½$'´¹à“ÁAcÒ‘6PˆE?šqU{d»°z„N©²ƒ#Ó®ò$æ³åÿ|L~ÁDê³DMM«Õj•ƒï¿ç³Žu °6Dì\Lœ"èZ¤³Ú§¬”׋êU18«¿û¿Å™öÝÿý9?`‘¢Û”Q¦"P³òïÍ^G™«â€…2Ô×W{òE@§¶Ý­ŠoS/è´Åf•Ù”Xr>kŒÈiÕl!yyéÉ)²çìö|è_­f«Óm÷cп|”ÄO¶ù÷ ÂÄ)Y}µ"w ÛË¿Ë9ˆ˜Âô=ÃøiñŸD ƒ _`O';y|éçÎréØX CvÝa,²‚·Î¢dòÄ+Á¼œxÍeYN±Rì€Í™bÏ”nV¦ø_~.×sØÓø?zõzÀþKnv½½ýwoÿÝ1û/ÏcÜ}Co¬£uâÿ ýHF•pŸ`êÍEoÎMIê~=îÕ--¸1}•×f1@ÛlÕn/ñ w‹ͳt(œ–Í€–gŒèqÃMÊÇ;Û¸.Áän.ƒC£Õê4ò­pK‹+í$nZ}Nò E¢|@Y“ѹ¹¼Å°Û¶:í–ܯ̋‘‘2b Â¥¿ aDNºõÝE^²ˆ-h"ÈÈžÖSŒæ@ºO˜õWbI¨áÁ8A~pºÈ­'Nîó:x3gÅØN$p¢ÑõæÁÖmßLgx&uý—¥7´©q¯Û0Ä[­n£Óoçâs(|²F»í¯oP¸~%—:ølÖ³o=Íöáóé;Á­FúU‹¯o?É¢Ú™i“iÉjTˆ¦ºûYkkð韵Crø;ô‰r‹}tÔàeTŽè`e“¹HÉ•±}¶º­N'«íó\žqþ|õgj̶L¢Ú#Œˆ^Ø# k=¡§AØsjŒ– ±Œ¯†U‘5It}0k¬ ¬¸³ÕO»ÙH &Q’oÍÊ¢î'œÛLªjðÝL4ú›JGž£èdŸu!†¬7¸Öø¦.´‹à4™Ëã2^ x~2œ!Š˜žÉø´Û­fnS÷˜œ,u ¶z s q“ÛR´.£-0]îѤþô§[lMˆrYraºxìA&”íaÁ×g.˜—ÏÝ}ò"‹rå:÷ã_ÓTšŽÌ#Ñkµ_œy"`ÎEÇ †ê•m½¸áK‘£ý?ð¥ìÿ-òkÀþOþiìíÿ{ûÿŽÙÿ# 1wß°˜ÏqÔÜNJ.Hwa,ðn¤<¼¸HäúÎAâÞóõ¼Qc¾¥£ ªërz ²áVÁÞáá)ÃÚnJô%„† Ý ƒÔ#B·±ZC°&‹ ¦Àa)áÐiwí~y…P§ecâ¶±oòóp;D‹)/>ƒë‚ܧ7V!ÞnÒ»jxâ+û'‚ÝœNg æ0x‹[ùøj:i‚FAûO ؈@çK0ƒGÇlÜ¡‘ÎBÅÍåKu>¡y+Ê,s¦[wg”ט¢Ôâ#S¬3£(¹wYíã+&_ë>(™?ir;‘:mr~—ãr#œHI:—rÒŠ)?CK\òë6ƒH¼œÓUSŽ»ª¦åZZa`L_8Ó'á9¤².ɲxoǶžD÷yÔVmNª GC$Ú6~×—&ù­–Æ»V÷¦¯†ºí¬Áܪc ¨½NRDÉWgPäB…@ç¦(˜‘6ð„q§¢_‘ ¿Á½Óî7ZÍ~.ç`hc§Î-Ù;Æþ+âË"5{ÍzF_VÑwRK«ßËÊnk…¦Ó®¿\€?©¯ÛéÖ_Ú¶ŸP>ÎŤR$Š?3‚a\´¾\@‘8÷vqìJ…læYi*ÒN÷PÀ6¤K¤ `ãý®× ³B‚!T`üNû´Ý•uU´?ï5 ÷ËRsÈFDNLÊi' ÙÌE½¾ùªŒ„l\>UÇìB¦€Ê„óoAS¾ÿï9ñ`‰Üh¯ô<´üv·äïv[{ÿÏÞÿ³kùèy9ç+E?ykcùM0¾ç|;ìéÉL›ïíÙšìúsDâF¾WP°os:ƒð©ÂNžäQ)èïqá”uëÒá¯2Êï⤮nIô°7 õP#×Jwצ½v.}BœùË=¼¯\ç+YWÔ±ñàƒ&¤y(:˜/©mbG1tÒcÂÀ[lD¨UJÄ8nɰ¦¶ª„bi˜¤(A´…g2C‡œ£¹wÊÀ{âl<²Æ¦ Ãz_XPa¥\˜ÔYî€Ö´ ¢ÞM‹Ž†nyâ9¹œGèŒ')¬›£¾”;±`f˜*R‰Ìj£m¶Â£ÊçFMûh"Þ͉ÆL‰†R{Žïòg' ó‰HZˇ›™Dñ*¯lgv눻M'¨~I©l§õTÿ©ïv£/½ Ü_ì+„LŠ*~ß ê‹vb ¢ÕÆ]9©…eŸz° ^‹Þ¸á#–!fHùw®Ç5Õ“±-Ë Šû0ƒÌè;ܬ a¡Ñ»"ìÚ¥N<¤ƒ¬<1¹¸v.Ü‘MÕm—[NuáV+”8aú›]n9_ …ÛÍd˜@V˜¡7>yTB‘°ÝC•õU=Ëî.€¹ ÷DÉ)’²)Cë}­í ŸÚMç(Qd3À¡È1!êÂä^VáHcj ÓXÌ)°~áRÛ~ˆƒ‹b×ܺó x(5¤¬ÒãCžò®Èç„J:‚ÿ5ⵤùJ–U¿ýxI]“I[s,ŽA<¥ ÑÈ1jfá?ÃŒQ^£A4‚\›I)Ô†º&÷dœ7D;­H­æŒòËÕúéX)€N(°ú}`@:XøA» n¸°îö“¦¯×®9ÝÈ¸î© : ½½ðaÒ$_ë_g„Í¿Ú  í8+Fe `¥í±” , ¢RÎ>¤<XS\ÿá#˜y¨Œ…`ÊèF´ñÌ‚&TÓÀmpô¯~âT†Ûo¬QÞ×p­.Dà-ÿ"𑵳6gM01ýY_Vp‰œý¸®Lo…91'Ò|C¡*IÌVNölw3[c`nuJÎæ|S' _ÖžÏk‚¤º¨ªH+XL³}¯åé˜m(cºÝz·_¯'zVE?Þ+€”™ƒÆEI‰¶Ë#(§ÐðG:œ¡üçÙS5Çf4Ñdaáå.JuGžÙ©™™;„qrW²¨÷¤Í”Óá,õ'HÐ ii€Š§«Æo¿œ213 Oމ\W ³Ž™Û«=_P¸\pçÅfçSË™}ÁÃÊ<¹nÛ€\JoÑÍòêÀOºe©“/ Ë–¯¦ï膗}ôÁtÇ8<_…ª„®Ô.—üLgÄÚbù‰â 8”ê"Z ã-† 7÷‰‰È„°1¥ge™ôóœ­áÑT›¦xý§FÚˆežúŠè€£ƒŒIÒ¥æB{tá˹ª éÞÒ‚ ”m9òò𤠗ÑÇ1 wĻ繎 â‰fàÞŠQ<ëG:»¬ ¸Ýqp)kSB/€Ê=:ѳ.Ù ’Š 9(rp¡DüÚ@ÇÌ °åðÓ„Ç2~ÈŽˆ9d Ї_zKpº½.”üŠ·+/l´O¡VM!‡yª…=zØ×Õx¼dÊ+<Ep³v¸Ö’•ÞT€7ˆ3ÑŸ©I+Ô•jÇ­§¢.v›CšªÛ‘Y3j'ìœfœ‘ŠßŠ1‡æþßLãQ;§YÝÇÊÎDU6jÈ\Û2É9{Η5æÈV~¥¤Bi€f”¦$¾Æšå¸&˜ÑæÌT¿¯Ûm6ã@ÐF®×µ£#O· CÔÀ±ÆÌ€ýò~q£ñ,‡pÿ<ÍSF;üß­ú@»“ðÿñ¿›'ÿãÿŸ‡ø|¨¶«tβ ¬$h)¹ÖÍí–Ü ˆ„ÿÑràc©Õëþk?B€¢{¢ÝéöœHöçZÔkõ>¼Ö©K,l[¶š]É`ñjòë‚Tîè {¨Õ´C©y¤„Ê‘e¬IÅl»zstŒän²LT˜_9Y`|!7œ 3ˆ4Γa|®h ÿaˆR•L3©ˆÏÔrp´Úxtˆ¨ (û(šñ‹A”ij‡×Y{_žÈ§ñZ·ð«[8¼“¯ ÿý‹»ñf`_?üÁq§:~ÆÊωš² û‹C~ûàÿx°ñ± ˜‰Î×l½"uÉÞÚxhUª íxêx7^ •¬óv¯ÕMü‰(sLÍýž³4R¾û‹‹X‰*üGÜw‡Ý~ªåSJݺ|犈Ì7 eöÌtp—‹pã­·ˆ–ò0¡Ó~R’ãOBÜqQiØTH9…¬­Æ¶G&š½YN 7l#õ·©|;ãWô‹•ì~¢HÉÿÀòA}3¢6wì7k²÷®ÉÖ¸YI½àC¨¨mÉ^9\^;Ã7ºÝÇéíÿK‰ÿ#›ó$`%Ǧá¿6zÁø¿N£ÛÞÇÿíãÿv-þo8žÜ~ 9ßB ƒD ”!pRð¬q‰ÌèäF@ÏIñ±Œ.BÑAÎ Þ9 Ñ€+יƕr{7ú(ä•Býeˆ`dïåŒL¹m‚£Æ¤”øÀÀÞRfœ``„0^ÕçIà@eÐùµN{ÝV+Ox`’CKêl4~ xp¶ ñÃÛT®¸;oƒó¥Hàé¶ÓæÞ%ôcdèˆÿ<÷œÍØJÛ>j+4‘f:tÓ‰`  8d’³›p­rp€ÁU’çŸ9*™[ëà [ŠõÖìÂíÓ&5<Ùé´…¥ßS¢²h_ß„•t¢€°iºW9ùùPãbƒ¸ t¡AZ÷ÁÖ„w­Ó~÷T&öŠ€îç =Jñã tå€*E-.2uHs)³~¿×oçóxô–öæˆæÈ=8`[$ûû#ùß9YÚüŸcíL‘W;[‘Gï]Ãû»Å]“Ê3•\‚ÙõLû ñ@ɆÄ|ùtëó‡@TônMÄh¾sŒIO6àÓJnGãÉwCrú:#O`ùþ¬ÚB'õÍÏ4pŢg~E®±tÈZ "Þ™æ?pˆjs‚ œ5¥L$5A ª3›m\—Büª5Ÿix"¬Îχã1EÚûŒÓ!š>­wÓ$]Ä#X°Q |‘¬zÒAj@í+÷CmO57kÕ3£·áǃb«… Máâæ"Zž Æ#»šžÆ2ݬµ™nƒ¥)Pí²t6ö¼üáRÈ'²)ŒB¦²)}Î8¤×èÉìL³‰²º!JLñNØ”ˆ˜ 2UJ¼«Aô†"œüN‡^»Õ<©N. ®v`í4½ñ³ôh‘œYgØSô× ®oT¿l¿“Ѓc;4Z6¢ÃÀù /Wr-äôW"M5"›k¶¥'kPf`G¤K¦aúyJØŠ Ùd¨’zå¶[ÀTö éd2ú!4{Á[ ]…+ºiˆl)¿Æ—>èö=-ÇÇOÁÕkDŽ4¤éŠ~M˜ÉÆÜC#›k9ç>F¹³Ø¸ð­(„q‰IUëÍÁãp1uµTË”°)ž`fxEFð-ÿÎ"ÖˆÆ_6$„­/5ñ4ÂÕ&†Ò¨Gz^Êb¥}®¨JÀÁ)ôL£¤ZøÝƒ\± É[“ŸiᧉÉRhõ: Å“‘Å­(æ¢ïÓÓŽDûþ@tú½³GÃ3—ï¨Ðw æôtõ:Ín»žìéRv;6Ïqe¼]<ÕV(É—D· EµFû]ø»qvâ^dp;D&ùÙ3ÁúJ³B!Ç “™ q Ù+Ê DäÅ@õcçóƒŒ5wX˜®·¦=¿dÜ¢0n ‰ï<€kæäG«Øú  ¦7É­km~•º‡Ì=žªÍàTíuüãu ò½Ø=LÔVh¢J:6ª‰xN»§ªŒ˜ÞÒÖq~ åeÑ+.ԌӆlÐz«4á“m4h•‘Zr_ã–Ë|Š]P]ê¿WD‰Huóöâª×ƒŸ«ï†C‰°qü–螃DXŒ„zøÔ£%Pòˆ4"5ŒïóÒ¹@h€ü~â&r—°áÙØV+¢µ7äÊÿ„¸V›¾ˆÆ&sFä&×ÍŠgJsW‚رH;PHú¶,)â\±>Ÿ­ ij§Me§/ɧ\Xïd²Ã Æ n+R‹1â&É£š»^79å‘…¹lïgc=Ǫ&8¯†Ÿ®|/pú\ŠQ]þü¡ýôN'ʸ“ë ÐÉÃ+< ²ÆšõyªŒ6|¸Õ×Àá¹–ö䦺ÆiU982j÷5™#×6ÖŽûE[»Î9Ì]éø†OûÇ­ÊKmM*üv-C…fh4ºÍëd¸ÞrrTüì ½¸Mäv»4Ôx,òÛ‚}O~mA¦ì*Ï󈘌h>/äÍ&CIN"»“ª¶ÇjÁjßC¦K™}껋—ÄO-éDßú#¬À63!—¿Äûv#^à= Þ=ˆîžDú} z´ ]mÜ•Ã]¸ ;šÿÑV®2î¯iæÌÙ¸gÛ¤fØ~>79~8â;Dj§+Á ” 3 28W¶F\c¾™1`Û™ã)hÍÌnAº:¶u ƒŽ (” a“»JÊí‚ žÙƒÝ@nXöWÃ6ÉUË`DrCÉú‡ªåý25‚û¬²Œý@8æ2 ÚâDðÊí† =€BÅÅöãÄ'„xQL ¡JI;˜p@Ŭ,¢oÄÑ+ÒÇz…™0<30%œÆ½îÎÑ£%AE¢M‚Ýf ÍÒ>(†î“è™Ñ ËÀ%@hÆ=WAs”A»szàðbRÝCŽ;Ú QŠÏ"ƒÉJ0 GN32¦|–}ÄV 8ª„ Ý©ˆ€ðÚkã²ÞÑ÷Þ¯NMiÖmÓsce @w¨€ÍJæ Cz(Â")ÿÝ9›@_ª.,‡Œ]É…%ÈÝ}8K« ¥!òÿ˜çOUïêašW…ɤ‹„&ÌeHV´<¶NyRS%VîëWZ½_¥c[O¢^ B UV+AF^¿ë<*Û^êHe½.Ʊp‰» ÷2J¯Î¨ ÞOûàÁ‘ؤBP±,Ü'¾-”¼„¯N sóÍÅÕ‰¨;Ã’Gƒ“â °ZU¥cKE@J³ L»×hÕûýld0CΣÂûwÈÒ‰VÔ›§ÿc\Aux£%8áÆ°­‚A•Å?¤>ˆ2BÄÅ âH-./ÃÿàǼºÆ·Éÿ d6ÎHß_‘fð$®„Ú¤l¢+Õù8 ‡”å̱6Ký÷é–^ŽT$©•å ͨ([ÍëX+“LÝ9‹ lÈZJïY~tÑ•øRM`¯[·HðÇ«Áä6Ë CcØÙaGgûžR@.é5w®rÞ”0ñ¸VŠ# 8ÜÔò#q´{ÍnWÅ«I z¦» gÍRs~‚ñz¿Á¬:²úéÁÀˆ!¼õòFU‰¯iÒ‡‚€á¨¡þÍÒçæÒt}¦…F­Óé¶»ÝÆ¼~||‚3ðè¾Nòë%ˆšÁG‹u#ÉDÙ‹Up&-OÍ6­<-yI¹Ä÷ò¥ |H^ùPÈ|¸ "¿9‚K¸ÿÝf³öy„øBØ$)±ðÎ!´š&Ñ…>•ñÃgÑ$FJ"æ¯?S·«Q—;Ê—:9 §ÿѧÍzýÛài÷Z*"X ü#¤ÌÆ©š’—$ž~D"‘™H´,1šqÄ#ÛPvƶÔìá¡ìÈ /(äÛâÖàÌ `ÑQJ¥!†g/ùãPˆ´{í¦‚½™‹B$îüï§–B@BO—zËQÙ$»Gœ1Ìi'¨>2…9å èÔ@ã*vŵÿ/Cü7RãÒ`[&ñ— žÊÿÑâuÚ=ÿÇ>þ{×â¿Ç“Áݤ:¹ÜŒ˜?÷-Ä‚—µ(gâÿ ýH˜pŸú½mYrü7ÌPÙõõå䣾£FwËðÈ>ËÕµÛDzË}_Fwhó(1à;4$ü=Z.*U©M-gö¥VêW£Ñ;Uü›[Ft‡º§ °´(èT·@‘éz¯LÙ; ½å å-àÓ?m(¡ï>ý1Ìc/jÙiN¶Ý\îóœ 0ý½nGˆwØVòÒtËÄ å#6‡t¦ðl ç à·w»Íþi>¯‘iËj¤º’ÍÑGœôü­ ;'×úω&ì£j’~Õâë›ÀOäô±®R§a¬&«QÿZ]é¦ ®†£_§ºûYkkð韵Cr„<ô ßs‹. ZFåˆ_6©‹öRC?Üv_&=Š2ô‹Õ>ج:¿´%L>@(0=ÐŒ½Å\O°n ¹o=aH‹òfކŽîO©ÓN0–‚É„IU¬§µrˆå~TÄBR(k1¾HÒ–ñÕ° ¬Ï™™ÿ§xi é äÉ)²âÚý^K¶"F¡‹pÙг¡ª¤ßíefXõÑÃà…HÓ£a¬Ë¢²5BåZ†S¥ûW¡¾>%·úîKû>nï³(ö<q¾$ÔÚîFWW牭/°åä©1¨ØÔš/oäcr5Þ,¦7`]Õ…Ö z&ÕÁ§É(¥ßÕ" Ȫ$þ:úÓåäG¹?båS‚¿¢Ûo7ð@Òpcï ÏÊú¡í2…xÆ[tQC¸èíý i—ì\.†( Àøèß»þ ìÿä@ñ¨»€–ø(0Éöÿz·®ðw€ÿ£Ñëîíÿ{ûÿ®ÙÿÿzUýipwsyóÃ7BBy"½¨b΋äéÝLÿÇ.pÖ#Ýt“ –~å®"ë¥ÂÅz÷5½Êoiÿt\^ÞÈqÚÆö?¥xüm¤L€? hýg‰;†KYYiÔsÄÝT9ã3+œ5Íã^`&žß×Ð=­×Û²ðÖÈ,™sL ¿"×ÞðÍA1 È×ãèëZ`wWV_pï“â#ÙÛ¢{ô÷'±ñ”ê³'Z¼LB=…¥:Ý\\²‹[‚\¢„L’ŸŽr™¼žo`»Me<)I½u;8±ŸiJkþÞ€Ù áä1ÝO Ubn,LžV¦@'bÀ„ßøIDBK ‰!Ü]è3ƒ²”r¸hÛáÂùÖ/Fôªüý=›UFU£ãzµBC{ÚêÅÝ¢ç½Ïïä=>u7ÜlT9è”pÏ·SæºÎ‹cÓÜá£_ûýíþ¯ÏçŠQ˜[©«àïÙÞ"ÿ×nÖñ@Ò±¿ÿïïÿ;vÿ\\(^îî©þ8ýå TÔÜí« Qn°Ç¨Íû+ÉhÝÁôz†‚´É°¥é µ‹_9Œ0jŒÊ0"$îE%š‡ c¼y<± †¶$C I!bAŽ%†EP比øÃV§Õ<•ï[Æ&ög6¤Ù¨W¶‡™}F^ÒN«Ûi4w&P1¶ÿ"£çæ›’M!t' 1¡lL%™kHÉg{HÔÝ€DÍÄ7:‘1EDt·°b­H©¼i–ŸŒ´ÓÎnÒÌçžVhIp<'ïÁÙXs M®È²8á\[2Š t;í[¡Ì3Ƈ"H*|ú‘sökBFå Éêtê-™K6CÀiJ|hâ΢}÷æÈÒ—Ó¹®kG˜w©ŽeÖ\xLŠE%…}÷ÖúûK8µ© @o§ÚÑÕàúÃÅ@ûNûîXû¯vØê·ÿ ¯)ñ  õhRð¿BžN³ÑÌàYh yp>tq!@ž°ž(¬òM£v¿_æ(ÊNGM4ÈE™/Û×®(E¤—ބܥQDˆ&§îè¨KÒ»buJ±Áè«GÅ}˜åÖa–¥\mßg<ŒK…—”ÐêtÛ­n¿`äa¦›Â7 ±À…|—"³Þ×s¹2ÖÀ.87SÑÞ­‘ÿGsyLûžE–¿Xü_£Ùk„âÿzíúÞþ¿·ÿï`üßÝð|twqyóCõö[°ø‹e ²Ñ.ß´;þsRôQ§UEEÊšŒn«JפÄzk×З᨟ñän8¸~åØ?u|·ÿ‹éºœ¶ûÐhm(@Y‘ÒRrôŸ4$h˜ŸÞ1œ‘ :‡AOypƒ“Ñ^§Øè©dßW‚}¾Ûn’cyøj×åDXcäafVµ6ÄwÉ.¯dB½²!>Ø[it š6² ;¹ ×!çæÇ~c@ëgA•HÜp>E£ƒÅclöò§2=uÖü2f È‡ VK431"^·“Mþò¨2þ=Ü•ÔazECˆ Š‘²Õ´²¼Ý^·Ñ’y0#¼dÏ›ƒ¡À@“&ÑáB…sTW¡k„Ÿga«‰ï†M³é}_Ê+UÔŠ4…1[ }rQy6S–j9‘´IE°}eØYé|–|‘0^òÿNûEü!ʆ­a¬¶h‰„l¡îëqNbŸ„®WÁ+¢Ÿ£½ï—WÀŸA:ã´§°Ø&ù3Ššõ»½^CAV ùžËb1pÁ+ àL©w˜÷‰ ÚJaErèó_ªâ U†-™ŒVGA+Ïè„Ùbvt;íÇËÞO"S£_W(/¢Ý “#î Û £±òÙŠI\®­4Ú¬Ðô<“S#*Çd‡R22(Šú2‚—“š‘fÀÈ—ZP;’™A bÏê¸@û?(ʪ ó^Úþ_¯‡ðëÝ}üÿÞþ¿köÿ«Ëñ¤:˜Lî.?|š Çß‚ý1Ÿ[jÜøIŽqä~ª]@à!Íc¾Òíû~ohG/.®Ž|ªÆ ü ¥¯ª0WÆIˆÀDŸ“‚<2Føh3Qƒ¤Œñ𯟆7çÃWô„gÀ–‚øŽÌé#È>¬[G S„ÀT¢!0dèA¸cd³ m*㣓Fà•â4è´šõ¾Bý´Ó Ð[ÙÂømì”üÑûΣ Çð]u2¾mï,q°›Óí±pQB¶²àüãtµôJ8Ðý>åa¬ý6¿Ô¡AÎbFæò¥ëbm‡ºe‰xæ—v)„Ú@¾LÕÞÆú»}ûŠýQ›•fñï´Zm¢Õ-þw‚K<ÀæˆU´0·ãJȳÖ|þìײðk¹YEÐ7§/¡ c¯ÌåŠ<«r>Ú²ëd§EtˆÃ8UyJ¨tX图>ªp§¡íàðéX>j°“4IòUªJ\¨èÚÅóÏ–@„$é%ò[4;­6¹öÖs¹»ö+ç®üì³f æÖ{×Ù¬’9\¥nZð/ÐNëö>½ÔmrŽrÉgl'z…\×4à‘©é®æú|œÿ¶Y›À³Y#ÒíMÕþ y`€#Œ¡»g¤¦›„r«‘òÝìÁ±6QWßGÇÕ»ý4þ±zuùánp÷Kõv0ùQ Kƒ°¬Ëâ1*KÝ6WK±I˜ŒLzŸ‡FUI~à VãÛ£»áå7¢Öñppwþ#V>~˪¯d!Ï¿õô§ZÛƒƒS äßÕßkž£Ù†1gÃ)Y¼Íjå¸k?•<džœ÷ãS ‡LË ò¾sVëw Çy'ú„w)v—tÆìÁ´ øãͦ„옎 a98BsæÙjã=TY#ª+}ý ŠªÕ \Sf7NxÞñØ—ÕÛÑxòÃÝZ»tæ¢44í´'7-•äQ4}ê|5þ¿Ç• BÂÜ}ÔmDž9Ë)´eMó÷‰H `Ñ–d¸g¢r A+YûjêÚ`|ñ¢3Ùƒmþ}_Œ0Ä£ã~ñΠæØîVÍÅÒX?8s2µç‹3²ðHÓ—Ú™¾ ë\;:rè÷ MÕYkP¾èÿŽfÚ‘ñwK;ÂwA?UÙB~ƒ#r «ìQX @.uÄÃðÒ#úoCQß|ÁãD9hYÜäÏë ¾òÝJžÇuðŽã*r0Ÿ3ïEV‡g®>(…å Ô”ÌwÈ“§ZB·+g`Öcì›i±‹ÂXÏÞq³¼¹®Y¦'Y*Æï¦‡ØÂ0°êDYÓA\“·V•8Ùˆâ:×Ò¦2R@€‹I7!ÄÃ]âþáë@¿ÁHú:•üKÑë+åJËCiÚf­²³Á,œ/‰±á§Ú%;_ò!2fðÄí@Šì´ØÇ§ìþ£OÌöÂñõn³Õ Æt»}üÇ>þcñ‘¹ïÇþœ‰«5õ1•‚öuqù¸–Àøè¬`}~²gÜ3J{Äqx]¢glV‰4Ï^¯®P§<Ís"I{"9-þ™‰F™J¢¼úpvêåŒÅ®él¼¨rÿˆtÓd‚õzr®É7H7MÝžl:0°ýz¿Ý/@6-¯£?(Õtê6¼ctÓå³L ½¶#xF{‚éݼÿoVsÈ¢Yï^õ?Ó.*%ÿ£Ýëïÿ^oŸÿ±¿ÿïÚýÿÓí¤Ö>üyx>Wÿ<º¼ù&@ g¾ ¤VŒ(ÂÅÈ5AùÏ)fеð|*¨A£ÑÅu"Ӟ嬫 ×Y2Ð?µFÖyã«Ñ¤úñntÍÐö¬¹ù+^Çz3+¶4$$öiN“BþÁÞÆÜ…úX‚Á!j“*Ñö5Šh†ø„õzTHú‘¢˜ åJô[­n«¥•bH¤Ðä‹hë[íÌ\Âò‚#æ¡>ÖªdçY¸d?Æ%Î8†‡œ‘IAt&™Ò›,BFJ ×l¢"K  ópIü5¿ ݲNÖR)`ˆ‘Jr{Ý“‰_”(@ +QBRE2~‡[¾¹få¬^ƒxS× T‚lˆäUgjá›:}>øxÁ‰Xå9*N‚Ü$Ñ0IQµýLŠV2ÿÆK'BAf!Û±«¶Ç¥¯ÚËî qÞR‘¬”!Í©Ø×˜äÑkšöà:¡˜¦E£uÈÿ'«`Ç0FRצúÈÆÍQœªÙ›åZ#vù@Éd&þ}c¸OœÌhœá$«G×/ £û´G÷WLŸ¶Æ„”ø‘oΊ¼IÖ>ùãA'½ zC3™Û²´ô;Ín/£˜Ÿ{Dé™Îã|Hújå:+•©Á [µ-û L)³ºhp‹ÈÔ $1ì‘.¥JA¢ŸB‹HZ¸ìüçO¥ŠwˆÎ Wc±{DÊ™ÎBͰµU®61 &´ÈqX¦B´±§ÎÆžŸPø1|ÞÃgô{Ý´kÌP/Xî!ØX,ˆ:'×ó' žA4 Áe`sÍÕ,”T_:, òÿa¿þ?ÚÎ_”m6üMŸsŠâ¢­×Š,åQ' ˆ4Ì ¿ò)!Š?.ÀÿÐï´2ë hiD-c’öVŸÏÓðÞjGžaÁ]ç ße«A­ÊžÒΫJ¦à¯†þNSýfÎ?kg r'" QÒ¿\\Ü Çãáømåïc8p+íh¦V~¬½a(¼-Q‡qå5Ÿ3&WáöžY3<ÿÝXëïY[´ÿj÷ëêÿ¿v#£ÖíÕ³»Ð)®Ó&ç §õÒ™£)D3ÒïôÛY ì±ÜçBNKÞÓTsÇÛ‹áÇÁ§«I5pK½ü\½Þ¼ `™‰`ôô3 Ölõ¾HÿvV73ìÝÀv ÀZ¡*›M™WèeïvwüÅf%ñO¶-y‘»Ë›ñdps>”vñàyIÅ—¶˜e1EÆ`¡¥Pãô»]èû[ÅøËi~,êJ•,Ó%xQ3ZsùQc&×nxTC¬À¹ýªÿm>§®WHHêÌuõÁq¾”áLãé6Zþ—^³µÿÝûÿvÿíâ¢:¹ÜŒçUQ=]__Nª?ŽFùÜ€ÒWË™ø?h?’¡¶’ áÉ]QÖ+µ°Ë¥n|A½ã:–5ˆ/¡y|„¹@×ß®®> Îÿ‚ÿšèp‰SbK`tGçtþE î6î½ ƒV†»/aO*Ñë—0|èü£9îOTëqÓÎÆË­Q‘ÐŽIsèÊqJtï´˜öi¯ÕjöwÆÓ{‘çsÃ#k¶ 4Gë¾ù½H¶ƒvBz¼Uµ=ù:qâ¨ï.vމ,`ÜÄí”ó€g:U˜²ñÙÊ‹1šÔÊbziŸö[u™î5Ék0˜Ï=­Àr8a.KïÁÙXdvû±Ù–Ä ›¢Þå´g…Q˜TD‰grå¥oRwiô2…)äóì'ý^£Y/@u.í’E[«%l)ÚwoŽ,}9ëÚѱv´rM{­Ž7x’ x lß4æµÃcae?Bóô%œYˆD`å{¨vt5¸þp1оӾ;Ãõ°9ìöOÑp}\9¢¥WbëÐ$c|w«Óh)´å‰&îSÃóç€íÁ4›­¢Ì Z(¬ rLÒjÀnËf'/ÊYB*é5úíÜ))ìEqý .4€‡ =ˆîX®8D¹’!K ÒÛµ¨TþxçR!ÅâôT6¨¿Œu›6 pÝÄÃq¬YUis#/¿A¨µñ^l}üµ5–vñ|ŸñÌ­TP@`Øëâïï?]N~”…Œ+XL&ïV§  ci&ïâ—“gÍ^Úi#|ÖûQë{hB•`ƒ/hÈe“š˜vÀŸ¨&v8á íÿQüH/ÇÿÒèuÛ!þ÷ÆÞþ¿·ÿïšý?L­µçGžÊ$¶½$Ö÷¹ë¬b8ß/îF·»ÀøóRßw™ì=btʰìv›­ù±B þ9ÖFN"FU´¨f÷N«'Ÿ~·4Ö:çy™Ý Yæ‹q´wºÝ~ÿß„£–Ù½8Qû·Åm^€V¼«2G›é’Æ~ç£@Í+ßWx’ßn§^ïç2å4Šö+¹•~–bŽÙ÷U kZ]©Lqð9—}·Û–oM§8M?}ÊÌol/FŸÜí7åÔˆ×åŽîžöÕaÎdp£%é?ß^i.r® À®YK.˜tí&*íHŽÕÉ=`'Â'Bh5Šðº„dq°ßüË]·ž÷I£ó¼Ðâë5»¯gœõŒgôS (J¯Íß:ês R(µEdi©“ :ü™4®ÞÆJ*haÈOëA®ãIºPÀ6À]*F€›áϰñ8_@8«+Ç‹ÂUú Ü/ Ó‘–CºNiz@v¾Óø×"ñòº¬ï¯¯[p¾ïÝ»²ä74SügÌ™{&öï4ûo›\ »ûo«Ùìíí¿{ûï®á?¯†ç“oÃì»L1ûÆÀÿ|LzÂxž*&¸ºï.o&U¢†î~I2ø:Qï^Œ¤_ ší–ÖÝPÿliÙM¦­l»Ê@”›H™hÐ8$hÄþnÌ6ÔäCqîͯF9¡&\Ý´ËÂdjwûõ1™hÿð#$Zh]ÈøO6Ñ’…n¯!ÛÙ-„ÉDîÉ9 ’æätgÚ³u'×YæxüÞu6«*˜T2¿ò@Ö3d,d~Á2å0¤ôçý\/0ü€¯Àý†¬9vŽ÷à!Çó4sAq™†5GÌ›\oPB.ášPvÀ/ =‘g ¿l²A· ¸_ÍqlĨ‹,@(ˆù|±ýˆ5-,q¡ýä©@}þ; Ç¡öur ‚+5j}²so–v O­4çJ@]æª*Óá…_G’ rO—b$…תFbê±d'¨¦•'kÔÎ’¡×ìçóÔ…7®×•'´/Eù*Q¦ðÞ» BEìï¯;t±Ç‡×+t:y]qöÉl¥%³…Žv‘ýÈv²_;ž¡R>‚< °„|»ðQ·ô§‡c¬'n´ñÕó)ãݹÊû=}5¦gÀHYœ²Ú¸+ŒO;ˆÒä“g<s³ BY1®n›Ôìš3 »Å£´Îü»+Ó[Å *õö€Ô©DêsöØqùfÆpgŽšÅRw,Êf`|kdödZ žÅËgdÝ 5.Ø 6™é_ ÛÄ@Hó„?]”ŒÁJ²¶‰~!ß áØÒÆ~ÀÖ[œ~ç^¹Ý>” >efâaû5ÊšîO=ð¢˜4ŽK^¦Ð†n ¼½òÊám-¥b²ÐC& Çk„û $‘z||‚³SAá…Ù-‚5_ÓF0qM€ÿ¤Ù{4úû H‚@Ÿx·yÀ°1Ã2p‰BNÞ}˜A^¦;<%‘•'ÚÌb_ƒ+¦IU&]þ'ï,È]œ]ä4#cÊgÙGlÀ­¢J ª‡È£!È|ðüvBFûÕ©I¡Š»múqn¬ {N¾Õÿ6+ÇfTÎ\ýÖBE¸´#åŸ;Ò19›@_ª.,‡Œ]É…%ÈÝ}8K« ùI ”"ÑÂm ¦yáÿ–.ÊL”!Yñ¬eö)Ì2F^/¬–,”åØ÷©2…¬ kW,+ŠJ&¹ŒÎ˳ÄØÊÒŽ¾²æØi òÖõ*KǶþ)”³~ŠÒ’+5‹„yªãhÜ$pXùUë"C[§¼Ž-M®ÜׯœWéØdàõBî-­²ªÔ å™GP•`tÙ|dhjŠŠˆ Ù6À©Wí’´™=(ÌÈMŒ¨¨'g£-õ'Òrï65‡ìÛ.ÁBó!#2¾q~¯ 0Mµ™e-“#ûK/“ôu’aˆ›0kÐ[±€Ê=öCñ†q±‡ ÎV²ÈpcS’¯çÎréØXÛ,9ñäY`»Ýb ⺫¨gÙìk°4eœ't·ÁmAµ#=”E=ÓµØ9d}d§èà…d§Z†3￉ÀÅù Xì$Ž™Á£?HÁjà\¶&},oš§_Æ1€ëÐÕŸBJK˜èvZV/#:OÈ^ÊæÄ¿ÂøÀûZ.cÕI4G¿eIÞ"ßáO¡÷é¨.É$Õ‹OÚ’?@ôÔ܉´dZbâ°3# &WIrÁD(ä—FP¤©CTÃÂõKÌq8KýU_½÷ou—ìöã»Î ë’ (ëÙ'e¯£~5O¨bÞétv€T°{M ûO®çd8*N<ðúp»†²^Åšðsýkj 9µ »rƒåî?z–…fèñBfÁPáÏÚ.Üw˜ýAÀëDÌ4 lRô&F~P]— Ý'à;<ÑòúøN2UôÉ%×åËVOØ{•\SÈ»t¢eª'ìJ®'Ê9“­Eñ1džg*!‡B¶ÞÙú:ñ“?Õ¤ÕCþ€8¢fÌtÉRY9hà 'ò«obRÔÇ“Ð*b©â/ã‰eÐYj¹¬SŠXÜi<|„ w‰Ðbóøm.¸ éK˜á¦ªž¢~þ4à§$ÓMƒòm…–D®¦AjÔicbªéöØ%9ñzBÁùÝ‚û›YÀžº\mÖ̘¢œw¨UE+`¼Èpc‚a-­¨¶Ì@#Û‚è;yŠ˼ð/q[‚iMUæn¬jȈBbÃm‹äyròôP-+;¸o‡öû¤Í;ç§ô?l%’MÕÁ®õ©¤³)Ã]ôa6'Gt<=SQó 䟸¢ð¥ñâ¶M]Šô~Žm!g}±ÏÏÙÁ(&=ç3ÅI ÄÚÃdþz‡ÚáŸÉ^µ ÿþ…M)Ó&\ÿÇœ“׿—ݴȧó‹¹Öɇ¿Yúœ\›ÜC¬þð—kW¢{å×™³!:î×·ŸÃ=Ä™H³5õàÀüŒ_•ÊÔG";A}$Ðí¢‡ü.j“ãEÿRº‹~Å:Íÿ»Žü‰=t$u"}Dt%ýSt¨vØÄ/°KñW¹_!í:n²E΄3ð«e~1àa"ÂgíðÿtÜûCè‰@7ùÅóßBÓ’}58ôÆA(¦ÚÀ†tVç+iÌ×øÇƒ )Y‡çD,r_üâÏ?8îöEøþ/îÆc¯ û÷výL'Úx­[øåÄ%ç«/OäÓ/Ñ ä;¹›€ {ÆœÎÚS’ðZhZf\žÁŽÁ+“èŠF]–Qÿz¯ýú`@¶ÓçDÕ7EµNÿôô´ÓoÏ•‚Y»“' ŸòŸo|>ÖÄôoðþ?>¦æ£Cúéq(÷7ô\„«ÕÎèÕ(G¯k’0 iØžÏ:Qó±qÕYá’¸6Ù3•XÁá6õëÔX?Âì×·RŸÖ?Ãßþ¡Q‡OŸ?WŠ´)Ô–†ÖÔZZ;S{*A™É^+ž~#Šò%óC„> uIü,-$c¨&ÿ'4ב•FCœÖŠ¦ÛƒmRPWëiýØÍ+“Æ<¿%oŽŽÔÂî͈¢W*˜ä»ãˆMH(9i+bº0´ùª•ï=loâ:SÙ¡„N>V6)_'óBĆ%Tt`ߢz:ð%S"¬ ¶©‰-!óÞþ/by(fRí×ÿd9¨Åë-íxåK½ªé„«:ÉÅ.*eSeS$ÃæqÚ£ÛjÄ®›áH\LDZ”¿1K³€O_qR,BØÛé6Úil?‘¹w»@8~m¸Nè;Ä ?ü‘Ú¤)°¾Ì­ml2´Ló[ë ½±?ÕrÝ)ºÍ^§ù¼4¤’Öi½ AJÇX†N#LáM nZÀw É YªY ‚¯xY¨¬ŠMY”c€t@§#÷òË [E P€8” |¡\Q&Ђ¸J¥— Tx‹Ùå®q©¯¢ª¼ܦÔ)^,‚æ8«*6ÂF£x0.x«@ea+V1ß ?Þ Ç?ã©€c bÛ±wz€|:¥)|èùB À2# ɲž*Râ5ß0´ÄRƒX8x4­X?iÀß/íHÄÎx›)…dZK- ¶µ»!írù±’²–Üñ¢8Ocî")¸Oã<¼˜å 9Ëø]à“Ѱ5ɨ¹®KúÙ§vrµ¥é¡ÿ–U‹‘ ÌͱpI!w³{ˆM¦ÙÛ|Û¡þ$l†OÚ#òY™‹¬Vé9š ¥®¡Ô`Y&‰ü-ÆÅ4Iñ*ĹƲzÂc=­! ÑÖ¨GÏœQÓŠø³•®Ø†ä‘eæ:ž°‘,â<^§*lذE“)"áµX ¯% mrw0Ý2@ÖÇs+‘Ý;²&”›´÷ïŒ;¼4Uâ¿á.hÑIû (pÉøoÍz£ÑðßZÿŸz£Ýn6÷øo{ü·Ã»”ÖÉ®£Àî:óM[Øùƒ¾" í_ÿlÔþõÏKé±DØ7ƒRÈ`Oø·òO Ðo3r¤I‘ðÚdCzÐÔ­WDƒ ôÖ˜p¡Îˉ ;dÛ@ÀùRþ_zb€ÞøãpûQ~eòƒ?³ Ý=Ãhÿî$u;½<©÷'ùô)U3“T-U*ùöÖì4Nëœúrh{äV’plŒ/>J™Ž–C&¹D>´¢D%'ô´™<áƒ,Ò ÞÉ74¥E÷æ‹DŠÐzÂò¥c‰‡â•Ãc|Ø•ó?£mB%õZ³Ùi³;ï‡I.= i/¼Ç kE.R–9uuˆï¸ÒS÷ý,EvdQw,ñ˜ç%W¤{'ûYî ½Ò€ñ >~¼”뇻â ÊMÁ?6˜3w𢠹Ê 6 ¥Þx'Ú9ëÿÊÂâ!7Þ5ô/0Q½`ϰ<þõ£ƒ1©¤f¢0*­f¨.#4Ή†gª27á7)LÚèµ°Y,LÝHÆ!æ±ù´º|"š-ì†3?0ç[™æ|;qÎK‘±#zmÂ]ÒY¬µŸÈžîš{‰è˜qm½Ö¿ðWmé})‘Ÿ,GÊ£ÈÖ#®õôZH¼š¦M{fÀÛù[EæžA#cɬIp:þ¹"º'üÓi«÷Àu Œ‹L³æ‹æàYƒæSTR-Že9P€AãM5”ŒBŽxÏÔ{êù%öÌònã¹ï¼¢RßÁ‘üœaÞñÕU9­K<×CÿhßÝFFn{Ñ]þÒ§ÿv¯Í«’WëõE'ã*ôÝ죰²ÀäÀÑæYà_]|Oƒ|ôœÙcígÐ#ú/dIô çZÎ;tºd-b­Ï¬*y„¿+/Ö“øÕ*ÜOôm¶Ìx![­¶J"ðAÊ¢Ó´ð¢ã^{šœ'a Ê}X<‘) ±Kˆ$‘´„˜´< ‰™°”4%Ò†OÍg]O¦`Î+¼ûÅ^a¨ñè€+‚®„ô…XÖ¦+VÒ®è/Æàr+W†26Ço¹>CŸn¹êá|^ôØWpÚ­øðƒBËGF)`IêÙ¼V)²ýR‘”ÆþBC) í þ²U•öß>ŽŠü^, ZúWúì Q/¼•wëBõÜmÈhK…·1I#Žwœtx†S™ôO’¤Ø#2nG¦åD /G*¨BøIž˜I“®J½Ýw@ŒË8 ÞÃLgŽn‰±Ç4†f©`(9PÔÖ& mþª…y¿aQ¿h“F«AìѶFÏ_ y¾ÌW'µÈ€û ®•rs5pnÉkwB!>„Ç@"©á€:‹ÊjA”‰'ÌFËÂxï‹ë¡P§ƒÅ,œ( L¼¼í¡ ^0‰Ý ²(“;ÅÀ$Íã³%C®ÖQÚ‚M ®-*Zô9dWÃJ2x½Š–„=›%—$;Ãò–È ßÐÅÍšŠŒûa_:$eÿß þ‡ñ?ú|ŽD.D ú²ô äøŸF»SïHñ?ˆÿétZûøŸ}üÏŽÅÿ ..ªDAVÇrƸþx )4àD«ä̤ŒËw#íŽÿœúP r¬#’ø Ëå˜2.†WÃɰ(êub~Bƒ»eÔO°Í9C~BC´Ûcô0”Aû¨î%Ò?ªã4`”Ñ}”4N–2uÉh¦Ã™…ð(¸؇ÄüǤ,í&š CúF9T‘ýf§¯$ÕmG©ö)¿W¥0 ÊÏæâˆ—ú3ìõ›§ýNwgöÂýœ‰\ß‚y—Šò^P}p\3²·-Øí›ÛyFC; ’JD‚Üñ•& ѱE(ìn¦Â!fPÌ@~Фä‘­¶çŸRø§*©=ø<”SE¢ÁÒH”%Qöl[ÓJƒUn´N»§É°Êd;òTb¶ÌóéíHÌû4 FØÒ¢‡„ÑÝyÕÙ¬W›5‘cŠOåo™¤ŠZñÝ1¸… ç l›þcÕ‚ÓœG ù™ây×s ±Ù'a"朥¹Ä­Hþ㩱TKA­—$^@÷hqC§î*Âá‘Q " ½k˲4سòLΈD×Uü!êD ‰A€!‘±Hây£ÝkvÛù ÃÈ}}Ç#_®3ÌŸMæ•#0ϲ%Q];UFv䃢8RÏYš.‡<$¥Çù0(儃D12Âø7g¼v€ñøþ{­Y¯·«õ^µÞÔ½³Vÿ¬ÝÏõ;°¿ƒOì´ÅøÑ©('(â d¡Bûx7ºæ•ïšÃ¨ª¡i¾‚411(<|úŸžóÕ4Öpm§P$MMCh •‰p%>¯´ @ÇæÅË@ÔEü¤>^ikÜÀ§9P‡¦}aŸ”Ç+Z¶9ǧ9$ˆ±ÐøI}º«i€Ç!.)¦æˆâ'õé©^‡hcD›ñOò㕾¦1È([ h÷ü“òô)pL¨$ .„|z¢Ÿ}Ҩˣƒ0$ÌɼÎa!°‘Fû´×n'ƒ(9ËҮؑ`Í’šœ™‰N%XØ™’|#7ð9qÐùBj«ÓèÉœ Ï‚JÒè´<2*ÉõµÛ².~u°3Mw´Ü ÏGw—7?ÄÂ9DV_"ƒÅ+V€à­=VH^cY,zH° "ˆd줂°—ã‰$É8â#PL)ðn£ÞkÆÀk¤.„Ýq‘¦›‹&ÞÖRÙ÷ÙMˆ¹¼¥þ$Ú…,üàû·÷}¢ÿâ7³IS…k‘×Kò¦øÿZ½f;àÿëvëõ½ÿoïÿÛ1ÿß§Û‹ÁdÈÎ!U¸ëTÇW£Éø[ð:ŽÀbá%Œ(ûˆØ\€Íµ `sÅl´£Ñèâúê8ÁM£CÔc:0ÁÈŠ8]X0ãwˆ,[€aé´¦ñ+ºæÌ–ÆÄÏémÌ?¶qG¦jžÉ¸]­DeÜࢷòÖï“6 %H0ŽJ”‹Ô,/<‘‹m<‘õ¦ eém牌ëÃl>IîoÈì[”ËÎåÃ,ä”,䎬7{Š«÷•Ý‘á.ŽòšpÛ”Dï L9}O0g«øBœÛÉg:ñ½L´öm\C¡i‘ÔFŸˆÌ‚Ä]JÕ”LîÄ„Îè ¹Š_ИÑ#¨ðMgq±Æ»^‚Ýšß/WoõÛ2ÉH„_Ž*^ÏxÛ€ž‡sz1Á;†–;É1†î$ÌE:#*Í« ~¬ÐÔ=A÷Ñ ¬;±Ô3H±rU+QDbó3yB—Ï®¦%9GQ²sQHNž 0 ‹|1.@€»Œè>Æš߈DÊ.¶Z¹ÎÊ5}êVz*t ÍŒ¨I0–ñ9£N½|Sˆ¥L{9oyŒ« †’¾sØ;úþ|¡4ÊöY˜£>o’WÓ>n\x~I–ÐIÎáa%N ÀñB£”·?‹Øêëín·Þ/ÄJ”ÁŸM’ĈááƒN0€ñ?"]OŽÚ[£ñV;š‘O\–7¼F¹BOPÖI¿¿QÄ`L ‚ áí”LZ迉u½Må29#Åž…šÝ·^hIUh‡—_u›¼2{8ù_Å–@kÖ¿ÖLþ°Ò¼¨˜ß+GqÇYVþubú‚úŽäg~ÓãÛV í¿Þî÷Û)hÿ•ƒkê óDćКEÖ[§Þ”×[”oìà†h °N*¿¡`Õ§¸Å.øDÑš‹U)ò„y˜âlØÓk‡ÃªúÀNæÚóCÿµ1+Œ5ƒ”ôêÅ‘#Ÿù™ž‘ßìšçlÜ™± jبÙQdc½'Zôð7<ÙH¶ž_>…úëüjpÑ_ÂöY9 K.ìAj˜çšBz·ÙN›BùÁ_z¦%Ž2à Ö¾¬Œšé¼{ÆÁí 1¶˜Ò’„¹í¸QŽOéÔ.9$ \nåà(§ž´?Îþîˬ¿?†µÈ·+KÈÖ€[ÂÚ»_j~C»B°w¶UPï˜ÈõfŽê©€ÖÂñ…ðÚßxZÐ#¼·¦áº†v­›äi²<ç2Eyc“™‚ÿ©š|G'ƒ‰|‘¾o‘Þ§}?¦Ó‡(`i^h—Ê„Hƒà bÂ#ŠG„/W{ãÞù ÂUæñ„ÁéE©ˆ¬aÞOX VÇ­Qš³C£`N?:î‘ÿûµ]k¡(äC;Ô"EÆÊR{^ϯ?ùÞèA©ÂýX9;–Y8ÍZ¿¦5NgÁwžSÞñ_Ü:©¿-&I½vZkt}Y*Ï/ŒÔu5òÿ^²#FdE^Ë}Ñhó¹3©Q«ƒïop}Ñ O5I°wë¹ÎëÓn?¨÷zÕ‡èʾ!”«ï™:õPÜmä}£ZVÚ?‚$H2_[µf«Öiœ€V"Ó¨¢uÈ¿ÍöñsNß[z܉ç_{deÃ4ÕßÀÝš+jƒÛKüqr~[9`§¥™cÛôBä=ë’ÿëÀ"2ƒ¢ÖT‘^¢ÊViU^ÐÞLÐ1Î}bv}V¥æê3KP[ŒÎ/·¯Œ,È™ùâƒt¤>J8‹HÍ>NÒ”»ãK1Ëí e6k].G³Ñî€c+@ª·Ç”Ü™ü/¸T/ÈÞmU1F¢l`šÿ¯Ñkñ{ÆÞÿ·÷ÿí˜ÿòB?&ƒ«êðînt÷-¤}!æ&=õEsÎÕÆˆ„Ÿ¹6—†³YKZBÉŸ\^GŸ&´s‚¤UAÙKøòá±-ÿ1¢Ãò:#Çi; ÔûeäYvÓ«c‚YUbBû!ÔpõÔ5ù×J×)þˆ'Zù½:AЧüéV½Ù»N¥È@ Á×ÈÏŒ¹i6WäøT’&äÀX< _ú¸Õw>º¹žO.G7lnöðeOŒ*O\ðuë‹Cd›ÄqAFëÃ`<Ì"‚ZVFbêÍP]D-qOãˆ(/¤>,¦eê ‹5\ÓÙxQå&Íúlä丸„¹‘:+”Ú’û){›×¾ÚÜñ˜½F³Ûo$ÃñaêR„zðX䝿ÌfÀÒg¡Y*þª y%9óÜ®¶ñ(‹Ž,øê½¦@I–šñº éJ† UÉ Žñ;Yóg±ü´÷KÌá™ÊOâ†ü†—i1EÇ÷ÌðxId#iþˆD=ÏAäÄ¥°x<{-dM¯xÀÚQs<”\5 ‹õ-"„4kÂrˆ@qdnþ”ÐפËWëxkðË‹¤¾!áêµF&$ÆsÍD –dÆ(TíY¥•Rö{>pµ]9?­éuÓóŽ•Ð¨4%Œúžuù{­¯QãeÚ3 wb”h_™ó×%¿þç%›ìK®9OÚrò™ •& ÍŸ÷½übœ§úìKÕ°ç”iާ ‚;ÔÙ3–€z8c©‰¦Ç¹Í™Wº3€œA@Ô}ª¾ö\ˆ’ä9g…¨o??æÇøÀï_ÿL$äx®)àõèÝŧ¦‚ÒuÈ™xIU;=Zói8WŽç™Së 1“Ó'F„ë(ãÝ Ýjöú©¹Z–×ïŸÀýûxÎMó$ÿ›òÙU™öÏX°4¢í [;÷ß׆íÅDîxb&ûZÑœ¶ é´ÿ^Ší-7t¢bsÝ ')eïÝû¶ü3€’®âH!йYn`Šÿ¯Ct„äÿ#ÏA‚÷>ÿoïÿÛ5ÿßùàüÇau2øp5¬þõÓðîrøM@?.BÈ<3B·‘þ>¦`>Fè*Që{ÑsÕ‹áÇÁ§«ÉÛäôAÃ]Gã=^ÞŒ‡w“@xŒž[zS»6§1ψo™o±2œŒýQ¢£1bÑÙªÂu,j& yÊ‚áA ø$4—Ã$×ì6z-jd;üƈnË݈¯AbÔYÛŸ—O®tc³Ûl(„ ¯ ÝêâŒDr0 ¾oq›Æ2ORy¤2­1…S:QZxޤ7=¥I±m¾¹¼ò[ÓÎ…µñD6Ñž.ýQ}wQœ.7êc£InÍ~¢û—éj/¨¬U5­™öÂq—tßsdUêÙiÍB ÒÜi^³ðš‹lä75ÐÙ¸0ô¹³Z×´Ëf”SD62QR–¤Hh' B2’]j®!løˆ¤z|V²ôõ¡&€Š¤µAs2ŒWÄvfzÔ ÃÊ×ÉzBg?§ÐS¥²EÇ£×9ƒPsÀL—ÎWc~¢‘Æ‹a4ú”¬gV¨aÛóZÎÒ—ú2±Ý'aI÷ º~Àmî}r1tSA¹åÖúÑ;äiò^ôÓ:ƒ®„9H:«ð²A…FöQ*ùêÀ"EØd`¾ÖÓ Æ‰®+Öz"¡0èY!%ª…„Ã[)OWíRY÷yÒàéA1tºx¦YcÆï`b&‡í'\“ ê5šŽÂ®™ ”s½Ð[©­9¦â¤rDA]é“Ú¯ Çù8P¼9:ú Á¿to¸ÇA^>íè×n;Ÿµ…åèë¨(ä;”5ÛÇQ› œ2?æ‚iáX•ŒhvH¤=ôÁì¡ÖБxæèˆôê¡vvy3ikm¨D­q¬RùɯFƒI_ëû?ä䇷ç?îˆäìÿè‹LžøÛàŽ>Òé°g¦ÔuV¬k¾B··º)ÝÎ$·ýãL}¯±YOUú‹E«;ì Ò 10AÉÚë×»yHùÐ –o îV=€þ àË£B:õV³“ÈÁ÷\8œ%Y½ÞVã[‘§‘~ë4ºý£$õu;ñà©ûAŠé´ÓF«ûíÃ0cu×.ÊD ÍjÆÌå¯Mœj»à»U,ê{'îÇÿKCLŒ¹°)¼¤ÿ·Ñèöø¯n³µ÷ÿîý¿»æÿ¥)Và ‘ç4þFr@ayÊÂãí¹vÉéDô ØèÂhÇ$xr…™º(ÀkÌsÆn×Ã×ôãFŽî¶~\¹»òæ~& Ñ6NÚˆÁ(ÅGÞFÊôц‡}´wèD"gþ‚Ûû×PB)Ún¿Þotëõò<´áNãöì4'¨ôBno(´£Ýl¶_Öš£)!7Ù$Ëv1A¨Œq†|èXH³—4ó€îŒÉv¢™5rYC3öƒã……4TÓ'mFC[9™h%zâaçØÓR49c”˽¸ ~_Ýýua’ÂjI7è˜9sÚ¬7ò™±#Dâ¶Ã›Ë+ñ»öæÈ6-í×,2-È á²£‘:HS3µ3•öÝXëïñ P½'?Ü ÉÇ3ÿ£Ð¢Úµû­ú‡ónç¿áEYV#ÙÈ Ï\ è?a)–OÑ\ÿuãÿª=ï .Ôj£:æ(gY0¬EÛÖm±dB6ñž».˜#9ýi»ÑN±÷¢%)×.xÚi÷£Xž>H,OeÑ!eQ€4Eõ\ePS'tÊi³Ù´š»ÏÉ)·súâ–T¿¿ÇöË1?öçèêì|R‰¬s"{u䎻ÞBLÇ“ÁäÓ8¶2úJºÈvã/í@dîåÀ­Y) ™ý*óÜê5åS­bpÎÔ²/'_¯¶Hý‘ŠÝÞœœñ•˚̖ÂØ• üÞlü Ú!—Î5¬ò©¿²Ø{ín+`ÿmÁW{ûïÞþ»cö_D÷º3,~ÛmÛ/,ëæ¯fí_ÿ¤ÌPÚdC6u+ÉìûPozõfàˆ™$äðv„¡FñìÀ¨jÐÒ¡5¢8!çðËë2‚…y[°ÜuE9Á`ÀX øPò@?>¢ÛX‰ƒCµ+Äa|·¢‡ÕÐpE³†‘Ý%˜Ñ³áê##½ôã %ÁŠŠ^ß^~ù«Ûùàùèúvp󋈦!—3òàÔÐhlFeÎ!rjiÚK–•W±Ì/ƉvøÓƒ1S³ô¹¹4Ý7ž¶ÔmÒîÿ8Ä_õ5r}éö“6wHÉv{re Š 9ÎÆšk0Kˆb&-ôCÁâ ‰f|>Q7©‡èa4R¡²s(ÐtZá54P6ÖBÅ#ýQ‘ûCV%Á+×.æ­¹+¤}>P–@%¬š¢F²|'QÖ¯ú]ãQ…i®ßx™4=!£@´N&–ë¬Èö¼†¾õ .}aÁÄþþ{è,ž¢áªÆ;ãP7âùjàù´ú…2µ3èqéKHPÑŽðÛ*íþâ7ŒžÁAµ ¡’Ò<8[Pò½ðä@¾‹ã€ªŒ'¹Ièóѵ{ó+8°h d6$¡f¥èC†‡pqä銹þ0{£GW .Ÿ0þœÂE7ÊÉÿ8nœ+xÀÊ7Âòs)Õ!&ƒ,zªrpæâÁ–?[•RÇö zX…6>8ˆRò}Ü ’Ÿ`X×dP¹:?##Lè\Hÿ—í„åD‰ïȲ§Ì#Ø; ½O[ zÔòÕœP©²*qEÅYaŠó,}@R×+ô+Ïï­ð¢åäî6?Âï=q¶Èßwån’’‡e'ÒÉ/¬ºvªäŸþy‰GX¤ð‰ãïLd[L¯¸9ááýà~A8~RYñ&×t“ÆÄWÈm‚]–lÞ0?–p»Õb*­|„à )Á-qïhÀHÙUÅãñù£é_uÓÂ;«³b…ð½Lì‹ wtZM—Ó±¯N@ÆåÆ[³œ°' ½¿ñÙÂ;<ú!(Z¤£éDû®V4°vbJ•ÐKãSªÉti©ÚÐé)D††T0-QˆÖù£ôÓ’"cTö=pkò'sa¿b.H·žGèÙØ;_v¢p(ñüç›uòìDLéŠGˆ"§Ì†WÃPýÉà?ãL³”G›n¸8Â4É×?=¨^á­­RGï„-ŸÀÒ…â'_ÃËØ#üž«ÛôÀè¿}¢1 eÎòþ÷f´3]ÆÑ—1Ø“X„ÇÖ£ñÐd”ïÞfÊk%Ç“:çiÖSÂQç“=‹¯ O9Ñ×B¹+œczg´+Ô"¼Ð˜nòÔÌD?ÍŽ¾Ì®óã¹çÊïðPˆTå@pâ3–Óá”sìÒŠTfÄs ó‹'G°FÄp)N>K‡ŠE „¨}VÞG°>‘®£åp.Ú{aXÆzëòÈ5=Ÿ7^T[¥ÔÊ õbÓäP§pl¤—]uïè–`Z³UÊpïa»ÓÈFm<’KûWÃrVè½q7’Évå: ¡ œëœcAÔ­-<ÜæA-5X‚ŽjUØ{|J$ÒŒœÝ<Ðxÿ'Ý鸔_-cxV€“F‚ í‘¼µYÔÍD=¤èÇ…$X}iZ&98ãÚp+iL4’¶ÄدtÐø¡%GÔÆt¬y\25m’ õh…$Ê@"䩲D.2kÝ^ &Cß/ ŠÚR«Nxmófð)©=êOÔdÆì·Ò¼ãŠŸñƒkG`§=©å`F ,sꎤYà ô…¿‚:@9ò vVFs"¸2Ïl‡’~Vú–4ïÚ!+SêcO^aV9IMM›¡1/¸ìùWQaSù´ç_æVúì P! Eºö'ŒT½Z%ä92^«3C¼*<êHÿñ¥þÅ)ŽmA˜ ©–´{±±d ßR¦C°šeQÿ!x‡6÷÷† %ûœ‡#›¨*ŠT;„ûlº^bÒaœFì1ý53ü@F1|Þ“ÉUr¹UéµÐˆ©ác\x±ùxžU¢8›ŸÛM ƒÃodK½d‡,D¹¾SºÿõØn¿»úéÓhç ’ÉèV›õ6úÈ…\wïõŸCë(Vða=gD~[Š+^=ïl°-PËsg¿ÁQ né‚dâ p9tøÒÅeõÙÝ5ï3Èm7Ÿ³Ëî ¶(€¥eC6JÚq°$äÉßÛõî±#ô;Å–ꄼ]{w¯á9û¢]ù•79Ø`É˽k^£,†œDÿGø©v™†œ\!ÙÌ· yÇÏn…ø÷w¡R›ƒùÀ¨Â'w.C_–ë Jñÿ´[uÿ±øÍngïÿÙûvÌÿsA.{“a}Æ“»áàú[@¤Æd8Ø&¤ŒËw#rØ`?'8~ôù<¨D9ƒ‹ ©Cœ?ô¼+J Ä“\]Ž'R9¯Éç5Ê[ºs¢:0§C'4^Ûøw¢Ç¢ ÈÐVR"dh`þ#ðÞP[Ѝ({Mïîp•›ºŽ>Ÿ5”Fl‰C, 8WûK¢ã< „røüºnçTrß-2Ô½ÙØü”g%:¿¿ IãôiËŸÌvxJ?Ò½§§õöÎPú…û9#§y s)Òø‰Jã¦Ë&éA¶•-8çÒúpdÜxèÛnXF…Fm¯ÞY%î+°ýÓ~ L†¢Á«%Še¢˜Mïä—KæaÜÓ¦÷_FÂü½Ç•Vž¥Ž9?àæ`ë)v=ç&Hì6ú]…Ô'½–n”ÔÆém [ØùT“Zl³þ^ÜpyŽn²þc°Âôƒé„‹ÁÈÙi¾Å ¸¬ Ìß›4‰d‘Q%¦»¨êè$>%/FùÙZµâÜX4zÁ¬SIpRáûŒ,y'|ü‘넸@r±Ÿ\·qÚìµòñÏÀÚ±Td×±?•çlY‘=å6á€x žÙ´·ôBíΫÎf½Ú¬ßòºYO(º …—ÔˆB4b¤ËÛ ÿV*˜´ÒZRÁHMÎÌD¯>XòŠóŠ¡w‡‹a…æS·«€£ÉÅJ`Æ"•ôN_‰‹ÔwÚzy&.°¯Ñ9g‰˜ îèÝŸ2]Þü¹,¬Ö«³J–ht›Y `QEä‘߯®B†_Žêm¼$j!ň2ñHæ¤Êç„ìõæ0/ÅÕ¯Q@†h¸”î0=$d’dä¸xRN‰\¯Å¸pæÃÀéZ np{©°ñèï»ì7V_€¦¹H#(úËÏ SÞÆ ö¤‰Þ²~SÕÁVîªÈ•ɲXU4–œ† ;•¬I@Ð’Õ©Ò,Öýå&Àhh½d³äHµ»ãÔ°œGÀ'—a÷d’Pœ<šz4ã—kÙiãC‰Á ÊàdBWE_”âŒÕ‡‘+Tô Úé¹IÜåìÜm]«¨~Cbiy(ŠúÖW…ÛÔé‘Mæl K¿¯4ZJÁ qrRw Y+ ¯QWÚ •#hÚ ‚ù£ÖÁð€‰x¨k@…”u ûå›"©BCq3ù>Fܛ˫òÃ2âv½r:v _9æùmñ=yB±åMÏÈY…R ©ÓÉM̾Ï>&Ee²&"iiT®>”-'-õ»g;ŠÚf»Õ¬ç ¨]Ó4´Ø#€”°¨Th^º"¼ÐñYÆ‹rã#®Ëo…‰l^«S ­AU4êfæ zŠpü,å‹%¤åÞþ„Ð>j¥¾f¨ô].Øj©½´\‘7Œ›gã­ò`#’`õõî9¨ýBwVŒD…4(³ÏUA“ʧIÑvТDB急 ÅΦræ^‘ÓTå¸r<Ï„Û<;@üDî1G€]I-<¹µh<ÆëŽÈM Òbcx‘ #O½ºkW+çPÇÿ )ñ ÎR ÁS=ÆBš¼gÞ“c½‡ Ê.rÄÀ÷#|"¶Ãu!W^ œt ª¬€@Ü Ûè¡”«TÇ¢ÝFijžøÞ­¼à+Šu! ™ÒŒ†¤Ùhºƒk´ïPÕ¸.y UXqñN”åVRóEâ5¤“>{p~Õ¡ €²`˜̃P¼·Õ>hÈàÕ¼ýÒa8Ѿšzè`O¶DðÞGO3úfUžlô?&6¾‰'Øn_0.Lú‰h±‹Ö<óM!r*ù<×DÂtzW…|ª]` Ûh’ôdÐ$~!;§IÄΪÎÄVNŸ#¤„ê|Hx…Ltÿ•È3¡|àv”y'€à1TB[˜þÅï]-6žŒ=â³L§èØްÆÈd\j¢/t<;H¡”EŽ"þÁƒ²¿dˆïL2‚JhÛžBr±€·O»§ùbcºE{st<'‡Ú!™/†g.É'öþs¬¡¹ˆ‡úá·ïسïðÁ&Ÿ¥0¥/eK$÷׿¿=þ¯Bm_ou?v/þ›†&*mÒÞ&‰X‚ŒP6–ió™¨1GÀ™ÿ#î†.âp¹KÄÖ‘¯•xYà«.Ô°š_±ÿéŽn<ž"UýLûõün8˜ «7ß>Sœ±ˆ³ üNƒ¼ói<¬Ž®.È_ŸÁ5·!*ï5É{ƒ£» ®ŒÏD XÅÐ’‰³ª^@H¤àÆts¯iGØí?¢éîÁ°VÇQÏqLúp^~¬¾OÆÚÍå•v¦x µZ­&•?v6îÌ8“êù^ûhZä›w+÷?ßá¨Jü_mfIâÜ iá9 áÑðînt§½¡£L+¯ÒïÎHgV/>hôŸc¹ÛäÿŽü±¢Rß o¡CãÆí0®$íh<œüU#ò}ºšhßÇWɇZ©/iÌ3ÖÉš*×\ÿ¬Õs,úv§ñ±CýANoK§Ùê·“Cˆ%“©j®ƒu4%7²Æu lA•ƒànH^q{@JC@1Ä÷B_àjeè.g²@j¦ƒ —ê§(7>‘nÈg[ƒÓ8î§Sgcs'F倣œ)ä'Y{¶SO‹_¦Û‡ý²„¯8ù°å94p1ü8 3Q x{(²Ï Ø´yšÎðQ‚a—I"‡¼q™j« Å•*j¬ß!VLîD£”uØ»uÅ@˜QÎÌä±8fƒE˜6ò;l«OîvàK²ÄØìæ*2}èÑM±×ànËnµ•ÜAâNñp†GX"ùKD!µâíÀ¨~"ú|ã†Í«ÀD æ~¿Bx(uqöµû§Ù„óó ¨vC.Á¤Ï—Þ QÞkdŽ\»Î†|U9O¨àºÄw•&Ñ;ÊAR“Ä4 4Kó[ÅÎù—™-Ó§ÖN®Ó±ê–;¢ÈãsÎWFNIB4ˆ á™[L7iLoâ1Äÿ¢Y(S©vu o˧áºm%ãçe’ …*½Ï½…äŠ\7½È`¯‹Ë1&>V]¼Z ^qލR’k/¨´ˆrŽ#R-çH1׫Â|¼¼ñgA¬Qöþ|¹,úzã…2j&ŸÆII4䕲È*ì‘\=&`’âAEÁ…ý ˆ{Td{ë"^gí¢2YÒ@Õ• 0hü¾6l&­ídîCþÀâyŠŠ(ƒä&O(b®Dˆ¤ØÕH‹ˆØWJÉŒ  †[4MÞ³¤¤à5ÛM™ÿ…<×h×[Ý}üÿ>þÇâÿ17 XÏÆßB Àb>·'›;Ž2P;úxqquœ 0w*‹Àqónt‹}“èLpÌAÈrE.9f‹»}Åà~eˆ·ŒïôTÎpþ샵MlÄ”Õïï(%öûcÀ¿ÀH'3-‹;2ÝËÊð"[R§Ý®—àåw ?~f Õw‰vÙ]$.ÒOýÓn}g"çCÝ•ˆ‹l{'éŸñ +ºe‰Ð‹Ò¢B3"5…ÚrÇàÞ„O*­}E°”>Û5ŽšW+ K©Ýîö›n –RP÷0)ÔØO¤3G"nÍÜi´¢ÐrñQ|ÒÃÔg¦²Rj^ @ÆlÔwÔ0I—ÚâÀª{¹È'#åÔ¦ì¾R¸’NãœMz„EzcKaaœ|ÅV’©ÈR­ùA_Úí^»Û®çGF¢uŸa;´Ã…kÌ 9öئíývï:äÈy\‰zä¿°ºÿ ƃœüÉ'wCê§é?Rþú¿ü0Wy‡Øtþço¤påüÒ{òÂ_Bµü[¥ Ó‰,…|Uù:¶$,'$2þKá_G z…Iõ}ja¹ó ½F¨8é—à‹XjÄ›¿諹~’¾âjF*Årf_ø[ÆÖ$ü¥N®¦‹ O‘)ÝíwÛ‘§Š¢%‘ZúÍz?T¡D‡\ÂôÁTòbPQ¤¾F«Ý~qï  _.Y¼^/c½)þËE¼(i·ÚX ±@¥™ïÃq•+”ïC¾Û«§Âûd¾ÜàýLÆõÝÆJ½ü5©ûfìé¯ÿùxãùšÙ³¹²ŒöPBqø?½û²öÿ6ù1hÿo´{{ûÿÞþ¿kø?þ1äì@Õsl™ >\ U;~´+ “á•ð}”QÞÒÕY;éžWÊ€öñ·•2á}üáA7€ˆ¹V¬ÿåÿ[Ý~¯DöŽð%ňoc»óãúèy}ÈRØ,í*Þs¼©:ULn®:Ì4ú¼¾‰B^‰V¯¥xo^Ù+Ïl”r²Z”%XžFp Ø|Rä½ÿ!sût/·§…3gØçHˆü<=³6³ºGJ”$q½g‘çE+)ó¢ÝêwÛõd8Œs` ‡áäY¢;นðuïƒÔP,+Ÿi™ÍÁì“\dÌÐæÉú…SUЬ?Þœâg¥ãBDNYŽáÀ§Í*<ã2y¦xò«ïŸšnÖm®µT¢¶cWÓ\¸¿ ÷!Iú»ÍjçŸAÌ–5œÈÚ!+ðOÀ1& äŠÁ k€Ôè-ž g×Pë´ÕQùR]CÒ Fû•šô«hÒÿÌR`ÎH·þê¨û_¦ë­1ÿó3yZ÷?KÝ´ø+ògˆóD~_YΓaG´³GLÚüõOÚ¯¤‹É‘Ñ5矵ÆçÏÜ¿T©ñ*ß~æe(Ò OÔÑáŸÏX+èxMNÆäø ÔäÃÿôÒª5Ü"©Ž::¼2õpâ:kï ¸=Öô“ò0{öÆüb®uòÌ_ÜGÜ—¿°QÏCÙæœ<ôÁ5þñ`ãóSö1êù_6®IØpRwài}Œzú/lc ÏIÿÙ†ýÅ!ŸgüsÔ[׿—22ä±wª³VÜóÏQ¯|p\ü;¿DÇamOôSÔóô¹¹4Áx»¡²­à_åÙãìþ£Cœ>¿Á”ÿ‘îÆésXˆ¶„LúN¿™Õy4é]ÓνrÀ´N{*±ÝkzŸZ§ÁŒöLÞ§Ÿƒ%噋œû/ÍBó±ßÒ¾;C%²§”ô,øŸ£…°PЄRa:V°¼+ŽÍQÄGWoöûõ—öÑ½Š£, ®Ra`D`2 †ì“úÖtu¢¾êß>ÿF6ÃØN8É2˜Ær9ÈT#éxÉÄâÝ{ÈþüxÓ žÊó¦øÿÍV'àÿëÖ{õ½ÿoïÿÛ1ÿßO—“«A¸Š?Õ‘)Ï´ƒxÊs¼÷dBX‰@³À$4–M«ÔáòŠÎÀ¸!ßÒ-ч»Âö›2<‘L‰>ÁÈQBïàðwc¶A÷ LJ507(Ð\N”ΣK6Ñȵ>sBÎÆF½ÓSè9·s6Föy6·c¤5]›™ò2ôóK%5êý^§¹3Œê6r| ‡—è® ŽB$€ü•é­èz€ÇK¬=SBϼ±4mŽÎÑ»`‘¸l¹»lŠl¾±'Í ì‡ò²„n«•œ%tk¸ Ç]æPf?NzÏß‹¤w©ŠÒ½Ê6þÔ\:«qÚhæÊ. W†š]|8?ƒÿñu¹m<"¦¢6ºÞhÿÕ>­ŸvÎ k²rdkíH@NjGˆ{¦`«h‡gKcé¸Og‡€v§iG‘R¥p/@È2$?”ư-E …LÓ¤'möP†Ñ-„Dë°—fÇŽÜC¹-;¼ˆÒ;A¾Nï*+ªAXv”üm3Í|=xŸxp)ŽˆiȈ‡||«'cΫ÷…†ìô´_4Ý"ñ„÷¬™»lXÎtµÚ<£,—­\¶ee‰í€i9æF¿74ï’ý—†°Tíž‚Súò²,À)ößV]áî€ý·]ïìí¿{ûïŽÙ?Ý^@èùøj4©~¼]Wìòîâ[°;Î|HÑ Ü‘kÂF0§É׺m®6,®ÁO/.®“B˜ 11êhfÈj$à³gxy3ž n·rGŽLƬz<öªÿéª" }øóð|2®þyDªxEËqüdÙÒvœÞÕ9MÉù'Â6öåø,ÃÒ³••hkŽW´6¢± ¬mHC™+ˤ›îuë§í^³Ëf+¦mÍ‘üÕÉi)”4Â¥Ëo[&Üïöû»hê稠ûyÇÕXSu êþÞr<«cë¿ z×àwø»TñE(ÿÝ÷ƒ¸ÈsøšÉ¢ïÁ¶vãàÜHh¢œ£Ó•–bÜ ÷` MÉ9 ÂI7*RNզ䔿SŽñÀø$Ráü†äƒ-ëÝFý´Ùj&ש®õOÒ0‘ÚùÕhLŸh3óÌžñ«H,Ü ‚Fè^?GC_¯]s ¾OŸ.Ó§äÓW+×YD~§ggQ0Ã…•䧦MÎ÷ΈE‹µËŠìE±w¹ÕU•CÊ=‰Ú‰ÆÆpóÈyÎX†µ?“Ó e‰Ã\º“rÖ1L6a£)l°tH¡ÙAð@È%9[b1DZV+°€k¦ÛhËt3 ™± ­ÖÞ·ÚÑŒ|âioxB†œ‹çª0üßñMÏÐÎäø¸ÒÖ¾ƒäí”\9’ÞĺÞ`@¿ð¢`憜P9bGvÊ•D´J(…DÿZ]é¦ëioŽŽX¦‰vøµ*õø8ü®ß:¿"Ëä(æ Õôf ¯o¯F¿ )MR÷C§Å¹ÑR: BØ"%2zʈt(\“Ë> 4)Ÿ°Ì!Qhö»Í¬9 å¸$ðêBVÜý3w9Æún£Ùh´²;µ.¸¤£B]Øl¶O_œå¤¤ËüûäûFdñü=-)Ò)Å•¹OƲÛýwˆÜ/b(êo‘ÌV%x[ò™rù]’¸a¢VÀÞ³ÿú8Ög­ÊGKãÿh6ºAü¯N½¹÷ÿìý?;æÿÿúiÚýj0žüÀ„¾ˆNÝ”L_Æs3üyòŠŽœà¨o龉鼋2œ4Ê~S¢kF)‰#Dk†e€ ®ˆ`—§ïL§{Z¿4ïŒÒYÏ öœ!¤§ZnÿߋաkBÀ ¶6îk¨¬¨ÿN§QïÊ1¶±Ü ¾Î¡Ö4ݲœ‡Qæ EÈ`ÚŽ€¦Êm²gÕ„ÆùùsH×µÚ½|iE÷i¿.GXcÛPYÚÏO!@jéÖÝlPP%³ëÂîDgŒGΑtº„6*ßlšcº(c¶z¯Ä)Öý I¦t€ŸÀCÉÂïõR1]Ðg¹s.Á¹cPïžæ|°¸üpq…–T³Ñn¾Mƒ85EQ5ð£X]/¤(eC´h‘*‚R@QTÁ“LÃ%HA§E¡Î{{ŸvÌLF«É&LÚe.U/ð{³ºr¨é (ˆ?.ÕÛÑørr9ºI(¢À2¼déžvdgR®ÌÈ;Á—k#ó•z'à„2^ªs¹Bë||Ê’ß;vØþã­.ž—´ÿ×[½ ý¿Ûhííÿ{ûÿŽÙÿ/o.†?ËtBT[ï`Ĺûi˜”Í!‚«p—S‹L&w—>‘KL°W4ü‡†{K˸×vÒè56eXýÕ]¦D³¿2NhöŸ¤r¬tÑÒ†U"^XSèò*ſ߬w›½ò°{Ô®z^£ÿŽ‹“®UÁ‡¿y'î‹{ö„èÿö„è¥3ltšÓ~Š·#IÕÒ8\:ßwÂËñÍ1§³ÓBËw'lòYï¼¹ŒòòÞ{¼jWÙä÷ÿ‰øÿ¿[æÚh=÷wû?¨ÜþS«ÕÜÛÿ÷öÿ‹ÿÿë• ùô´·´Ö®{È1ðçf €û–ìµýS$©~Ðg_ªä/)ðE  Bí”f‚Õßqõ™x}„ß½¢•?þ`nvÛ:@êÆœ.€´ÁÛÆð/Oƒ??LǘôùãpªV~ýòST®»gäfµ~ðSèÖÄÎãù‡ Îíò©8Rêf&©[ªÔò­¡×­wOùuùÊœººkâ­¡Uûê=RŸæmŒ6eƒLÑd®áUÖ… òˆ~#Wy }Ò&uí’($nŒ‚o¨ÍÚ$•¨—òÅÅx·ñÜw¤ ø?~‚€;2ÅÆˆ¾o—ÔÛz›ßÏ9ñÅ?ñE\—&Í'Z>à°QæÝ›/ΜhpC{ƒYŽ>¯:+í bŠWYKY9®Á _;<ª­·ÛõC5\G„u5w± —˜5±†3Ö$½çyÇ®-H›%“1Eí™%Žb@˜V&aÚ‰Âtqºì(C« `BDšv䜊òë%;Ïøê ;ênÐJ.ü½Õ…pUú¥ÇYËê©^—“MJ^€Ýõ"Þ¹¨þpŒÑêMô(8Ú [Mð×àSþw –.ªÕm¼@±c ‹v  Ð=Qä6OŽ¡5ø¥àœÒÖú0›C€+e<õ¾Š0|(]iœªß3•ÂUKu>e2Ÿh:¨3ƒH§­ÈÏqÁ/CJA¨.ç ô§ôØÖ“Ft²-ÓílÓ* ó¥Œ­Ó'^³¯%—e@Ô?©T_€xE&Alà.íß 9Ü<(¶aöÔ ¼¾í©vj€+i‡VŒMDh öFž7•mÐW´&6ïn…À‚C—i£bÒ°Dœz6:VVwü©òø“"†‘7æ»b »ñçs€%ÒŠ¬ ÜôÈ!T0ÔÃQä@[¹ÎWr缘p?‹³IíÇãÆwb>¼ãGÞ„hçèsíÍS±åpÛò mvÍÓÏKõwÞ êštßÒü‡1gZycEþÀOñ4¥>£-õ —îÌtÉéþ{í®†¾À[Cñ¯Ò×CÞî[ò>L–¼[™m‘‡1³ˆÓ¹ð•Šˆ‰ÔÏ¢Æ)…­ž<²Œ,¾pä: ƒ¢óéô| jÚô¾ÈQt:Zf9½4v`'ÃÃ,.{Ÿ(”¥n?‘ë÷’¬¾…H„ ‰ù“®¹&ÊäÁ˜}á‰ò$Rƒ¢E´g¬Åî9þåæüÇ»ÑÍèÓX)eaé÷ ÀF?¢œAþëÕåd²lHWÁbŸkÝ´¼ãèy·±ž{}´Ú=NŒAtßäÊÝ,Å)ŸyÒ©'ÿG@®Û9m„vK…:ŒdŒP0˜ÂÀ„gÐÏ8vj` (kì9À¨„£”;ÁãK÷Œ*””ÐdU$9eÄçÌ'›Hy.½,ù&ÕF³½Íjå¸Ô¿žSŽéâX2íz¿%îO,ßà Ê$9 léÕ!zJ` N…“„È?/:b;‰-ÒæœU°,³”JÔü%o3%G.÷IÚ*²N¨KK4¬ñ4«&ô<ÍiFÖ\æÌsµÉæê¸¡©Áï~Þ!ÿïܰ ]÷Åó¿Zz(ÿ«¹çÿÙûwÍÿ{1¼’3ƒõü6ò¿–)ù_1gl ÅX…ž§''Kúî"oRÓiaätÞï´Û‰iaTçzBézdkòOÂT¬Œr†< °zB5eÑ• Óþd(/¤‹g™ñš=yS))õ¬¥t·Õl·û9aöåå×…ézk¤¹ÿ¬ý ÐBü3cQSî ;ßga©$¨4”MÚc±žfû”'GG‡¿l\“Ü ~Ð&Ã{ú)@Ùr¤nŠ!QbDðI\^¿±7—WE2¿ÈȶÛrjJbæeu™1×d¾!½Ó r³p-\ŽÂ¥®šl%A4)M¬h:©¤'\¦9Ò¿ÄÀbHž(‚ßË\äÔ-Œ€Êûµ(”*¯Êæ‚+S_È5¹Z {ƒæ£ƒ†kJ±É†To^å+LÞôxG4K>¦{S±an7ê2ᢚuW>WP´ÃÇ´ÉÝz}±½¼ï&©ü6jÅm²\®SXle؆ ‰ŒV§+o3ß8›Í3ñ×,ʤ¯É|/Â\³;\5ÃÏÞSðözüœé³²a”íH¶ÿ×»­z=ÿÕîµ÷öÿ½ý×ìÿo/†Ÿ®&ÕóÁù—7?¼ý\…šÈ¹ÊMøžà ˜O«úfíT½'{¦VóöâCuði2ªB`ØÛ?×?~¶¥þ{Õ2ì`¡l ”f׃Ÿ«WÛ·¯è'ˆš[º ›ÓQ¨·qdÈr¼ʆU¢û 4†èA•á’§ÄÆÌÇ*צÆ™.Ž+\c&æ".„Ùk7Ú·5ÐU>±(»kå?µ“ÒUt –=E­è¼‚Ü¢‰¸E䩯×î'HUÐÎÉíò”ö@íi™6Ž&XšÙxq' ö©S1xá` „_…’€nÉüÒz]£×¨·º¹ltG–±ÖŽŽÞ¦þ[4,c:š`k&w"òMåàûïÁô€Ûžn±GR’ô˜vÆg1Ú§ X¥H[šõ~=ÂôA˜€ð˜¯Z¯ÀkPÆl( ¸ºú¥zq9|¸VÉöX½.†w U'ƒŸ¿{€´¢EH‘¿‘„ÏT†a'h ÊuÜð&ºßlä.‚p Utu©õÜ Ç“Ñ]DÕñ„ì1¯hÈ2u¶…—Ï4$9í13c#A¦-ÃJº­•h7H_´#\Q‰x¥æý}žù©«Ï¾àLá46\Üœp­Ï\§ˆ-¡ÐjõòÂSû“_¾Ÿ# 4¦Ýë·³„æ¿p’» goÐ5‘ßÓœ…ð¹«ÃEVÂúÁÙ¬aó°ïYœ¢Oàô&Šdö@ž£o¡¥*¼”M©Kº×b+Œ¼@Þ#SÀô°38o¥ÜÎf2 ý~½ky Û眢!p`drÆ|j0õ`3M3@cp‰1aøBã‚’³æP”HiŽEíÞr¦:o}¸uQöîÿ®v”ºlŽý!ñ¡V«i磋¡v3šhŸÆ—7?hã_®?Œà˜…j˜*x,ü2©4ed Ѧ¶݆‰“!)`ÊYhÀu‘ùÑm¶åðêçˆ6"•´”¦g›&õuÔ>}[W¶s[ìy-ÎWl@êÄ˨O·áÆÃU§l_¹Ð«Ë=¿OÙyKìÞr·™­÷—¬bƒ¦ÏØÛ/IçîêÄ Ê0ô¶=•õ>:rj"ÇëÆg{VƒéUUóÄ’;o;N4ú‚Ü3iHaë1"éë4üôÌ'L),“ Í)¡ÎÎʹn?®ÙÃápÀНí4RzÁË[Q ¶Rêö&ìÂwº|€ê)ús¬Ú)šrçŒÚhÿ•0 ž£Žûo»Ûmñ¿›õÞÞþ»·ÿî˜ýW@WüQ¿[‰°ß­®’(' ø}ûŠFY1ž¥ày·vÐ[íø]ô¦» =ÿòx)˜îv¿Ñ­—ÓÍeçNUß_’§ FR9̦vƒMH˜YöÚ{ð1·x4œ%8o…§“kÇ%ýdI²Xɳ_„8ž)5ºœ_ ûqt=äbÓÀ, 'Êá£ÃóÉ[KV–a5]ÇSm²Í§¤!î4Cü¤ý*)/ ¼Ü{DË>éao s±»?ÅD“)¶ýJîS•:'´SMÚì¯F@QݯÓ¡x–Åsú<íѰ,ò/ó‡O_Òˆ=í\©£¦}t\^hk k“<âV˜÷N@6P߉b÷Öæ=ÄrT3rÛ\m¼Þ:-ç£ ÎÌï ²!:ÑSjf½]úzCÖ‹à‡;X¹&DíQãžõoo]ž¸“’=n`ž^SÊ¿“4ˆä‡üøË‰¶$ƒ¬È‚ûq.kLŠ3”é2©úÅ&d¼ÈEHÑcAl!:÷# _ˆ·Qö“8Y¡áUéÝ€¸“Áݤ:¹ÜŒç“ËÑM¼ÄÁ‚â°ØñÒŽ‘EŒÆøÔ÷Tû–ñ°[; ˆn¤|HìÖî@bsSø+x9ÿoUlå»ÓðŸ{ÍFÿ¹ÓÜûÿöþ¿äÿ­Žn‡wØoþ8¹ $HΠ°:üùön8Ãïôu 9Î‡Š ½:º{Eg`pp·÷ †:íõs/£PF¢…²”˜T¡ bðÖîf†QÿAì\ì . |[â ¾Nûã•‚ôÜjµš}þlËÔ ¥…#ÁÞÄÛ¦ZL£ GÀhˆÐÊR0é'/¦3ÅTS:Êê7‚70o‘<´›ýu2µf}g®£æV$R2ƒ³ž¶ÃXÁpI ³A58¨ÑPsjPñ¹Á -€L¨B¹ç”ïa—{@;³ —uªEÈE1|äÓø5çëÏsw!dèF¯Uïtó¨î°%Qú{Æ•;é5³”is¦=âz3¿²ô¹²LXhbó̉šv¹È6Y¿é¡ÕߘKÞt_á‰À ÃfÌÄ®·öã-ri.RùÚ> õÔ L˜æ\Y/”Ö猪ºiÊÂ=^>_ÅrÇÁ²nôz­fN,kyÑÞ0¬›ŠlSf½vF’ G_2Ý€{ª»ÇÁ×ä‚7ËE¶2¹°øÝ¿ûký=œÙþúix÷‹F¡s´£QíÃàîdüéúˆ~þ_ÇÚÇ»Ñ5ü¢ýôãðn¨‘4,ƒ¦î.†wÚRy‡_*¡¡³öh•ã‘k%^È¿ð¿ŠTøCuüËø þýøéM†psÑÆ“»ÛÑøè >òæä ü/­±Fw£wÚj¤dÈåÍNm7úõ|yoE–ZßHO{ ckGÛpɈ_‹bj‡¯}ŸÆÃ»êðîŽ\üÞ'ìQ~aÓ-D³eæŽÓÃÎÍšxŽ«ä¡Õ%~ΨNÆn·ú/iõw+ÔíI}] %+‡yà}žƒH^2XÞ§^>”)V8Ç‹ öi£ÕÉñ ®ÿòd0ZìHÎQ6[F.ç:]wÀ3 ÏÞgñ ýŸñ‹àžÅn4­VÐþßkµ÷öÿ½ýÇìÿŒóûb0|Œ‡ß‚€&ÊðCRáÆÇ#„=j¿Mp¬õõÆ ùá'ŸÆ‰àÎ`^}Rµ‹Ÿ¾?$çïÑ/¢O_ÑÝm]Rwå4ý'ŽÐvÍQ£Q† °‰”è :hmãV)VýÓvçT>¶¥ZõcΓ¾ˆ°7GD4‡bˆ¥KJFÎGAd´F¼èÖkoƒ“¥ùú´ÝW|!¯l¾NèÇH[©ÿ¼ dËl{²ÁÐ@DJ æ7pÓ±{¢™5£Fæ8³† k ¹–hå|>@Èö:8ÈÆ/‡b½õ»p;Å´Iiá”±C-,ýŒ¦Z Æø iµmãJªeÉyúZ{#j|Ã^ªTÔ7&›aÃ/µÈ.¹²ÿOé½£O( O8Ó~ŽßTht¢3C¨5 oþ•ˆ0dz±FcS©sp~Nn¯Ô¨öY$be4Ýz³“Â0(©+ä&…pIºœú*È<ÃyϳG i¹ðøNI¹ŸÇÉBA*Ê£Í9ò ó+hø³,çQQ6" ”7 ™öD ø5¸h`Œ½œíjöâ€/Åq—óH ¤(¦€Ýnå:S#FŽÛ»Ñ‡aºjE0¼ È[Œ}±ër<"ijí©E”϶GæMïTŽ“ˆMi©?‘]è«óňÌÊ&³ž?êazåÆ;Ñ £ ¸D<,‰e³Sæ Ô}¤©Ì#ÊaëEÿJÖç³”p!cr„o“yN¦6XÓ$u 8a<‘¹œ¨„å@â§ ûª›ŸÅ™«3®šÑX÷¤Äu1µ1Uüé2$Wl L̵yÊÍ*üµJ€[{Ç Ò‰W袆hÅ(R CÖKu>k4šVvÀ ÜöÔ ÿ^ü¦-§ÇTW%;Rìÿõn³°ÿwÍúÞþ¿·ÿï˜ýÿòFN8«Þ~ €Ø:)çRû‘Œ¯Dzñ¶×±,8€aGWWçI°ÿëó¹¢]hê_õtH¡ìâBé^šˆXýq4úË+z"Æ|K·€Ú“ys"Fm@êè”áî/%ú‚ÃÎFfîÈ -°ŒÈ èñÁ@`Ø@JªÇ/*ܜȻœüËIhŸ¶ú^·´D`Wò;BNÁ E¶·OÛî¹¢ši¯VÓð…ÙsU±š¨äÕïð/ßÈNƒ°‰ü„,*à¾ÂäÒɽïöhÒâú²Í_}w¡e³þsÃÿVáñ|R¤t$£*Ý*¨ü´ÝO³ËË+:ˆ,x¾Ú3.GM‹Æ!!ùZ’Àñb;ùDÕ/À/A­#œNbæ¬eGQJE"8O;z»žËâÔ&ÜrsyU9 åÍK¿jñïN*GtQ Kª©Hœíi§Ù“AÔ™(Šr3ZÚ 9š7"ðV+£–N»Ó}1Æ R_W¡Yy¡HÔ—ÀsÈjóÀH¾^dfZH>9Çr'°×ŠDÃ>#ÌGñ˜ØÓn«]Oå=ÈyîyVÛ¨¶ËŒi׈¢ÆÑÐ -Á@Zè–‘ËVÊ—ÓXKî±»g8Eû_"éijÛÿZÍvÿ£Ûiíñ?öö¿]³ÿÅñŽüq @¶+I Þ–ÞëõL‚ Ó`[Ó`0KæÕCR†© ë`ÜîS¢•0nÄÐZø¢Ý’»9äyIY»§] 1­—fL¡*{.Ön³[ïwÚÏÃÅÚ=í7ÒÃ0)«CÅJt÷Ú‡©÷9I+"€”1°²à0ŸZÍÛL=²MP[ çY;ùf™ZÙŒ6ך~¯›¬J]2U{Í~'kÞáí·zõ^«›Ñr3†í†È …Kwí°&Îkqüw9XH%Ñu×F%ÛÅ=¹‚‚ò>Ó굎i¯±ïPƒò/#Д¢eQÜäò©&Ö®I#¿Æ lˆ³/`Nä¾i~C©nAÛŸ´©aآ凞yFªžàþ _.‰D³ˆõAÎ$ΣOA—e²\‚$[·L‡¨6`[Ðôõš¼CÞÙœ–䢿qÒ¸¢Z¥¿aœ'|óŃ`úWÛ ankÉÚK 0tÞ?'Út³&…óFŸHœÃT‹xÐi°w2aJx€tÄËðIâ³:ƒ–é­4´šÆÔý˜U¶Ä› â¢ÀÓx!×Fî‰f| Š*ÅARWËræá 8Òo` íÒX@5îÆ¶¹’d¯cdþ“³ñgAyî“x|ÉZ±Å0MBô Ç£W‚Ýœ;N)JßÉܲpM-Obšx¤™­Ùï¶OO›ÏK’L*é¶Z/g²&õõºý7Yï)ˆŸ•‚8•í5ZôüÝ•VvÏŸ¼ûüÉÝÓV¿{ÚÜó'¹ ÒÜAA—,Šûfi“Ó &;VRÀŽ’ËÿcúÙ…àñ8u½"ß•øo¸³<úKºÿ§Ûíñ_ÚÝÆÞÿ³÷ÿì˜ÿç§ËÉ\ô—y’ñnªj±rjY´—‡Ÿ®&»€ õ-}áïÆlƒø00Y(CãÜ Æ9@¾¥qÄäÇ ¤:â(ìÃ4ˆlX’»µã§×®w›½Vy‘àJgfC˜™O«¤é9H6S!ià‚š­Œj ÀáI.y©xõz·›Ñ±õ2ñê¡‹ ²ó™†,“[ž˜Ø*¹Oߩķožlç«aÏWíÄ‚ïq¿épiEc×ñŠ_+¡ Õ €ï#¼ ;ÜÒ郆‹àðäünZO çî¸{á§îùÄæCåÜ\^ñUvãLU¾ñÔ’×ÝRÿbðÍ@YdÏ8ܯœþÇW÷hš~*E ÐYŠÞ(nQÊà½DÛ]¨ å-€ vŠœõWàóÁÆÀã5­´Ú3ea\ÀK´úLŸ˜{ ^ƒ.6p£ä~ R‹:ìw ê|°âz8úG½¯æ5DÄ aÊ€C8„èÆ'ßW“ìå°Ž9û&Yϧ˜CZ7ß#)º{x)8PI[¯O]PD¯ÕÐ6*Écr­ßèøEîÌr<Š~CNñ†ŽL´i+DZÀ1iün®S§€ ^ )¡Þo÷Uüñt¼*Úcî§•œ儤ͧ€>u¶4–Žût1EÙÕʼnðø²ÑlÓìü#ñ22Kϧ߯"UÄ"™/À,ßÈ?adÛð|ï­ î\…¸¯ p’_r—Ä>m4ù=;Õ‚–‚ìÿ:˜SѦˆÑÍÍð<)çFn}?—ßu!_mZ¥¡^/Vo´¤1«¾z;] /2HÁ * LacËûÄ;g Àòá®È”=í÷šS…"/Æ/¡´“²læ¦]ARÊi€Êå"Sm”;à‹\{/ìü¿ÒyÓ'kyÿO»ÕªKþŸäÿo÷þŸ½ÿgùÙöìQ€±ú¸(R¬U̹À‘cÌl °¸÷Äp:qEÆx’Eað!µDø ûz<Á“ ºà¨žÍëŠÑmƒcG©,òààæS2‡pp¸(ƒ€è$…ë ë÷´ùìÊ!Û ÷ù=ó*à#òí+–+rgWX°‚çax L$”(+Xž8ëïOxàrêDÔ²2 So†ê"j‰{GDy!õa1S_ÈX¬ášÎÆ‹*7iŽÐg#'ÇÅ%äHžJmÉý”½ÍšÛü—Éîéi§[O¶KQ£Ö × ˜ð0ìàÆáç+’ „CÃë![(¾l± 0È¡“¹òÿA·%]q?Rõ R¿“5“»ä÷ðŽ1çnGå'øÒ„]>ø /ÓbŠŽ1îY„Î4D¢žçÊ"î• Y–ЬÝ5'Ð ÂxU£ÙŠ!Íš° 瀖Lì,)Î:ð’ãr,¼ÎÈÄù7J›€³Cõ2oÀ«¡àq|5làj»0r¾MëuÓóŽU ð†jÜGÝCP{ëkÔx™öÌz%ÚWæüµFɯÿ9GÉ&û’kÎÀ;(²,h¶¡²À¤A¢!:¾ZŒ3€U {^£›!c÷}œ—e,ur>Ÿy”Q¬¹.K ^è3â2Û‰@Î äA®˜Õמ Q’<ç¬õíçGÂüX’á$7Ù—Ÿêµ)À¨]ú„°à,mŽOMy K0—ŽÒ®1?‘såxž9µž4Ç62L eHóD–ô0÷ )“̦ ~þNó@Ån™'ùß”O®Ê¤/x‚…ñLÉmÂ!æí´G,»©m ¯˜bo-‰ì:—.7ïµjÙîëÓï>m¬ôü¯H‡ë‹åu=Ùÿ×Úóìý»éÿ{tÖ¿ýÃ%ͧŽT]ê¿W®aH§Œ€sñíÅŒqª^~®~¼%7Ãøm"axYm°ìÀ@Ta.¾}E¯`äÔØÒ'˜Þ×»Ã*;de¸ƒÅ—è :'XXÈ …Ù"!ìo,ù¦ :*| ˜aÄ|ŠœÛô‰W W[°/«9è% ˜O´`FHdÞˆpZ%C¹å*ÐìZ¾ö´”X}6ÅhæoRª`ùjlwdˆþ(rÒ…"ù„t ͸|†rØð>‹t›‚ò¤B16á.hªé[ºŠR'S|€OÁ\¿ñróXhâ)ND9 A®Šݾ§÷mȉ/²érÞ ²z…3‚ùlöó™ºf /½d¨nž“_êP”/nØ UO 4fˆ÷ÀM̃ ]ÚBm‡6ÙtLf~êHÖlßç ÓõÖÁ̜׮±ÔM[`«Ñ¼…xî_ ‰9™ô‚d±É4qää1Ž[Éšýf.@m-6.åv HÄ‘0Ác*¯ ßFè?:srvO˜Y“ô a稻®°suá@>8æŒiQI›Íô =j•€0yNËâ“— UÉäœ fŒ}+ªó‘ªë,±ìJÖª>ɰd-öçÛ’ÜßÀ¢ø²`trŠ3ñlQ‰HqÌ©.q…ü0´Z3VqQ®GÎE¤ÁÆ<7BÙ²ZÝSyËJOuâµFçñ_ƒyEþóø2ró²GÃ3—äûÿ 'C!cr°ìïþÃZOyæ¯!ÿ{†ÿë§ÞÿW»ßêw>v:ÿ G‰a›–v.U‹ì’ !$U…Dð9˜ä¸'?Ü Aÿc@¢nÿãE¬D…:F;3UÔ)žvFÞ,ÔQ½f7ÐQáEYN¹Gþ^”tR¨ò‚½^¶¹&a)•G­®l«1Â6ѧ YŽÈ–ûðô¼˜—ÿ>yZù`{§íV§Yß‘49yJEÅðB‚ÛyŸû€U^²t\·ßŠNÖ’Í/äÛR;Pü™èâoÁÿë8ó¹¥–0¢¥‘kb¢ˆù Ú ƒÓ¼—+ݾßè÷†v4]\\§0•_C”?˜F’³³}¿~ˆñ'w—7?T¯†7?L~|MpäT)NêêœÎß¼#R†?8bÈJI íWe&Œ†F=ÂãÍÊpñuJÓbY%_ ÿf&’‹‘È3…¿ ÑÌ5[*E[rzéA|^iØÙîþè,¾ÀÓénëW?íµ•¤Ú(î8tÊ`op÷ZV#8¶žy|³·©ÑkŸ¶ºõàHÎɆcZaŸÁŠÞ¤1˜Ý¾?|DÖ"mmÄÄ>:>ªÕjÇÇùÈNžÜÉcË‘ ÇJ²aÈõß.‡?ù–]Ó1G£;íæÓÕ•Æ<®hÜõ œ)thIéÎÌÔ×2 /KσçMôh¡w.“-l·ˆ/÷‚¢Wd¹Ðò.È7‚\ä¼Ú.]™ÕsÊ+^™#ã}3ÆKÜÿzíz'ÿÛmÔ÷üûûßÎÇÿ ‹×,8R0R™p¹€’“ ÕO0šøòærr9¸ºü_’ç »¼Sa¿bFlû·#ñ¾i£öA¿UzGx¾È_:tñá¿xî¤Á¿åÄþvºýÓnZì/éøGrŠVAŠx Y(2&ðpÛËK¶xâ|‘ÂÓŽùü‘ÂäTÑI»ÆÆæ’Ï,"[€©¿FÒr93:y#‚ƒ©˜F%»ïPB‰ˆ~ÅP_§G g(1Íž62"ö4ëÐ`pàƒþÕM5ÊíÕ Õ54QEVuµqWYùJxâva‰Ý¾b;É–HK‹pì¶èmL(!ýÖ/"nP‚ï­‹…SuOûý¤pªüDö½Ó^£)ǽ¼ 'q\?©Ç%ÿ´¤no±¡B&ÙX’Å–±U½v#–²5Øñ;šñ¶+áEŽe9c‚Gû]0ª$\ öÁYì?›™-FÕ5fD]yU`ô¨ Óèöf ”üïf¯ôÿ÷Úûüï½ýgçì?Ÿn‰zVï†ç£»‹qõãÝèºzy~•óá7 °Ìâ§¿Ömsµ±ô°ý:1`nXäd+TW(ÈîáÕt"ï7Þ› 6"E=QíÎ!µXelèÐŒ¯F“W´ ¥Ì–­ D }]Fh@â$ØÆx”8œeXŽ’¶³ HIã‹V¤O(‡äx¦¬¯à¦Ù³èGv/‚&Ý9í´ÚògKrѤ.ÌÆ5ʽýAÂO2ÒXJ£ÂœÓ8?‹°}’NëÕ›»Ãöî²2?p[Ã[x¯1^Aw¾·ÏÃêØŠÃ/ˆ&Ã%öþU…yXÅ¡üwßCÀ¯Å¡ Húûýzâ¨AŽj­ÊÄ–³â$‚„"Èwæÿñáà¦àÐhiáF8–6IÛ™;÷;Ø©¹™;§Ýv7…)ñ“‡öã™zhT‹€§1gd€Ò¨¥0…ô‘j‡H~0Ú!ÀoÁa¡Anð$'ÂøØý";ðõè¥1/æ1З9mõ1ã·A^²8ù†R2—# ´°ßQ(HšÅ…"È·¼ Ä<’û ô‘ØÜʰµ·§­f£[š­]î¬ÛzØ&¢>›Í>îÞÆZ±’“æv2\Ýk[É#ša9ð 17lgÍŒžê\H3_gíÌPݰF¯LoÅEÀÀÑéSÙx³ŽŒS^1?ssæ<ªÁ¹MËíf½¡„ëF˜–åÅ(·±o¼pb Q"> D…±Æød/¬„¼Ó¡¦].´,ÖŨ•4w j“õ;WGm⸠+V–4¹—‰|‚Æ"ÓCº$fètòÿûù ’2ÑÞXæƒ[ª@y^]þeX ~$Q94£ŒS9(¡Ðn¯ÓL6A)íB]¨Ú„’ÍPšpªÄ”¿ŒÉ‰ rèv˜@üTÀ(ƒ4B¿Ãð"O}ßoï†ã1¥…M`"E”!ÓÁó}êÎ+@>«P»Ùhõëý4«P©zþç3¨Ö¡‡z i³ìµõ¤‘2¸~¹Í{N0ËÆËtî,—Ž•ÓÐßÈo0we5ç)„³%ÌíèAÓí'1T¡y3ÎhpÉ÷ŽnYy_±%lÆW6¶<ó2¾„ ‚žì÷ÊøâÒ´7^Þ— Ôˆšo™ï}œU²a.ÁÞXVá—ß~óÿWøÍw…߬~¶òÂ/+‘¹Ç·ð«¦]øUo3%7³âsêÿý‹¿û§Âo2qñ—ï·|y;¹·{{+ágÎÆ^~{©ÿ^üÝ-¦¨þõ~‹é½,ü® 2)\ÂÔX?’ûBñæˆ.3Ûb×°¿ZÅ_ö ô†ý5I†Œ9˜†eñ\Ì•glæŽßJ0ž&«\Wï1ÛØ?¨‰ãRØ2 Ù9Tù\lp'\Fž“âàöRmͳ gŽM¤Ør;îÝb^š[Lø{×Ù¬ªÓ§Â³]\ãÃku«ƒe;(¾àV[`Ìâ5ÿ©øÎ¦XÕòïjºex³-JðÃ,ó¨)®V$ÛÉšMÖ7Í jEÓ€ùÊ7s‘ó<¤TK1­Ðw®ÇêSå*¥#Ï ‘žÑR¾aÏÍ€KkÀ¾ý×?µýS}`˜¤Nþ\ÛñŽÌÐÓŽwž¨8ÕYT4`Cö –±‘îCÊMH,ì;;˜‘ÝUùeœRü¯çÁýÊÿÑ +(ÿÑn·öñûø‹ÿP’Ëÿx¨_\K@[YPÞʘ²;yÝ ®‡,‚ívxžïœÎôzÑÁß6i3© w†Ì70 ¥€y=ˆ—2>òƒÁhv­ s›œ+"äX¬æLÛ&¤Õ«7•”«-cA"ñˆ’Ó%yä ¡Åç!íí(aѯ ’1pœ'ša"](ÃNÊÜ‹dXŸæwg–ãI,<á¯xŠ2|­å q¡í‹í<ÚaܸmbCZ½†Jb"úHáKôr¶ˆŒÍNΜ­íI+‹Ð&ž6/šŒ6ñH-:œ9Êk*ÕŠ„wÞi7ädÈÜ£´œ‡ µtGZ¼G±JÈU£Ÿ5àã'Èæ¥ i>׫IÁéëú ÛçÌä[Ùš¥ …"uOc;^JV6û°zÚÜ*Ä—b¢$úy ¢íÇËY*¶j¥€¼õãk±s&Gþ¬õõ&Ðúñd0ùß`úJéô–d14»­nzÈOŽópÖ?—3gÇ“ÑòÝv†æ/Ã(_Zô-y þÊÞCçýaðÿŠõÿ2æÿõ:íþ_«ÑØÛ÷öß]³ÿ^?áö»Ûvß‚>Òx»¯¹¬zÎì‹8 ÞÒŸ1 N°õ:óiÀ^<ºøpþŠö]>¢[Úucº(§E7mŒ¶1êú=_ÀœËOÅ1[þ8UØwŽ?³ Ý=#wÄõƒ8\ã¦CÕlàHÈQ r43É„Ÿ—ô½v§{Êqί̩«»&è[QµÓd®øÃ:žÂ ƒ ª†se|ù\«Ì,@`$fêI;Ro¦e€ºP¤)ö}¼s¼Y×* ®åв>/|ôóÂ*@> R†Å“¹\µ}^]é뇷‚ ‚a1c”W9X;ZŒœï6žûŽÔý.N`"ï`>g ^[Xú=£Å÷˜5¶À°¸…ãV@Ù yÓ5¤öei~ѺÊÚ¼8¼£Ãª5;<àmIË’æm·Õì2#÷öüC÷Y¢&oå€ìãä‹´rêÞ|qF£L í þ…c73 ú‰Á÷0“"J:Ê3½…¥Y£ì* « OÚÅ7*b™^tçSò€íûn›cýKŽ·1l³ÄQÓÊ$L;Q˜^ƒÛÛ©¿ úLˆ…wj"M;rND9¥Ž’]Lާb°¥xNs< ¸9k,¸6ÂÀ¢·ò¦à¸J[b¹/K«žO:#ùEr Ø‹øÑ‚#áUÓøY…‡Ö,¼ êŸCÆ_åà@Ë£È, —RºGζžæØ”r(jñÛ&_ù´G#f(•FÂægPµ­ðI§»ƒvÅBÁg#ÍýÁJ¤æþ¥µ³•¤Á”CVx• L©fènJÕ7@ª³fC•e(x H¬JJ`é‰Ú'ÛüÖsy±U3£~ž¦ÚäVë>­ÀÝÄ‹ª •µ¼H«Í…XõmŽÏ É™àXZ®ÖO¢b|‘·ë’€*Ëј,ô™³\nl.?Š=™MÛ$7ñsí¼@cÍ·ÜôþBÛl¿[ç0Ú™AA›kc ì+Lo¬Èø­þ¨âgtœA@¶=3]r[ú^;„;´ïñÖPDü«ôµÃfrŒ_ÇuVÕ3ÃÅÝè¶zys1ü9Þ¯#^•|-J•âò£s¼^©©ÄÁœO­J*XòFåàJã! >]™ô:––YvŸeCŽƒA†ß|dg¯ud‹¦—wËšölmÝvÅP -NŸ1÷¹:(:‹’É×âg,®â䘹7|¸Š÷³Ê¯ÇÍA°Â¹Žå‘˪A}í.&8€BãxÉkÎ5G{iÛÎÅ¥fl¢ŒâtŒÈmPê„Ú+ ‚óhÃnÛûØ@PVï/O……}ŽqÃcÄQ¨ø“"Ô)úƼ·W‚/Qûnc=·>%·Þ:WÂ×ߦ¾uM|Ìήµk“¬'cGÃ1l2dÆ< C¦ß`Èù)c–EB8ׇWIÎ|úŠ´Øj¯4:õz›‡E¢ }‹[tÁy€·«¸ìw6VA¥·$›Ù9,¸´Ä´Ë¨ÂPÖÐçϸ —ß-4 4ª5™:C$‘Š@Žîµœl@#šŒ‘ð… á/yÆZijÞ«wÆ‘¯dë¸ÅAЦ{î$:–{¾n™/Eáyò­ìçkÝ p0B–›ñåoý4š ÇYcS aͦ%w-J'³7«H|Žêž,!8'Ù³•+,'äÊÜ€œøY®Sqå/«CóÿD|Suå80qKI‰ÿ€_ùV«³ÿØÇìZþŸŽ«ÞŽFWË?^`¶d½èèÌÖ¯˜ï1ÂÛæüƒGw$Í/b4JÉô î%efûG3þ0áÁC¸ Z£oÈð]l^ÈÏ­^¯[?̓üœÏ:‰Ÿ¥žÌ(ÆÒðÃnjž_±$¿^¿ÛLNèB.g^5CK'ô3¬^yŸ¼{YF?b…á«\.41P—>blWcª¹¹¼â×Óp'Qƒ¥ï(F¹y¬Éºå ôÒùjÌóåøô›mÄñ d‰uêÆŸx^Ã|-C9KØfÑ¿…Y„VîexÚêuRíþrìž1Ÿ¬ð=mµä\G%½+ïö]~f—ØŸü ¯ÝÌìJ=åîJ2WÆso¾|.1w«J¾Kí³¸öÿeÇÿ‚›×‹ãµ[ÍŽdÿk!þWcoÿÛÛÿvÿ Òvÿp¶¿Bø ¸_Û‰½2"›[Zc;ugÐÀSöË„£9CåCƒÁ@)Ð`8Ô‚„År5ãúISzI®Qê(2 ÜMÛ¢Ó"%‚¢Z(a2/M œkx0“†l˜Kr3IÝ:Ð1»!˜FUë¼4²’®¥WrcQzx:`˜æÑÝ,y€af%Jß´yeI‹;”3…±UcúÈ™€\Œ_M=A²( '4-g ÇEa3ö—œ¦µ™ïÃ"#â>Ù§ÁýÄõÉÛÁ}ŠX|†ƒ‘Ü´gÖfŽu±ä(¬‹ÍjÌÙ:Q_?Á,Lza!dtöñ]ƒöšdœ [fÙpa{‹Ÿ÷³”˜w"©C¯0ÒëS¯}71äëÆÅr¼ù×M­¦icO¯Ë²K{ä:ž3Y?žêÀ¬:tmïÝGöWîV€wMJÕæç–kÈÄ–¿¡³¥Öj758^ÚÝž}]fO¦^Û5–½YäˆùôáÃy”æTqµFmAIÄ]žµËï´ÙÀP¼[ µÇe= _ã]/xv™Ñë¾X§v­}Œ~"¿Óø1+ð5)Ôð¨«q–}è-ÍéT-®|Tx±‡Úåí×§³?…6 öWYòxH Ž8&PåäzF ¾_ÙÓ$† àãÁš.,טúuJ"¤y|Œ¸u½ñØ(s#ˆÅ_‘­£&â&éoÈr;o7Ê­0‡bµa¤’!?!Fý £©UÕ@w³šv¢á­`ßû"ü aÇÆïÝð=™öÞ5ªFšÒªÈ!ÞœmsZøü–=ƒ¿Uè8GÑ‘¤¤5ùPkxµ¦v—p'²p5˜¬roù¹ÉÃqº–à÷)>eÜXSQ¤9å XˆÄ)~Tˆ}Ø úÑy{0¤XÇÚ-HàXŽ÷ÌšZ˵ÛC¤@ÉAü}åå;¿01Àµæšºö¦žW”T‡ŒË^ä!øVQÝÙ*˜#ó(ývÍHõ–’ 0Ò[Á™R‘ȧӒœ¼0Mq#©Ëö¤B¦B~+°UÎ?Tú?Ÿßoßfõ‹S3(>]TòÈP'Wv„†Ó,Ñ,ÕBLßQêvefþQ™¸–UQBr?ÎÞÌLå²÷såÃM¿_á :\ec -ˆÎ£1CèìF‹üõœÕtŒ§%ì ûٲLj”cêè}ºJ_ÿÛ\ ›· [gHòåPJû&ŽÜ úפ™ö%£¸Á¶¨½£ÄÑráœ_Ï{çÿG ª Ês,› ŒýæÒCéQÆZ@kQî3#a >“ ü5 Üôsªë— ’™XVnžÕ eŸ ØuÁÅÊœef¤4=9mmúB¡C±A6ù¹™Š0r\4±9L]aÙ 2m'6{dÍ™Pć¶÷rÏ„<¿ƒ3QÀ B†Zj7ëÞÃðU• Ÿ‡kÒ¤FÂàå¡0Œ­±QÀ¬‹ŒDb|û…3bb,t–=¸eØË7Wcx¶ÇZgEäùæ•bkUÖ£rÚÙPˆ^¬Z£®Ñ›~Þ%zcUàZlÞ¸}àIuÊF¿³–¥¨ÙŽª¼½„{×ÙûËÛbÌVãcß±ÀØÌd_ƒÀZÂA ú댳˜wÎj©$?úÇR±óU­¬_^ð"÷ –‡p ’=¯ê…Þˆ§ QgýÛáÍà—üTñö¼uéZ¸Î]ˆU×7ƒ÷8…F®%tÛÀ ¦.Ô QHþÞ ¢rw¦: iz²-¸+,G"ϱʧ˜8,¹`ÂM£múbkm0Avÿt>ü˜ŸÛý?¬ÑŠ&Æ“±*wc¸g"·¾\aíÐù@"²×9kÙ€¢¯@l`{E)Œ.6Êã’1%"†_]ÓjâÚ€8fΫtЬ˜±¦½„AÝW˜ Ãÿô®ûWX˧‚‰o êÎú7•Û_®†½Ÿ³kcSçŽ^YG†÷û ݽw®‰íëÓà}U‚‡ÊPYcà]=à ¨êáô©’2ƒÓÞÅÅ/•µ§å‚õ÷|³"”6;bDëÏ’ÒóM\†–Ž1– ª.–Ô¹n‡ƒ›ˆ‘TP§É.ªdôÊ ë6q@” %þØÎŠê\E²´n!}¦-e=~8‡)[{1îîôÙ2¤#3i”¢Ððxå*²-i]k°¾»†l¶ ?Eà_wEê/ e~q&„yö[`õFL“E‰«øøtVú?_Ãj»=\å'Ù4û-èÖ'[ƒzY_F!~pÝ¿é Ë¥Ýô©%HÉ*mŽÁà&§Á…—¤¡Ã\®hI7Köµ¦1§R‡%B"™Sƒ¼xgÖ„n¸JaÎïWæ½eìcù¹ƒµõŠp‘ÀwjuÀìs¼)±"?U,~©’D3ótm”DÝBè}í BôÜæ^T¦4‘ê´\óô.wñTœ>"{—*×Ùíøò‡K=æ"·'ùjÃrúbûñ¼ÿÓk,¾Ôzh¥å¢šW1´Ð¨–©ºÎšR–k¹eøjp‘!]ϵƊó/15=–¯1*¸»Æ"cM_e*I~àÂm rhÑûºD#‚Êi¢õ‚æ\x9¸Üˆ¸çZok0Ó\²DÍâÜoÎßæ´3«Š‡ð‹hZ‡ìl‰× Ö€Nvþ…6ìRÉvÑ!s¦2Ö¯{ËF£p[ˆç~£ ‘ˆ¶ÂVøZɳ~_áÊÓ…Òmÿß>õ¯N×Q´dÃÅES€6’N¹) ¨õèb©>¼ mŽa¥È)¿‡b7þzPX ŸK^­Ç[I5<¶ R|Ñ»rüC[†Å‚ªf°|j1ß:HíUÿça7ìEVÂf‘TåòÕ_²è×V¯Ò}å"dÙy®+õ-f±³’;¬ÕRé†Ë:•,Úð‡7Ÿ®N 9Θ,@tLºÚ2ÝóP¨tÙ—[O_-ë_¦gò2ýcø.}iÎíÅŠj·éË2nÓæè_¦+¼R¸ðÈè¿ÞéG~¹®Àj¸9ïß 7Iö¨¥[îÈà˜­<ôêÎz0Ñªè’ø@ZÐÈåL„K?† fáŠ-<°<£¥‹ñxèÆ–t‹ã· ºí¹g¹Ë :Þݱ'UÊÛþͰ‚Þ÷›³ÛbÛ2–+D–§ +¯VÎ5yµãnÔ‰ýt}†[1/±Ÿ¨-Ï—xD1+ÈeÑGAÇöÔ ÑyÖ¿è “£-A0–ÁM‹ù+˜âlÊèn¸èœ¢¢{:¸¼ì]å÷L2Ë&o”£ $å¹Ãy]ŒbÜX" ·Ò/E©£†HغþAÍ×-iµ\4WnÐQQ ¾¾9¿Vò‘Ma!S¸A6cÊ(¡ãÂJeCp-$\a%mê‡ÚÜÂòÌgÊ´1JXP]0hÀ[ºˆEQt9Ï9Ùw¾D;4è2X(}1ß  Ù,­¸us*( .,)®ˆL~³²qÝË²ãø®çÏ«<7¡•mœà~ Jñ?3ÌCw\ßUx(¢0¹Zö ýŨ£´ÊEþ»ïüyã³j¾+<}Jwòâû1!ßøiwxz1¸eY tåsÁ2zˆ7ë )éèO ôy™>~oW&n}ZÉöÏY¡Zþ‰²¼!ß‚¥¤[5õ†x" Ñ™/Dã¤hŒáäh–GŸxªaØßHI¬Å³ÃüN³‹ãçq¡á¸H%/IC8.<‘dÄÓìדÜØ”|hKÑ÷6¯Q·‡ K"·‹ºë‘Êr<‘2šAÂ)çV:vbÝRN3Èïb©´Ð…=[ÍŒùjvÇ2µyç†#ã]pÚ¡Û$æ¿;ö¼¨yâÚò&.¢æŽ})ħhÏûpÓ¿ý˜#G ±IIID©Tj`lõðnÖ2;*4GØ "qù c¤kaø"ÛËwO/t2q{À:ùº™ ~ÁµH«2;ërÚ˜}c-8höFycੵSgE>O­½ s[ÇuÒ±fÀ-•f/™èÛõøM= (—ñr—Ñ0"]r«ÑPŠ9(žsƒØz*§[U)× G®«Dç¥Yˆc¢½<¢ÅƒÒ<Àjq®üeLϽʱAar¥Dæäç×kýcüG bFzþíÀ¸ß–dld9zÌÜÈ2p"AwÈ~[ÄV Ù¢êÕ!DËõ\KŒ®‰¤Cl ì,ž^•T?šE¥3w,‹0äÅJ°¢w–ÆÅi‡[®eβáÝï] »ss<¨Ö*+U8!ÊŸ…ùh mv‚poˆ2[8s2û:‘còž}P\Y ‹«i…æhæ|±´ÑÉR©/?>§&G§GªÉÁå¼³²t~>:YO´¼Á‚Û*lÓùÏUƒUÈ8_·O ÎÎÖ–óh;¶æãÊ£éÎQ Éû¿k¡ÉºuVù©ws…é}ÿcïÇóÁMë¢2äóþ¸þ±š-wú„<],a¶í@VÕéàê,_Ø2 ñl7 6»€y³"`bxãþÔÏŠÃR†jBÜÍMŽt¬W9‘]|Ô|=)ãæ+vóG.¶Bá±K–0$K^n|bÅ®‰8 ¸ÁØ0*ƒ{TƲ<`ñÝõžCàÓmÿ&ç.ÛÐ7Gà¸ÙA6Â(\"6Ö°·ÇœéÏóOIÃûD¥¨«ëOqppr‚Ë 7A2£—ãJÙįXŒWQ|&.¤EÉóàx|<Âg‘/d×A˜Ò扟ü%ç8ÄÆ Ö¦%/.(aMçõiETÎúpu8.,Šìàz iØ¿¼Üôn~Ys<†ìBÝÕÑÖøx¸^²ÆHì™å¬–áqœ_öŸ†¥®.òÆ«èbRl,åTÆØ>Ó?Àºº(g¦A]ø“a§"f»äÓkõ ¸Ÿ±0|°~ø”:ûÙ~½)œ5wÖN¢)ë„”ö«´cðÃ'«î Úgò¶Q¼’å©{Ùç"¬dûõöÉ?4WÉmEöÅ÷G_z…Ñ®µÆ¿Á[°õàò°xé#¿H òœ'ÅÉc‡9aãµb²ÞºˆNež¯ …Þæ7T¦·Õ©u—ÿ¢0Â}d³Ç¼øº +XC-všæ0Ül§Õ,s“†:è¶[¸0Ö+g|'Šg½?-q*eGŒþvI±â3l°Ñl`é‰5'2ÔêQ£Ôy ¶ßªwŽcÅlîÆÚM,ï‰5ú˜X.gåafZ½2ˆM»Öª¯µ×Ã-¶Z%ìõp³ÝV­Lêà¨Vot×ßë Al‰£–Xn ‹¶ðª×Fc݉Uºãi××ÚûMvhÖœÚp»ÝZ³Ù)qn#z8jwJ›ÜfÞÙm–3»MeD ­yHG´Y¯•±u£n•»y#º€ÕÞ.A­r¨(¥¨šÃëY=ý¶8‘­n½³–¦n²ÝPš|2~dK®”–:eœõ¡v;µn§Uæiêአj[üªjJ/ZìÚÞ»øŸqÍG7ž›_&ŽÃ аò«ÚË·ôrò­ørò‘…âµrò㸖Ö.'ŸB$F2Ñ_KgQ&ÅÁveiÒP{>=˜A‚Õ¡aïþeûóZ?Èÿo3ï£VÚŸ-ü·~Ô®©ÿâ¯M¸ƒüK½:` Ôû:<×€ÿkþ‹Q{ ¬0xË0þå3VÉNx.íû¯ôçý¿̦BW)X­íÖ|ä`ÈÆ÷{Ÿ†*],r޹PSgn$röþßw»ÿëÿ:œ"—KøþôþâüÔØ«|ûíOÍÓo¿=ž?^^Ð KðµÖÉ·ßö¯öŒ½‡årqòí·ÕÇfÕqï¿Þ|û¶UÇ—ù¯,w¿Y/Ç(º±? y"=Ü Ö&g/㣰†ßý¯™µ„cž¬`•Ö/ßïñZÌ•áÓÂÚCƒ=þ‚ d)‰£ï0=Ðõ¬å÷|øxT )=z6{Žõ‰UCàè²æ ‹Uéê̽ÇðóŸo/Œ[,ï=Xˆ£óc½zÔ­Ö©Ç©=ÿl¸ÖFé̬=Õ3À„¿A}ÁpÈD1íÞ㇕=¶ï¯{1Àð¢‰lø@; ½— 3]4 Êh”öò‹.Rñ¿©«oÙZ`‡Ž®Š0ÿâ„G½»Y¯ã=žÆTŠ©#‚]Ë/K1w]tá×XLc¦€¿øk)Ç †ªRÄüž¯ž ÙÇÒ`†11–ž@ß&Ü‹/¦â N¥j.F5êGxiŸYÞȵìöÃÚR¨­3—!:ˆá2†ã˜_ÁCíĨUÛöü;ƒFG‰øenS“Ó{ï~bmeM¢l§Üˆº¥K£cUWË`ôcD–€¿É„¨šâØŸ`uZs.âÇXeq@L,t† ð!‚ÎŽ {¢¾Ïx Ô=8¢ØŠÁ<§H(wd@îdB™ ëà% ÓRjfˆ-2cǘ;èp_©°ï0vÚÀO>{†½DêÅàõqÏÌ'` TðñB‡6•Z`Ïw°ÿæŽô¡²¥ILÚXÄA%³.ªàN»}¶Àr"ô¬é‰‚ž ÃF±gSÎh|³ÐCr¢8ÇV°Öµ3¯÷а¾I•Å_RStËÃ$ñ ¼­P[ÂŒK Abd.ä ½jœOŒ'gå?Žü󨬯x<úLX[±~sÄ6¬Š~1B?ñ`,mvÓ¿¾¨Ân#¹øîÖ²bhÏPðEПX÷%v ‰¨ã t X[SÚSXïUU²JÇfSÓ¨z$)Ó¶¸òÑl7º5õÜY Žzk/W¢ä|@öR?F‘s¶Ùé4ZŠ„‡ÉëM=‡õ°äÅØ\àâ÷{5å¾sKûŠà÷öä9HŸÑGâ¾ò.z!d[¹§?Ã̇ ¡ï6p›e%²ô›ð»e¿LâËUn×Öj³’½12,Örž¾ç1@‘1Ü)CYBˆßõ}ÝDê$wOBÑÓ…Ï⯜–œÕ`ƒñM3¼Fjƒ½G'•¹ô©ZïVk{²¥1¡àŒ*é ¯ç†kr…М+Š× WðA•e'Jté¬âÌ‹ï>-ü•\Ìݵ†ù(—#,VfaÈC„µöÝGgfeãFЕ–¡Âaq'ùÂ¥Jõ1¤ùÚ–îÿ©·ÚõÆÖÿ³õÿl˜ÿ'P~dó=~ý>©´d®à—àý‰,#IÔëÇ$yz"*©HeV+¨òŠ>œàœ¯é°‰®¹“ÏM“§ ãž›¨:7%¸i´Ã¦DŸŒ6Q)u¸E0²ˆÃ¥Ýìvíò.[„ª`r¹ÖbjŽ,ä5¿[¼›Óèùtiã_ÍÙâ;˜Å”÷ìIeìX^eî,Yy ­‘äw3µWžÃ ü=n«Æéx'Ò”¨0Ï­ãiܘ3v¦ ]f'Ç1;”¨Ü­ü¾%k¥ñÉeW {z(ʸ:n ­âPnã"¤GÍY:ù=ãpl<æmá7B4!ÞÐi\{ïÞ ˜BÑÚ[Þuµ´ñ%®ç,e´VKËDÓìd5€_èGŠÖ ÈPǵxëa2£_"3²¸³î+Ž”ƒØéN iŒÙ8ÇGiNVT[”xÏ‚knž-@·t!Õr®¿ØÅ”s¡¡]®t`¤ \$1 ¯ ßa% 1ó,<‰÷¬7Qª%P‚Ðî@t]_ˆÓáÝ(Læ*,y—(çÓž8oÚK_ÍœÀíV­I‰1Nàì~¨¬ñëÄq~;ØeGÐpw_c,ûÖ8 Óà³&^LmØðËæ;ÍZµv½ÖÊèjíùËÍq0¢Â)‘M,ç>«F¡™étU7E„ëc·˜Ô/DLW‹Éè3éÍ ì‡ˆ³I˜È"(F†s[vŒç>Ü1“9! ›:ñ~[ykþfé ÃLÍ$ EòËR…Éc\_RÔÍÚ‹»±r]sãìýFЏ²_“c]€€Øzž>!e=Šh° oT»ˆå‹öFå¹SœF¹n'K‹r²oŽ'£ñ¨¨ïÆ·–á¹Éh>Êå¦ ÝMpÎ ?méNäÿыɕÞG²ÿ§Ñ©µÛÿO³Ó>Úú¶þŸ óÿ(E¿ßÏ,Å÷“Tq:Áû*¼é ®Ü=‘ e RDÈWôú¨3½¦Ç'\§t=oOrðâþžèúœ%8|äéR¢³GÎÏ¥LKpu:Ý®–ÇêŠQt%²y~X!ZÂÞ%€Üœ‰næWˆ°Šoâ(âsŠ´'¿ÂÂi^.w{±ˆÓ©Ó9n´Ž;ãtJšçdžb7$XfŽŒ%šb<s{*Ì2ëx`¢U$}rŽ-2kÁqðåìÅXšŸ©6b-cnŸ0æ_К¶™Çúœq»«±É{ùû”u [ƒb5›ï|;tÅ9¥¢6¼2 55ƒugWØ[²¶uq¶&m¼(öÎóÖ"tÙ|\ (xJcJ¯ Åò7$VªÇë¼k¯1>3¿fRü±`6å¥#ŠÀ›Æþzµï0kr¶X>h °} k|Y}wh/à‘ËÇYiÒe¾Ó8ÖÐcÕÊZ~%H–]Ã’sxÞ¯šA‹Ow’׃¶+ãDt§kN†‚›ŽYOq̤Gt“;·Ù 9¨ðT+hggp·UøÌ¥»PhI;‰=ïÕ³^d¬ˆf^ÍPax¥ <\¾åôžg=+CÓvžì/ITD\Ìà¡ä‡Q§N‡äVõ¡ôù´ŠÃŽXPóöfuŽFF˜ãöðhöWJgH7ãü)ìˆïÕë„V˜àˆ÷½Uh„s$ÿùçðb ¬àÀ¨\óåI\¾ð”ƒÃø~ŽOÏÓ×T‘]ô`¶3Ÿ|¦–RÐnÆ9ã D(¬ *F©Ø†5?U^>³¼ˆ‘‰e uZF•^:öS1Ù°\½Qãò'¼Ì!‚ê2e§2¥f*;lWÛÄE§ô-Ѐþ}ùàϯŲ8…’æ÷ä—#0 ïs¹tí»–›ãòB#€vKx³ðƒÂç‹ê™÷ÝUÎ_Ê“§ë§“umè©ç¾TàÁ-kI`X)w¼HKônÂ/™‹PÝL‚¤vÜYA—Kè¥5† hE©ÿ“#=Ì\ðœë@†0&g±÷™=Wd%<(– vJ±*VY¥YÌHÃí;ºˆd/R‰×5ŸBÛ zìºwkµ¸wMVÏÐWÁ˜b®vý\a9sd³ILbM„F çÕÜg×~ÜUS(œ…¸1çbå}Ç ”‡~ …<@‡yü-¢äfÒÉÅKÉ1ªP¦ÇcJ<Ð¥",dŒ°ÀÛbÊg–I•ù¬Qž?Áo¿Xp:Ãgas›8è‰íÊQ'r ÿÈaö~Y¹6Ð'€Sva9s{¬ò?ý+×=hd>kØ"y¶??˜öTc¾ve¶—¦Ê5üôÇ)è‘3Û•,Í(_0žâÓqÀ.ẑQØB†xÇ6KçžÖÜlå )ê°¸šˆËêú¦2ŠV§²Ë÷sûï yR^¡S/þj¬{Ž6×oô•ú)8™ëðTÀþ=8«é8ÀÕÝ5MâbË6â|5»³„¡-qì˼Ãtë°ÿ.ÍÑŠÅ•Œ‡*ô·T³¦èŽÆ͹‘Ž­îKÇïíåÈŒÎäT"ú:T’»¯èq:Û2ªÓë›ó«aJ¿ÊË…Pž’©â!›œb¡óxœ#Å/ú§I±êSòF® Þ9ju±ÈDÃìVBÝ óÙzz„µ.­~ÚÚ󅉇a(Z{k;Â*äyšlâ}¡ha‡Š´8PIÛ™6å`ÞFÃeˆ…+¼>+/x=s,\®èuÜвj¹­Óñg®ÿ1Â{N…æ¨;ÂUFF@rü …@üÿüß6þÿ¿añÿoO{§û•!Á°¡NxÞ¿­œõ?ô>] ßþ©sJo\MˆO.„§åsÒVÉšùeg3“ b§¬Œ„‚„ãªÄƒÄi¤´ƒ[Í6 ¶wÖ,gå²2@+Úâ¤Q†¡0—¬Ä¢ú‘ÇŠHCÀ$,oè_¬(PÝRB[ÕAÿ¶$|¡I3T#›“Ï’e(&><_¼­C?¡jU 8`â=ݪ™"Úë>­¦»åcÜè“éÊ{Ðo}ù»ãã¶nŸáeY˜’»X®þ:5*º˜iè_Uã—­ý%¼lý«E€y±hIkÏ\—:M@1¦ñÞåŒÖ /kuW¤Å÷ů꡵n½{܈ÇÂÉmk¯uµÆQ#Â~ÿþi6ë5—ÿ…`8ŠÿïrÏÚZ¦-`M«Õ3m½9™4eb#¬1¹”‰\™<êÐXn"úº†ºÿ{¿OŸ'ó?þs½ÖÞÿmøh{ÿßÞÿ7ëþOn?K‰ÏÒ*aÄ_ìõôÀW Úéÿ|}Ó¿½Eà¢×»Î³I_óÒž™¯_«3j:ʸ¯C»%ÞËq¬xû>Å«ƒ»-y®)¢æ±s"ú×W ìs³Ñª« •kÂ>oX =–²É–üw”|ùðú¼ªÈÙhµkªçö•óâƒ,ˆÉ…gÙRê (œ'ÃènÙ2”¹Ð”Æ0¢D®‘WØlÀ\t’ó ox®™¾5øA%°DYt•äN†P™ ß«”¥´A&:µ§&Ë"“iŸ.ƒùæ#xpNë¹÷ÀZ„ó…E2³—~å&(Œ,P ´Ë£Z¾°{ܦs{*" ÷®>]\ìí²ÏßÀ%L~ña0ŸïÝ™.F òoÞÀŸoöv öe½&_©×dKûÔ Í±wñ!ùÔ>vyÍRC‡ðx후×BoíùõEée?’‘r…§dðêù÷ß~3Þ 9ϯßÓ3ÀFöþ"ÂZßà„Ò·°]à•BßmI‹01Œ÷½ãÃÍàÒxßû?ÆÇÞX u¾¨žŸßÇ7ðËÑ»:ç«?ö. ÖÖ^¡§v«s”Rà4w ¿F»S«w²ãRã…–èQ³“¹N`8t.:ødØÊÕ,ÃêÖ§[PÚú77ƒ›ø` ­ ÅrâÝhX»æüÉOíœç’-zH£ÀЇsÝq 5‚šöMÄ{(yY8âtˆòfŠòÇAˆ ÆÃ5xˆ;êï¦Mõ9ù”Ò}dòx ïBõCíËXÐrèÙI‘Ù•#ò pxüD’0¸îßô†iÈÖ" jí³þSV¾x½”2}N§öZ Ýd6¤š\Ö N>bÒåwŒ†úßzmBö_¸F“.3 ʵ§Ù[µzÀþ ÿ4·öß­ýwÃì¿Ã›OW§@}ÖöÞ÷nÿÌ5 CÐ'Ä–Dö:f⨵±¦Ñ8ÅY10àø-Ár:˜J´#‡&L©ˆà=H©wh|±­G&`ZÌr%QíH’<4K)+Ø©k7ÿ5íË! ó:¸­ÏRï¯S¯w»Ý11oQ"cP"ó¤ëÔÛÇjÚo^Þý—)Ð+Wº¢u smòz·~ÜÈe¦zŒ)~¾;¢þF‚NEÜÙ÷öNÔ=‘0¿"¶9Ç$xs<ÆÜ}ËüÛ¿;”ÎïðÆ9‹ýÖE‹Ï~#ô;6¿ˆiŠüצ˜„ïýíÞu@ÏÈ9óŸ›8ÝÀŒäû!9åWf‹9B\Dí¡å¢¿*RЭªfZ2¿\Q— OOxê!ó‘Ì@±û3"e¿ˆq±ÝiÔëªk2Õ0]¬“F³QË]í–¬Â^(-?CQ4=bßò¢˜[°²iAFèº)W…ÌÂFŸË´K’¨ñ@²4VC¦H±øtiùj‘m|÷XD·?ž÷Jî_,ÚiĈz=¿:ëÿœÜ-½Z´ßè2pZÕéäÞ“KÀ ÕxQ¤Db§YoÅ&V§2ǪˆÞB[¹n^Qn+ýî•˨yußcvÎü¥­©;“ýT[ÉÚw¥‡'Û;ðs¤ØÛÿR«·ÚmüïÖþ»iöß³þRn*§½ÛÛ¯Áøë8!ë—–H¼Ap0H±óz”$:ûЗÁ:¹Ä6 üa¼K°K1¶I©d|ËohU¬iöMâjN»oÞ¹^Çú?oeX‚õ#ªD3°>{ÌŒ ²<ãôbpËš°<œ8˜j%8M²ü^"”O¡°âf·SWkE¬iöÕÙ•-®8T6<ùqoµ°\Î<¯M¥® †áÏ)oÒ7gÁ 9ìÑœ ➛ǵvgs➃SUgg‡- ªZ@@ÖøR•}¼N­Ÿ¸ùN¡A}Mdç¢ÕÕF@m&$J -¸¨21ßb¤4,ƒÖpÄÍD¯,:rôŸ€èÔš4 ŠA–5ƒÕŽhÝ2Ýæë “ÚÙ«¾Ç!™¨&ËcÍI˜êÈáx¨†ã‚˜Ñ¼ •¾$ö6Y±W^öȺéÜ=A7Êâ¨`ÔŽ¬Ø—|ÎôœŒ¢ÆX@j¸ê8ðEpCÎÜàvxûw+%U`¶‰]‡¾S-™.ô±h Ô˜:z1pµpž¯qjçTÙ‚³8ŸkQS–"½Š~­éDd=ñJ ,ÚSk"0s¹w(ñN™k1} |±ÝåÊœÆ,“ß0Ý1é\| ÈI4ÆŽÅ,÷0‘Œ3l½¤E¿36µ×” ö|âdƶËE+«Ÿpþ¡ª˜wCe $¸žý}ÏNŽ‚£‘3m cœ—OäŽPWC×íJe1h™™…ø\>ñg(ÎÞt­9-å# +ùØIål%tfâ[ñ6n¦Ž2L©·Sá šÉª6;;ìt‡eË·vU½Ög2áh-¨äk2Ù¸\2PMË ZuÙP*â0«¬!@›\0Ÿ¤ux <Ë—¦{ .ûµ—ƒ† ²É·êpW,4%»­b#)¢”Jy´™ø+•iàϰù¦h.”‚8bQ0’à5vˆ™~=GE2p’…§`a©;8i=k²B"-E¦†† ØhìÀë=&œp ÌJfçÌœ?U–NÿÕøéZÌà=Ø qÎASj‘=ìx„çÙôÉ ÎáòÊJæ±g‹L~y2®¾®m}ÑOÛ”µe‡vÒ0TƒÊöÒzc•&×+þñ@8Œ ¬(ÚJ;¾ö³š/í©¢T{ÑÀdٱ …Òá/ʇi±g|E„UhÜLK÷õärk]ÖóÃnp©Á&óPv>碑J,d˜yÏZ†Ö¯V„ 3–—6“†‘UÚb Ò”$s­€à¶Ù¦á:S¬_f2}h 2]ì_̰ZŠLÊhë* 4¬jü„“ƒ6¶V“[¥Í]@ཱCæCZȪ(ÕD¦_&< <‘ ªpü‰U~ÃJÅN¬0ÀI’^ô‘D×´]ª€–Øë>ï–M‰c1 • b;ù§* \ŸÆd<8ôáðœqÉåiúíÊ7b¬w#ª¬–@F¨l7⨠u¾+®ãæ¿x¦Ÿ´¡¡1v“"¿`Ž“îkü~N§Ü]yÝHo’ž.õ¶·à·1L–=d_ÉZ‡‡ôæ=HuÜ„TˆŒŠîDU&œ±\&€%üàŽâÒY‚›åO?–¬X+<ðqvøhö®Šø83ó‰½ š‰}¹öx kx割Èis™Ê5õväc%ž(v¶õãÃR$=ã{`Ùš†0ISk~¿Ä£Ÿ ÝÀÔ°zê«Yª¢£xL,k¼ÂÚÐuo9djåvxs~õCå¢õÃðã[% V{ù-3CøT¨[9­•2ä}{1? {bÿ *v̉6xýî,é„f¦Îü¾8¹0ØÚŸkŠø £æ(ó¸³N–F3j'œ…©œ.~hï#©.$ƒvi¸.3qˆ_Š–A‚NA…XÍFåÎ^âåmlåën_e}6ò5B¼øëûì0X‡܆•5É`(k ƒÃP¬3Ù†±Hi%e.íùLm`õæòæ'f—iWc«jüŠ&Wõâî‰3¤1üKKÎÇÞo…÷73ñ6˜NX½ó”±4Š4º ‘NËßl/@×jnc¬–9­°+».{æ¾LØaÒ[M&ö£?@“BQ`ÒõŒì#zsUc07fˆA1Zú ݪ(j¨cBÈ”J¿D$ÿþü‡ó«aØè]€À×H¨n'’Lÿ3æÀ;,m膿àÆ0[ð ­–×ùlGYÓLZù&¹á±û?_BÂß,Áªá)œW°‚<%‘ì†Bdè>z:œÕ’`~hP@èØ|ÂÒwÀÏ%Áì).XùôYØmÄ2Žc7^V®‹…%4i\LE_ƒ“«J ?·C†I6‘þKl0 Üpå¶|&6®ƒõLydF†ÕÅÜØYȇNЄg'jĉ"Øq@Ÿ‰ãašÉH^ €ó4ßÕÜÓÌ‚=§è ªÄPkÏ쩉â˜|Ïy‡K4XŸ–MP3ƒM §1ÛxÆ:X.lgó´Î#–¢=¤íz.„_¾Í`Ê#R@Š0 Tùô˜ Ö»½ Ì­ç¯Ì5÷/QŠîb—Ò¶¦‡7Ÿú¿èÞçÕã–-ÿºØ–`éqqM‹osÌê¿F7IVBÐb]Á¸³cSV±ÉÍ8Ì®¶3O̽‚Enq…ÐõN´;¬‡jŽYð-´¶´æ储5M1ûV´Ì÷¹%߃LÈG’éºæSEôe™)™b%…8°Ó81ú‰;U}#ªOZ,ƒ„Æ7fÍ.d e™šÅKXtŠf%yˆ>Ї4Î}1šõ=¿‚ˆ2@ö.>ÄDáxs¹àý0¯WZ+9§–ÝëPåXLʘº/Ž=ffùÄéSâtä€ÓObRú»l¿À¸ˆ!¿Ò»Ì8Å® —/n’LÚEÂìòeé·¦À>J½Àweš5ç16q¦Sç‘ÜàÁ¦xT Nµ¼çÄT©™cŒÂj* úr&D>»pm4÷²(^F;úI¥–¥ÍÕœ]Ò„J¶¯F^>‘®È5O¶tF‰­ÿÝrôænÝ_RÑ  bÏG.Á‡î¦ÌáùG!í+êóÉW¦ü«Ýß‘¶pˆǃåžÞDaXiιÜ9Šd:o‰¼a@îœO$ƒ¸_]ì¬A|GÎ"rD¾6G╱‡ü},r„/š á·¢4dÑ…Þák„ÞÊ$Ø%ü8Š õƜӼh;¾Ñ1iâT¸h°qŠ[%¨Í}®Kó3’#|[<@ "9ž`,…Á?¼ØÃt!ðKÝÃj`~1AR•óœ£â.%»éú´" QRL–ªC­*Wö’ª}¥,â¼L%ˆX-" S™¹¬«E8µ%£F“¥¬ö>_,ª7’Ÿ¦óà¢ÓVŽœ©ðò‰\9 ]‡¾8õN†5ã“r>'£ºx²¯èÑ‹GuÀg„5èÕÚ Æ BÖÒpñ•Nš-ŸÀHwØÀ5âÔjÑžã«^zÀy52Ë †šèúÜgE)õêªÿ¨t©jk²ÆšY¤pgŽû '‹Xö€ àw))¨+"ÂE+08xÔf*,É è1Çy⑺ ÏýunÃ*§Ò“sg^QÚóFÖÌôxàÑÒ]Y‡Já)â†DŒO§}% EAÎhQÞéPÈy jÙ©a»WY´uo±ôŽ (’J¼¸…¤BÄˤXÄbf–)l?-µ;±Y{~üç¶¾°ÙÚ@†JÆêN§XG†ç°Þðq}*¨¤ä\mCÞ=¨·ó‹Å„ ^©T©©3‡…Û(Íì{¼hyKïÛ±s ªTuŠwœÇAl üó ¸Ž±T {å¨ÑM©Æ±»sJAƒd·|Ž4è@Ëã0F ?O.!l83(XS®l;2ÊÜ œÕ AÉGÛ³ŠW½¯úOíîá>߈È\C&:¸]MWãµÇÊ(`V Žù’ŒDŠRwTx/5{©[;öqñšï®¢%<—ΰ½šrÓ²ª¶OLoÉw%W?þ0êÙ¡p⑨´¦S¯d7 ž?‚Mãã#Y® ›±ò'™2Ç„:Þ œÇ¹8ß-%kvê…3',vÏAö7¦÷‚òlœð¿é.-­Úüìî’?˜¤ÔÕଲûÿTØøWÿóÿ |'ŸÞýOã¹Þÿ“êoËãé?+8Á៿ÂÙõŸB ßú,]ÓøÏ5úž/úÐÒ> þü¥‹ÝòÎцgˆ¿5ú MÖƒ1öq"Ø4P}{¬L„üDNÿDó ³‰Â,l`«°ûÒ¸v€B÷öè³Ò#ûSvÇþÔ'¾Ó Î;Ö¿ñç½øÌ…ç¾HŸHõßÎÏ 5àÌ~½~ ûÐ?×7çrÖÕù‡ÎOÿÊ>+xb¤¯±âŒÂk.ÿ85ˆN.È>Q€nfI–(å;8¤©Yiãâ Uñy| ¸f ñ¬%²ðw}¯ÈOüÅË>ɺWôçÒöÍóÈ̯eï ÕÅöÎËï€*¹‹«{ÔXæÅ…WSáÅTXÃ…WR!QŠ?"Ÿ ôr查µá^$¶0‹¢¿ßàÚ“¯£1ÜÂÅßübÚSqÝSÇÅÇLÛ~¨¿M†ÅÀÔCëE‘|€5Å5ZÅ\kÞ9_,Åü#ÛÐD7‘GÝ)=ÓsÍÝV.3½¤ŠpÒálµg-'3C…í¿™ùÙ’ÉP¬')²:ß{ò…½P(\Ò¿{C‘áK=Ó¾Þƒ ó ÖFÄugüG½Vk¾o7úõÿB:wU’W Œj«¸0¯îØcð\’b('òþ1¾ƒÍøÝwFµÊ¡•ί “!ü3Ì4ö¹ä<$9x`üØ»øËu¿~ø&‚Ö7¼5¤÷{cÛ6eŸï¤CÜZÓ’ÖPƒõ]mÄ‚ÿò…|By€ñUù:’Åz›8‘ê¡9 o)ÂáeI®<“Š Êœz ²º+b Ÿ?aˆíj¶P¢Iå6ÜÏév¨X,Ūǜ'Çýì7û–ÕhŲ©j2«å YÜ0†o‘<{e?w\ì“ýflO&ÙñÐnt YÍ`v!\FÑ€ \ÒCÖÿá„i>,ŒÏÐ!2—@Gµ Чôh›â-ü@1ggèº Ýýâ¬PÊ`<öJ+œ ÛñÂöÏ9)¢»œsyD`(:{s4õ~ŸžÈhfå-ñ m\Y±”×ô, õ]þ4{÷Á¹»{R†ÂCÓÔ¡³'ðoôDSEiÔ{ƒÜ…7Œ}6lðS®º‡/|AE]êé»!Wgk– jvvb´‰Ä©M^ME°:uòIö&ÿ3Žík9h®!ü\¾|LC¼´³³cRÈPˆdß(H=Fð;ôGÒræûznÂP2 O>©½7<íë¬ÃoÇçßkQcÃâ7–3•À·ëRé¯%CNJ˜ZERË9bÕòu/V-ÿó–“l™1Z°,|sÏR_ÖžÖH;«ü¨oco/¦Y¹bGö’“ßèöð“¿Q‚è^¸=¸›à÷{ÙK|”¯mtèie$lB¢·¿Û‹8V(ÝÖ‚[Ço-,±íÌDAWe¹4ɰĖ¿Aá8x9âØ‹Õ³*ÁÃ6IÐ2©2™r Ä>X% KRü¯®Ô*Ï‹´ó&¸ãvâ·œ"öµ-ç“*¾ÒŽ‘à—GÌðÁ´"ŽYM.j' D°Ê–ÕY-8&¾’":‘ñE*ØÕjZ%·¨ v~ÜÒA`% ~5O„ÔQ­ÞQ+¥EÕ¥Û¹rè®Y¤šâQ­Yk´2—¤Û¡Úw…úi5Õúz¡Šo;ÏZêmjquÉ¢›,P!-#(=ì]õnÎ*gï+ƒ÷éŸSÝcŽ ªËWN$µ|]*¿Ö*èvT¯Õ:qÝÈ–Ä(}øáÎݱµ@  BÈQ#‹ðÉÝ[ÍÙón2K¶jôX¥FáyŽŸ]eK`Yp}P—Ö¡±d€¯¹»£dk¥6ùcïæôcïf?Ô¢=7²åíî0ãqÎQ]îîÄ÷9pÍÑÔRã¢ü,uê(:U™;ž=ù„æTßÞNÖX cdš’ÌBCn~@7™YÝÝѼk¦¨‡m¡—¼m{©û"碩3iÏÇHõ°Ü‘HTðXÆ!ÏhJ=ÜGzlYZûÆÍöxX²óˆ+*kò;c8KÝð0#×6kJÐ;3àïîèyò”²Éå óU*Z¿P©-UBÃ|åƒr3Œ>7 šaÔÉóÂU ©þŸM^=²ôsÉõÿêÍ£F'Pÿ¯Ùi´·õÿ¶õÿ6¬þ_d9µ˜¤ƒ¯AºÑ5‹¼­V¤ä9‘d¥5sq~;d­ŸXíï®ByÞÞÓ|D¥|_é}*·¿\¾}Åú~…f}Í€a¾æ¬üGO¯åš•‚5ü\¬ ¼[©O¼mÔµïåmHMì.Td.꺆C.(ŸKÌ]œ°ü]+xd¼Sg6ÃQæíÝ>yKЀ÷ѶrÀð”'æÈâ%ù{¯Êªñ¨ „¢t—ŒŽ‹¾—U ôýKIf>±”bDZê&tìúQðÇ'‘øÃTh53……ÕÌ0†H¦ãÕH$‚#ðDؘA{Ö4lŠè_0óCôŸ½¢\é9eâ –Œ›åe a€HÊçÅ!XcXŸZÁ×¢²Y›¼·¿X˜FG÷ñ`úï!æ³üo/}þ‹²‚¢æÀ_aÊ{"b“B )8 Œ”Q˜ó{ ŸßõSK¥ÑAΘ»=]Åbö .VîÂñ 5ªHÜŸ³TÔÌÑ…òxEÆ+ —í>xFéÕ>³’ËÁÞGæˆ<1‚bÚ;ýx~õCv¢OEY%)Ôà‹ê îz¤òÅÏUÊÌü1ꃔó=Åü·•ËÞÏqŸ} *útaÏV3_Vè=aÍÊÁÊä†x9ÇBƒTöÈÄÅ !?ß)›íÃMÿöcÿ,óPðZg<àM‹(br¢¹°Õû):# Ââ]Œ”ÈLöµNË_È5¶q¶_¦>&Gja®BŒJ?Cß%žÙgšiR3 cÿØ/o Á3ö]Ì–“r/@º·U&Í^2Ñ·ëñ[fN•ËøEô]’šw0>Ïy‹_ð~ ê£Õûw1z}^š…8f a¥-Ž”æV‹så/`zîUÎñäJáéĆ poޝ)‹¥*ÑÃ~ªUº¥*—»Hµ\n€“(¨2–ë’þ¶…Þ÷‚þŸÚQ»ÑøZ­NkëÿÙú6Ìÿƒúçù·ãFì•v÷Nüá°Whg`‚»7Û²âý> È5PìfXùñ7ÎWtýDMøšž}â%=<±ñšŽI söDp¿$_γ•™˜#{j/Ÿ¸Û‚ÓÍQÉa)bLžGQ]Žouþ–žõ”’ÙîU€gB㜰ÙÍÙûË[Bèô$0¦û•ǃaä¿9óüÀ(Vf›h™9sdR0gíG|£¥ýÇMå<¡¿±u·º¿'Pv¿ÝÝ`HS$ Í9vF„rë ҜǬq Ía ð]Ø\ǶÇ?óô¢RN§ø/±Aúë8¾/癸ØS1‹ÔæŒá1³)b.ì@ ݾ’}1~GHÑÌ“[l5níú+µØmÊ¥6†âÁua‚ųѫ’ZYbU:+×Ù ‰ˆN*€mã¥õŨå*+L;[Þ Ù·Ã›~ï23Å7Ü•H¸°®cŽGXa’µêk?óÍñ¸Dïì¬R` ½1‹ü-@‹%ù9&ïÙÅ ¥¡qqi¡9š!Ž::yx¼üøœ¶ÐmèRí.»ä]Ø GNB•7¸ ¶¯äÑŸÑÎ’K_Ìen‰ºAl€Ù%ò}ÑÐÜù!û(WwVEÚIË6¥ÄÿÖ:õ¦bÿi¡ý§S«oí?[ûφÙ®oïûW½÷=,B¸ÙƼQóPÜ)ûO'¼×œc¨?Ýã­ApÅ…[Ë“.(”H8Ú¿Hö$XHGðcÃqâÛW´ý„&{MÃO4÷r}§n{PÔ”4¡V(Í:úÑÂcŒDQ­á¶‚OöX$•,`IúôªHŘàŽ%£‚D÷â>þ›ôkx¶ÔÌœeGZÚôÓ|iþÁÉR µžæÎ‚™O¢#¡tΈO%ÁµSsd!¿%˜¿œþ ¦j‰}ÿjÎßavyr¢Ãp-3ÇÐÆñúGà½wÞŠÖTœsäšÓŽ;͆’΋1ËÊäbf,Tšúbº6’Γ£}3Ið‹ÀÕ„…o$Eˆç£~éãRëþó²®ßq´nÆEhˆˆH ´ ^™êòê5²6buwg‡ìiò—²^T°x³ÀÁ~+Bª4²Þú“]xœrÙ¤ŒP€3L¦æ=1K)u|¨G¾Ò–÷Dõ¡@-ã({¥â¬Oèæ—¾”ëGÍz#±Þ Í€_ NŠ%VŸ!R4QJqÉZºïîN¡UåÀ™xܨÕb¡ £ÐuYf¼Ùß›:#súà Ðýð_D$ÿø`³D-Ã{¹‡»ùïÓƒ]&ˆ†DuÓ¨uTÆ(< „~ÈÅ‹F½Ûªe…–èÍ}LPLä¾Ã°j—ŠsL¢Ö£1v°„ ‚”­ڲъ3žÙs¡ˆ@‰¬L­/ÖÔ0Wºä2A@G–R23Æb(fJ0ˆd¿lVvìè„ìîð‘)Mm„p0´ÚoÏ ‡­Œò”_©‹¦`Ná\øù”âø¸h½™”äЪã¨Ð›(×–N·ÙŒÅµPªæÑ™*¸\—(¾Ö¯ÄU}1ošu0륢hŽ¿v,!Ë?ë5#—1¸É6Àz¨ï· 6’ýKAè/›ÿ_; ÙÿšµæÖþ·µÿm˜ýkçWgýŸ¿ëß$”î+, ¾Ægú~ Dßx; ¥N°û–p‰‹ö ̤ÿ3H¿ÛÊuRÚ?¢½D Qˆ¿¯hù Lóšv¿nå4úeŸ´µrþSR†õO=XJ´ý©ÄRͨý:)Ãà×®u»ÝZƒßn¢«ò$›Õ/T©5£©Ç«¼•üðjnÿ¾²r¼à—xÍñRèz“ÅðXÄâØ®ëey_ÙâœÃX 2ЗWvZ0ÕBõëyýu‡ÅY,U1 ´¶Ö±Þék(Õ¢êïKÓ^Êét÷Œ÷ÌþX"Ñ;$ -·A¶Àj¹—H[ÔFÌB™oHbI£,VR±6ÞÈflvæjÌør[iÛõZ«ÖL¶ÒJlÛ9ß[EŠf;*¬[î@cö½åƒgä7}ü9ÈÉ{Ú»|Çʕˣw¥Y¥¯F2‚–ñ.ÓL×’ÑËy½—ˆæ \‹8ÜL~d«%Ô ö‚D[婿•¬Ø“¢09cÖõÙu¬xóTý‰QΓ0‹€×A%îæ³æ«ŠñëéþfœÀ:ÿU`xÿf6ù‰2€7û¿úuY~3~•ÕT~ÃL{úÛAèu>È¥0ýïîîSçRmfTøž"p×õz½ÓJqHÂzB&`™6b!øäÝ™R`ç›±fK…³Ž‚Ë.&^ Ó:îdv€¨ü³\ë—{†×&YaÃä’6VJ[*ÐÒ•Ù1jMvœÈ)Œg”Ž(ü¥B/+¥á5â}BàBË®•EÎ sŠnš'î²,¶©ŽZ­8Ìsy\2\Úa³Õ+OnÇ“•Qn ê9Í©Á_/л.‰ôþ©kßÞGÞD²[%ë h4`c¦9RéÞØd¨âLÖ‘¢Þ‹IéÅ)ö‘\n ÍV¶)hÄÂèõOè¼ý‰÷ÿ$á¹¼€ÿ§Ù¬òÿ;­ZgëÿÙú6Ìÿ‹l´ù® Þ=ú5Ð6)`]hÈxÑšð‰¯çMŠ_4å $!‰åó3º.æoJä*ÁûÓC‰Ž¨˜¹ÍcV†sê¸{Ô(Ñ9• tšæo jJyAÃP-Ãþü^¤ããz]-ùõÊ^¤¨RXa›ýŽbÃRÁQ_!‘‡X¯0X CÔ½M´·R¬ta–@qQgJÎ ‘–*6ˆ¸Y‘±½zwbäb¢îÆ£=*ž=W`=WÎΚ>œ^R"í…õÉÖK5ñR_°PßcƒKæ0\R‹ Òr’¥X“ Á5{ˆ+ò%ö›Ü∌Xû¹-Ú¿§‡µk…å8>¹Í!Èùôɰ'…è”–`ÏsF6Yã TÞ ÔG¨ç8ïh´‡¿°¦;Ét3~Q7Š|Š­—^Y}]X'H˜-’øTÔ±ÕµºÂ¨f‰I pIDq¿ ª2VJ`»’¿É½GƇ•‹ÏÏ`‡æ;¬Äl  œàDävŒä7zw0‡¬ÓÊåÉbÅ„ãÉ8!ö*~¬“G`‡eüú=ûÐÿfÔñ1,LN+k¯Â ÿ.|ÿÔ>(æs{þ¿=öì/ž{Túxã­Ukìà7Ñýѡڡ ²Yö¿£QÁ;=ݾíCË0(ÿMêë N<& Ù°œqï{_ªÃá­E|·»£%F‘óŒsIvÏ`§V¯uR áîî\:c&ñ¤°)²†ëÍz#ªîûRJávtföR¸g2}ý^^±.ÛÝÆ‹û¢^¯šBV¿ÑfË(ìaêÔhýú=LEÌ$k”Äœ•çqÊo!)¼¹ì6ÀȾuN•ìÿ!×&ñòY €¦ø£v ÿ§yt´ÍÿÙú6ÍÿCòaïýEÿOœýã}qLº&¥¡ÿÐëQÑ<ôökúk´I^ÓEæÕF¦þ„f¤ ”èpñ'‡Õ‚>Ô¬Æè+ãvþ×(ͱâsãys~ìIA%*s¸ëSXÕ&çs;ͦzãþê“s^'ÑåëJâÈ?¾ÄÅœe ŒÖªqi™s˜CçåŒd9rX' 1×Ò#¦¥ÅyI ÞW ÞT £¬¤–V£Ó:Nqˆ Dô”%Y$>o𥤢xÅsQÎÕ}…‹€ìÿ´Ôr­Ea{I„é‹€%ldì»"Bœ!g§'…ýÓ¤<¤È˜ù S±ÖXÕµ[ÀØjÕ;9ñ¢ˆ_JvÇÄq”ìŽ}Ÿ§ì+ã$4@ƒO‘ogNj¸-ö_ 1 ±ÙldÎá«QØ` ‹”íWVÞÙnÕº›‘7Ä@Äþ¼y#~[yë}þ†Ë<¥ÒÅ:’€åª…üûÏ$ºu óñe¯§)€`ª@Ϫ’v·MLTa/èZ—zïÔqzžŠÞD^XããFšÕé⫚c_Ê”NÙìÒÉ~{ ±ôd±QlDN&+E.ˆ*64ŒÉˆsr0ü/†òVmÆsKu¤Õ¬µTü¯æ¿ÔêíÆÑ¶þãÖþ¿iöÿ·§ƒ««þé°rþ¦oÿ|E¢qNÓAÿÇw•…ãL+3óÊ.‚T; +aÅÛëÁà¢rÙû¹òá¦ß¯p¾Ÿ®nß¾¢k zþ×­ °‘õÒg«|°àÁS¢« b²˜Ï€;³[‡åÎfca4jº§|LøÕn$‘Ûa/):¸tküÈÍÝEÜÝÆQ£«Â­Ýb8±&µÄצETx~Þp¦ê,Ê2\„v7™åЀ3Ç¿©ê÷TõJy[\?Œ¹â>šî¼’þ˜zNlÊ™ŽSóŸ(~³®×Ž:-uù¶gŽ1éCÉ×åÑq; õ^ [† •pÌðZ¤•iÕ.œe= cE±©«QÍ“{ugÕ0Ð@ñ¬[¥€ŠÂÚ£ÖÌDXwYÐŽm<î¡`’Iáb5×|µ’@ü ?gƒÝv«•¹Z Í㮆Øÿ:@òåLnIéõZGG××,&AoùW‚@^L±É‡G¾98äɪô6”rÿ‰öºÌmu¥÷‘Vÿ±Ukð?šZckÿÙÚ6Ìþ ’7ð˜¼6y[µaê›#“P½©ŸÎ‡+ÛÞÕmΛÛ[`3‹Iқ¤„³ÞÍYŽ3V(ø­@VÁš&¢h>ç4ÑS…íAq3TÐ äb´½XCxÚ¨kßKUYYLQÎ?'u]‡Ž!î‡K{¾tA{BjöxéÍÛ¹±p/°³d2-ñ›•ïb@+$Û9»àêŒ)½§Îl†ÙÞBôxKµ»x+û˜´~ÀCú<¼Îú-`´Ṳ̂Pè…²Ûùs,}×·€±ré˜4ïwöë¿ÇòŽù]Ui„™0èV¢ñßÄî¬å£eÍ5‚æc V²Ðžó„bå–<3G®cÄßš(ióÁÒ[*±wzÑ»½M(¼¥6¡ÚÛ^Ø™±Q¤‘³´ç¤j•²¶"¨ã®G"r›’©ŒnR¡V ŠSØ<2çÀ}àìÔJ¡™â‰SèuVz£šSyë¯Ulà •'ì$ô½=¯ \<1jÕ¶=ÿÎàŸ‘¬â9ß È¼2Ão «”yç|ñ+æyI a×Ä e_Ôü8ÕÇ/¶d6ÇӠ퉋¤ýg5S8ÒÂQÌ'd£™Àwcø‡|Öã AÃ^caY:£=föcFá!{@%Ww<Ý\ìGO³ƒÁ¹ÂTïKÝ”s |D³SYM/VîÂÁrÀd‘¿]-,—¾$£—9–ˆáãfX^UÎ8lÇÉ`UÎï—|äoAÒô>] +·Ã›ó«*ý«†ßf¾pH°FqÊpa°ž ’›$ÞE‹žÌäÊZ+ré3ÔŠÂ*:}¡sâ~@ä™.8¦ZX#®+×>œkWÈCãž;øì½µÄïfð<Þp >·ÓGÇý,C(gÿ¯Q²¢.Eá0‘H°@†+dbÂÝ!nb»ôÅ!æC:Ì„ä³ÐàdNYКK;……[î2Ó¸¢È›«²¨Nñ’GFmŒÖr1FI±fwˆv– V†gŠû0\Þ!uü”jze$΄Eµ9üpÔÚÄ´£•HtØŒó1ˆ T:=á øf/˜‹{לM™-Í_£)¬Ç2yMŸ*֜Гp‰2VVXë»ÜEÄüdQP&*Kƒ6:®à‰kÞ3K7¦Hgc°×ðÔŸ»*6‹kzá½3GŸý@_Z²b7Èi6ÅdDñメ14´¹,€q¶° ÕlžqåiI;Ðt©ýÅÒžÙÇšG,ß·è Ù#i±€[vQ£ýVåf×™zÁ®¡ïhS­C5¶ÖíÙˆdSÍÄZ4Ø-®}èÁâVÐ ëá»ïÂÑ/%â—X 1dÈlœßüëtùmúÊí/·''øËùYÿjXé ‡7çï? ûƇÁŸÝ¥f•Vm™õù²¥.~_`ǩࠛ³¯êûÞM±þ¾7ö.°ÏžñëÄv½åßp¸¿ñîѾEÁMÿ¢‡QC½‹Jÿçkcÿ 5ñÆøÞøp~s;üÛUï²Àèù_÷k5s¶Ü¿¼¾8?3¨‘¦h¥L ÝÆoT‚H‚WÞ±h]6ŒÞÕYF6ægß;0‚³ä€ÓŒór>ÁÅþh2P™G¡”>„(0}™ YQæ<¾l`õŒÊ½‹O}„”oÚÍTŽ*7Ó¿ôûUΊïº`}Z_Ø…öŠsþd¼A1ÂVãø·µé9\^÷®~©^ßôoi;œŸ1 UaM°tѶ:Ÿ™ÂNç,˜âO%Ýf ÇE W,›f®P"¡öªî:*_Y~˜0«OõÂp;¸–âãÀá62¿·<ß{ÄÞ« ¹l7òÀÓCçŸeÍC‚§æï„‘!¾À4‡i5OΊц‡'ïå¾·rI×À¡0"2ó%ã!!-’þÁ}kó“òT28)fXŠØÊÖ¨’MãBB¢Ìè„ÂñMÏ—hg#ô»XÁi5Á£ &¢\¢?}ìßô}˜TE˜Qcñ£ú¡×GU5ðgÁ×SÑZûìúeô0oûNÉ^óYÈÜžŒ¤Pp±Xزš¡<˜¥ŠSI Ügü!.K–°âÁî±ÆLD?¾{†•:ÌÄU¶I¡Q–îfï´M†á’žå'àî=C»ÙœzGTõ,rù(…ÒÅÔ˜/–_˜^;#zˆ…6?ÀÅEŽu.`ÒÈrç¸ì)ºòhÀî7KoT(i …sP¾ô¢Sf†Z½Ë…0o ¢Êó;ajqÕl:ðZœBžPꃕÄ“ì4²ÃOòcê€jÙ-˜±AGy\ÛéU!ø%•Bümw~„^}E×¢ªRÃ0ˆ¾¬ öÀöDÜHX†èœ”¬Ø1qZðÄgtDSê?FÏeQ`4|8·xRaÅCîá–×\ª,É’.b4ð’8Büz¬?LÌà"–옅Ïü»cÏé6³òñeÕbe*3']›íˆÕ2|¬ÄH´ÿ 8Îz®øK‹RgûÚ‘?[b²¤âxåÒœ›÷ –ë/ŽgMŒÛ%ˆbX§¢ÊŒ?!>hÈËìáצZÙŠ¸}Ûi ¾ÁtkZ.·`Àæº~Á wëüªü6VMzï_:þKS«ÿGþ¿VsëÿÛúÿ6Íÿ÷‘í“͇uYºÎxÉ"]Jõê?þç\y,Áó·~kªZvq`Vƒ%®Õ¯^ÑèÏòšþ¿0çŠzƒ ^ǵ1›âßãçóîÉiHðêÉÚe[E˜ îöd¡È\ã¯x—Uã”å9ÜV) »'˜gŠù&pw¦teë‚q­pãµ1TÅp¡@Pià(/ îI¡1}úðáÇ ælmL'Y-Á…oá_Ë8ÃØdg“qÈû›Ò[¸ö)iÂøÝ\æ®aáŽ,cA6ª”©J ,º4Úº‹·š¶!(R¬Ùà *t§\Ú ,øxz×çt .w\*ÆB0an'CQÉË‘êËåa£éZ'j<­"AÔ’¯“Ç}¯¦‘_ÑHqÀô;eIœcÛ}gìá™êF{K|™0_®QäHcYÂÜ]~:•䂤HŽ( f˜¹“¯#´‰ÅaOí¥o»„ÉûwX Š4Äg‘ãÜLíØa¤ yê˜ âL(4M8}ø¯¥•…ÛšŽ3´Û¹ÎðIÏÇÞIÃgïO£á¿µÇzŸƒ¥$ ÝÜh/ÃŽ‘²6/6ÅJx`¾¦æp2y/kkJä½ÑÑ’Þßå V L;¬˜Dæõš[ž'C⻽|RvNNf‡X×”{¶ÒZÐB³IAÇOétÏmâM±Ðpl¬å8åöAÝšŸ½a~è±G^žÎú#u׎3ÕR[3¬ísÜ.!˜)À$RoŒ§Wí2´d± ”0ß ‹4RIþv5 hwÑ©¯fjÌ¢Ð16F´»¾Ñ1£žŸ¯`VÜ…dlÚõqk€Ìcÿƒ‹Ö‚®\©¦Àû_³Þ< à?·[Gõ­ýokÿÛ0ûßípp]añE§ƒ›³ó«¾ }Sû˜ÊÐÆù·ãF|`$+H„„Pšo†:k’àžÕ†‚µJµF*ׯhŒœî5m‚±œÌi ÍÞZàÎQóQ Lø`) &<= Mú4dÐÖ\Þ0ü…ÅŸxå½×ZÍF­4 —0»D]h‹k-¦æÈ€!´–äÇ£J§¼‚v9®uÔŠU¯ í’M%²;˜K¤‰ƒ)¸¶D¼»·y'w¢+p‰Å˜R(Œ¯SÒæfjÍé²aŽÖ I‹ÐVÕ^*Ç&áEï1 ¬Äaánq¨²!¤üa¯ø0³,Ï€ñ8ƒ<̆óV7¾‚¥é4›z'–¥ž§ˆ=Ž",%ŸÇÃáo})¸+;xZ ³£æœGnõSÀ„v qˆ ×c­:£_ù/ÇfÆxÍLË›Î{ ”ɸ¼\áÍÒ š;Z¥X ›#k\ÅpþœãJblPb Ð …®Ïònvt!}®ƒã‘KHŒJj$çBÁ¼°4<Ïå“Ï[”ýúJ¼{2hy‚·s±&¸\Ò„cX˜N«V¯wò$Eh{Æ C>Bbæ<È")õ#=ÚŒ¿ŠÐ»ßŒ¸$%ØSÉ׈}š¬àÔ‡‡±ÀñÏMÍåÂXRä+ú¿*µ£J­aÔ;'­ÆI½a`@á·µô-…²‘°ø[‡AI4"TËðAƒ¢å}F&e…dls<¾7ö)ðÕGŠbq°Èç â$ØÌ—××ÊéÖI½^§ƒ\+€{ ÙRÒñ±†,`÷º²Õ•CêÎuÌñF€h÷–9‰àyÎÈFó´l…­È+§0¤×µl“IÙƒÑø;˜‹no¸ðœ_ð6Љ‡ö±zxP/èä¨ÑiåõZ£¿n§[¡ó¹ ¯ ™ÞÅ^ªBŸÊe²ˆ%Eo$*ë ÕGZâTÜØßJÃHQȧ`ÃëûX2NryY"V÷& ëë‹|ëaù'Ãÿ—)ßtRf€tÿO'€ÿß©µ·þŸ­ÿg#ñÿ%lBÇÿUT˜ˆÒ¾²M&¡Zá,V˜àÒ%†ÞÎ¥_.{!á:Ão_»&@xê×ôEq0§#(ûL®ã!Šœ¥Ò Žž²Ë¦¼D7<}Ù¦Lt¶Ì;‘“éßA -‰•ù+ÃoÔntêÝV¹LŒ(å0Â?RËD¼è<‚ˆ{nWSñZíÆq­³AµB|N÷8¡õ„ ;þâ3ØU<Ñ‚ŽKV^á¢j”æ¶ Ír:Ù=I_ª•Å–JK­9J¯ÀKû Bãñ‘Æ9²NŒ»£ c¨´ñeª¡.éX&çvUµ›µèñ‰®ªž5$Ž,ª%Œ©Î$Š4N$ìË=w¬*‰$}¶W"ª)äÚ¡„áRÐéC+„AƒÄ9´rúÆríRÞúÁR÷àÝ“$‘‘­8´Cá/v¤°s…ú'YZq"3x´Â‡†í 4ÞèØš;ä²6©}‡i”äëT§¸P±.F_r1ü-j ùÔ« ˜·XÞƒ¬­-=u´A^þL º‘9!–͆¿4-•3CÛjìZÎ@å5̉»ìm¡QŒX‹äIÓedãñr¨ä¨Mœ• ê)ΙÓp×tà2j'ìÙºaO”F”'GhÍöŒùj:e†×ýóhƒ®°ÌƒL:jµ;ù+›4*ÅC$)û{Ìògœœ_ [FË€­eÔŒý½{×Y-Âßýû{>Î<ðcïæôcïÆhÖè¡:¾.;QßóF¬™iO•ïá¦ã7`Ièù6÷ß=XÌxòábÐvnðU×É ß¿ àsÿÅ;ÄØ|‚¯†ç—ýÛaïò:øöÝøo«¥M#ƒ~ýÆÄTÄ5³¬Uy–Ò-íf]¯ª’äåÉ'ã S?nv^Ì„à µî‹{ƒr˜â/zÜ?±ÒS»iÆÒ“pa[Ë3Ôù§ðe3Œuùö°|@™M#¹|@úJÚ÷OÀ·uÿü3åÿX°‚WKƒ5ìåK×nÔ;`ýç£ZsëÿÙú6-ÿ§"ðÓpp:¸¼<~ ž%ÇWog¨$ÿ~„Ù&'™ã±ÚVÅu¦Sʺ~€‘T²³³Êð¦wuÛ;EæÊÍàââ}ïô¯•ƒÁ_Ó CÇÒK•§”f_3-(¸ Öu¥ó6§O(jr×.ššR„´“§Ìä m’Èå3\!šî­ÎÎdbøÝRd²_= OŽ3ͺnjƨlβ qî¼°³xÕj¨Q¥¯ì¬ ñ-2Så=¢/˜¢Öó“@[ž8Ïþdi¶õ;ë„‚z¬FNûò6!GOÈñ«VëïNŠgç<“ßͼx ”¹"z˜[`Hï*k]äöß4ÛÝV稑è¿2ï?”¦EV³pS$; ÂR,‹_ã0`8æÞ~±ÑK*üP¸†œéXzh´“ajÞk&çÅ;G bûÍÙûË[cßC$Ó3®9šZÂGè ¼:6‡N-*dd‚,Ѐ´ÛCáëœ|H„IMfFr}ý,p,ú¥’Ùãä4€X3¡Ý@Õžlû~¥ŽÌnV䀈]Ï'íû²n’ï0*bC„Ö=nµòã×± 7Ûǵ®šxšhÎe`« >¼•ïz”M+Ó:Cl¤B¬;n×Ï›a´í—³)CíŽjPÉ ƒØÛ‹ÀV¯ÉÙJCŒËŠÙÅ¿ç‘Þ_×[Uóô¼l°†2\ãAìkfo¼©9/„qD›)ÃÎÞìÔ@a­¬ó­Ë?kïÍ6ö¹µý‡¯±%ÕþÎt?ÎçH²¤lJ5p…À­Oà«ÅÿŠÎ½z•úß„ÿÕimíÿ[ûÿæá…óþ$`k4£E *zwÒéUá¿¢f{McTêk"ÅLH9à_¡S¥Tô¯Ðìpø/,Ÿø2ø_µv·ÖQ/ËkãÅ¥ªí`x¢7ºÝ-Øl –Û*_AÓT¡‡"À@vü3 €!ÑÀygµÄò»è¯Å'Vÿ ëu„pcEM“é“ñï Ñ'vÏ´Yw\a]¼•ÛEªsì%Kk4[ ¬f4A $¿6ÆZyVÄ›.kÅÀj hÞ6{I¢éÈùS曳âŸFÁù|ÍÀiúÞqÐä>d]òµ ^(Š‹Æ[•ž­çÀEk4;:ÍFà¢å€êÊ„Óõ5Á¡ð“Á$ê~߯Ø Û‘R¢X.¹o0«íRñ8læ¾wVÈÔü»¢~Ôh·´ägpÖA'£vãÅœuÐ_·vÜyyg]n«Á»¼Ë›‰–J[ a n‡7ýÞebçšò‘×…×7º,2ô©:å¡!¤DédœÜö³P§åNò[ˆJ ò)II Rš)ÃQÙê·ÿ‚2ÙÍ6.‡]-6\Ðú· ÈpQu¶žÀ¯Çÿ7¾£x„Š÷4=Cðÿ_½yÔøÿZÖÿmëÿÛ4ÿßÛ³÷”TP¹ýåêôí×àúsœñ,ý6`(6K"Â}„PÃ.͹½XñZ†>nØ`pv™÷\}¨NCa.™£‡îÿö¬ÿ¡÷ébX9í~„“çí+: CË£_¡ÂÜœ~Âüs°Ž#1r’Êð"ªgS‰îC}®ÈsØŸ#e–v\äÌx…Ð4¬`7‡rΊ|r‡áÜUÀƒØé6»u ›„……OÂø÷óz¶¾ØÖc…^ˆsjýO§ø±ôaíîÈá#M38Ô1(=6Ÿ!×´¨©ÌýÃQ€4×Ãa4ÊÚ‘­”F{uj¶r+?‘ ‚°–«ì= .Æ\ |m9®œH™)xphk¤¥m`ïò+ WA»µ\\ú)öéú¬7ìóûÓm­Ä•ó«Ûaïê4ÔDk^o]1(3N$k×i}Œ¼Û‹Á0iبB–o°uóæe¢ì6/i^m¸0k'°g2K»ÍF«›Ë/²³?µ–Æþ¾Ü¶ûš@2ÞLçàà«2ï'-.¹ÊáÙÝï¾Ã­Iʯ9en¸]ÙÕ[õ|}k,yëQý*~ù+´€]ùÁ>Æû¹êhÙMzÿ&W˜#Êo÷ÎtŒ½;óï{jëû1sxñ`W%#8D•¦Ø¡æ¦²sVB«™¸ó^úÈ—guÕÝÎËc1½¤HóbeZVÃì+ɶ5É{ WØž\¯7[uu)köd ™¡<vM•ù'"UWžÇFïú¼º±†æÄKWQ#³ÚèúæÌ÷­\ÖåüwÆ 0?‡L[ësNû¯3¾{»oÖüf½°ÿ6:Í£­ýwkÿÝ0ûïàìýé¦[}áþkÍÇv ÿôÿÓ«þãÎÄ ö=fYÂ^‚‰wöäý0ï^>9 [S ŸäÝ+ÚfãmlR¹ua]“­Â¬œæÚ´ZÇ8«ÌG“¬ÐcÌ®âqTµïQn<áܦ–éžPíW©L"E\‹Ì63¨aªºb$™Ld6u2Uýö¨]÷ãà.ì;×UõÛfTïhËdÑp™aÜñÉ„¢ÈEtkš-–±‘±kƒ¸ÆŽ9€3°=ZÓ)þ›§ @[P-_Äq§a„ÍJûˆx¬Z²é!Mî,´4Zž@ÍÀnã{YÍí?TòñwãŒÆ€Ê)ç¶!Øpi\Çs&Ë7{š³ªJ³CcÓ»hP Fìñoo+õúÆOÚ[ Ç[ÞÃ„Âæ‡c¤žéÞò÷7ÒQix¾Õvd/-¾ôð·Ù Ê(‘)׬Gß¶)ÃדÉÅÃ’I©‘3ûvá:ãÕhéÁÕp>‡ ä¸4žo³àò)Žþâé‘!Ç;Ñv’6t£Ù!‹ÜýaÿÝäþˆ„] ‡­A£&+yT³é''ÎO~ËxCMs\qƛу•¼4±–—X=Ûäs•Kn°åëoPŠ˜›8SSØ¿”B±þH÷KÍÎÌ›S¶ñ`¿e:£Äy ÓÌDL+™˜cQ•‰eò¡“`$ɪ ®PÓŠ\5Qé~û)éwÞ ¤’S\&µ‰k?‚ìóQY˜¼˜ Êò¸‚ Ö›:&«FSIA!zé=,¼€êßœÝ^aþyœw¸2–Eø\"ºUïˆTX{_H·2–+fØï —Ìì¿[c¾­WÓÈ/ÄÅ„E\ãïTfàÄ€Ó|>²]¸°|gìáíÖ7Û{Kl"þUöÚ^(s8t;ðOYVUˆñ"“ØäyÑbåà¸ý„D= >†«•?‹ýŽŸŠ–‘YîŠèÖÖª}±õ4µá?«—ZOí¦äG¾¡¸F›i‡«Ð¿0U >YaÖ–iìÍ<иöhÏ`¬‡3ŸØ÷+—A"#§ÂóJó¡ŠØ¸ë`›ÄJù9Éæ]–`EJÝ ßëÆ›}ÑçžÌ;Fiªþ-ÄÕÞA(õìD>ÄòÞ˜®ÈR¹¾Áü.º@UPXœà*g½aï}ï¶oP¯ßj}ƒëþ•ñõZí¨Ý9«7šÿ…í‹æŽ"G"¸ Ê.µþÚÛ4NB²0ŽôŒ§OÆÇ +\äŒDòÏö ”Üᦽ³›óû7ßÿǘááÙí}wÛ¿ÁhÀ¼åï¾— Àv¿ût~ö½Æ’ï®R>ñÝõàfø}½Õl~=üíGn÷ìVkßõ®¯¿§q•:YQŒù6Ä–èùóo ÄITGze!Šh€µüº IÞ*]èByÉí¢4·€‰“ç´²x¨š5x$°‘^¿D»]Ÿn†-Áá—bÃË忣ë÷xî⯬=Ý*»uç=«ÿ-°Z+&aW8H¹[’O0ÙÿWë4êGÿ_§Ýioý[ÿߦå úfÿê¬òSïæ Ó{ß÷?ö~<Ü|¹ Xõ“xéE5s*¾5nŸ<ºé$&}¬Õ˜ ªl,œÈ|:¸:;å‚/‰Ó^BŽG—9=‡Ñ,_ .<'e¤rÄ3e¦uÄN¥xàÖwa¢•2À0NÇÀ|[ ÷/'Ï~)yBA¾´L$g²òkàºq6$]à%×=±\×qS0ǘ…@u(¥Fÿ‰ŒnvMµ6NtZJÚ€óõ·µ4›È´”»¼À­ea¹xV‡1ƒ] ÒÛÝ¡UÂ×rÕ8ãé6yqS‰®—æìCÏ5¸»§LükêŒáSLp ž¤oj'Ë<¢+.µ8µ±ÓpÕc¯3Ã#þiîwZyŒ5j=`- qý0kl³S‹/OP A¬ÙÛmÅÐF×ÄÈÍ•+!lÊÇŽçà#Èol°núéY4b7Ôr ¸ÙNÖ\·ùèóp!Tým{‹ßÜû?.vÞÏœ†ÿPo…ê¿Öíý{ÿß°û?Á“Ò©l(Tà=oöå¿ÈÛê}ŸÊ›A[#ªñˆ< áüH¸õ[”kÏ’ð"®ÊÙjÿª÷þ¢Ï¡…zgýÌÖö~~E[@üXÓÀäœözªðÝ?yf š\)V&Ïq=ÚsìŸPLsކ‡º®¥Æµ0Ý¥¶Ñ»ý3vŸ#]}á:_`¡–î ªÙp`Z8–8w¡yKwÅhµ—¥ÒaTŒGA¦GnQí™Í0 ï÷•IØÈx[X2`ÞïJ)ã7™huü(qÏãλ1ÝïdJüjiOA[,^˜Ö‡ˆ8Ûÿ‹ð 4 ¶|tð%lÅ("«© ”Ý9éâ¡-œ…ŒÂ€|oÏ+¸±NŒZµmÏ¿3øg´ÎŇ{1 C{qB`ÑpÅŸÃý±¦YüÚ¢36'pC®d“]ÎArÅ °¸ÜÍÄ”NÃ\ËAÓ¦¢æèÁÀw) ¤å-“oìKg´ÇnœÌ–5$I MñÓÑÓ­\~à{1V%l}þ®Í$MâøÃ$ ÛBn+wáxÐô~˜:w„úÍ:Š^‚|ñUõà­Œ#`K<~gç·ewõ ƒ˜:T|4eé¾»œö..~©¬=-¬¿ç›1 ´Ù#Z–Äžo’@ì!ìHx,ªÝÊGtÓ¿n"FR¹ö†ýÌã‘¶¶Ömâ€Ð:hÃ#+3Ф„)0Ú ¢ô]¢ Í>Ò†ìF‰QŠPúñÊ5EÌ1Z׬\B BFÂOÅ!‰&_†JERd€öV¨”ÀY®˜E‰«øøtVú?_Ãj»%ãM^’=A³ßr€î`ÄãÔ³$ øÁuÿ¦7,—vÓ§žu‰‘Çó‡ÀC.Ô n2@-hÍt*¹¢%Ý8,Ù—Fmz<ñ«™ysÝíá§ZÏz7ÊeȼDo€7^oMºÿõ?­eų~_á-½Å÷N¼„ý·qÔiì¿F­µµÿní¿›Vÿ³?¬ÜöÿíSÿê´_¹Ü ÇÖÆ‡~MÆã„ƒ({hNÈÏ™5¡š*Ä&Ÿ$¡ÿJ™¦Ý@ì–`ÓUÿça‚!®ù᪢íÊÛOW§¥Ù”_©hÌì¯iø`bNƒoö¹\Ç03S¥T :ʬ5s¬Z(î@TE¯xå3Õ´ FU)åBÛí£ºÌv.£\hÛDJu»Skv­´ª‡E®UåGÚ+1öÆF—`Ìd¨(kï[¨Jˆ²ÏaªÈW|Q]Îà˜ YÇò{d˜ýÿ÷©Í ^ÿ¹ÙlÕùßÍF³±µÿoíÿ›fÿÿ· Ø'‚[FãO‡ì›ß | aÅŠ¦¨ÊfAù(÷IÆW\íµÅ¬½0àj·[@s²-ùõÁ®^s8ݼëÎ0¥ÛA÷©EŸ‚'3kæ¸O'Â<ôˆÆsfeUÃì¹ÖØâáɃe85ØÛTj4VÜ—+aÿÒŒÉX¶÷¹‰×Z—nÜ*"zÚcäßYXá tu„V˜X`÷b4Z ätíå\š¬Ñg$Ξ$ÁòÒ¬¥ÜžXlùãÍàjðéVG²š÷xˆ>|ÀJŒ–¨µz>ì#-+“E2ášeO½ƒj6Ûò÷Çq³.M¶€ÄÏ Hü¼ƒ…+áj6¯`K CÖe@’ck G:e~<ïÿ”æÁ—£ ÐÒc®.Œàw\žë™ûPËŠùü [æ¸Ñ’jVTÂî×·ƒ ¨ÂaÉg‘iôÑKœNEaí„È÷V8ò;ŒmrþäQgi•ù£ÄKÞêî÷••Täß'F¢íe#€~Sí0¹\Ù v7 8h,Ü—ÿ1¢È kúL üßv­£âÿ6ÑÿÓjmý?[ÿϦùά©E -«“ìmºÿgªÜyú`.@–ÿãÕü_{¸‚msšàú!1zy$ð‰Â‘GЈcß‚$áG+\~¯èŠ˜Ù5<~åÅôUç)þh”3(M1‘ë8‚‚µ)¾ qJ {fpÆ¢=¤»_9 r›KãÑ2>ÏáüÀ–y% ,®ª‡h{`¥ÏÑè:ûŒ®µL¦?÷m\¼´˜å߇m3Æ }5SnZ¡»¤‡5&W,ºué:+ZÆ®Í.ÌS¸8“äÛŸçˆ÷ଦc95ç‚.sscµ0Ì Úm€ÏšNª†qŽÅ0AÂxYÔ!‚L§O$oô»±W‚³þE®³çW·ÃÆÀÜôO7g·šå˵fŒÐ@ 5Jœ_*n å£óhÁ‘sHåDp(Á÷ð3ÓE¦»–·öÙÈ)4#ÌL²1y+§å(8¾Í3pSâDÂ]Ýq]FG«`ž\ȈU¢iK!^›-Ðüï:îø¿›[¬”—eCo.šöáŒÙÈY sž,¸çAÛÊ;Ô*­*òêP ¼´c]ØŸ­GiŸèœ *s £·øØ˜ã1™çOÐ k×'âñÁ1˜GjÆGD ÔÝhÏ«ÝÈRe‘[™ò•p#Ë"s]ʇæܾüCx{­úæÿ‡P‰_ôþ×Ñòÿ1þ¯ÕÞâ¿nï›ÿ§ZÿyJ¾$Vˆ’ÍÆWßH)CyBáâ/ý››ÁÍkfüæ{Í+a27¢ê‹2¥$ö«K™ ýêÄP"?¹²\V¡³ø§ÓçÀr­x<\‰7îo1àÏ +ï’¿ZÌq³ÞíªY¸§ø° d7KÌž» ·ebF¡šY·“µòR€M¸DÉ,áO¶ ÙdËË(oŸŽrY"Gž^³V×O#R™}'!àÚ^ô:z¦¤¬I‡0$:y tzhVÝ“¼¯ÊDÍÀzf!îÄÄì:r »tÇB²‚8[ »ôáïàw×/5úÄÅŒãzÕ"ó×hÔºµ,•RR–䟶§—½Ÿìñ=ž#çóQuïàÀÿ^ 8¦@|ã¿dœàgzGÆ -Û ëïÇ©9¶g¶»§>€ !üû n{z‹¦=5@NÂÿÛs`â–xLkÏ(#‡1„Hoä!½Gú_ÏšÄÑ}»ÉI¸Gßd \ý˜;Zù€ü%y®lå.}‡·ÇvšæÌ~ÄPV…5Æ%ÿéú #̹'¾òáfp)ýóbÓ‹§Ñ 7nÚÄ<8\Ò÷×wß×.ðœtV®‹)'ŒsÙtå¿ÈÛªÂ_ä}Uß·çKׯFá¸r©ÏÖAŸ=W{EeߟÔ55}õ¸Ë§æÓS…õ0» hêüȤ«×£ñ¾ü& gÉÕ‡z¬FΣîïq9 ×ùÿz\÷Eç÷HN,s¹r-¯|Ó¶p½‚JÑ9#¶<}ZL*±&¹[ú ÙùÑ™3eÖÝ]€ÏêÐ3œ-Òó}¦xGÞz5yzW°3ùâÀTyj†AÝyÌm âƒÆ$L©Œí§àøû©ãyˆMаx›$W¹ #ŽŸ;ó¤ûÁvÕ¨!Œìß0½=q#>cyøl±$ø®"«M•ß› ÙÇ[­þeõÿ©ã,*Ëʇç¸$ëÿZ먨ÿÞjÔ¶úÿVÿß0ýÿb0¸þ:ʽÏRʽ_Š€ª`‘ðËÄ‚ïc§BàGWÀ òoŸú7¿$\ fæ"êÍËÞµòêëèÿ|R×TþuάYÀ=ivÖ¹)f¡Œ oåè(1¿ç„Òºû"ÁUoææÀÜçETatŒ]?Õþ…‰ÒDˆ†Ü.Ya4¿“μ|PæŒ~Vú{}±ƒ[%X€ÇVSú¬H ø„µ4aj øÿ0=ã?Ñnþ_)…Ö¿˜®†dÿkòã˜/Ëk?ø/ýfÜYhþýË=@·À£ÿ2þƒÅžÁŸ< ¿@–‰=xÆžÃ_Î$Hb¯N&%æ¯!ÿ[®2ÄÀ÷£N³±1eá“Q¯î)­_Ø´ã ¼«NÜ!†vû©Ùʺf?y ’9|b*¢ú[¥ÂÖ»LHé]Ýžë5H€å€í)[²Ê¯ó&ŘËн•·2§Z$2È¿T³›î +{T×) ¹š£¸:7Q9š¿Á–8ê›6 G% ĬqÄD¨ÌÏ‚»2óµöÔ‰X‡¡ýÍCQ‚,Ô.?d„)Θoè/ŠÖõƒ35 ü÷1w_“ÿ§Ä|Ç"·ed3Yh@5Ò^c\b‡VX n8XQvìû ‡,%OA»|:Ѐ¶± h€„PB™¤!y¦ç1²¹\ºöœ9ø‘>½IeGølkRpi~ÆV„PZk£¤eòVˆ)sin% ;›ÜÈê!ì9»U&A(A#ãF@ŠFÖßä,¡žTÊ'ýøèÔáI!ÚÙ¦%£Úœ«¨½Œ]ÕצïÿC¶Öïà:À`I¹!N-²*‰Ûà:ƒY-mÌ„aZξŒÀ–;ßM°G`eS éBbu3æ{BùûC¶€ÛŠ¡–XP¢à \[r‰›ÝàÖÇ"8”T“sÁó†xî5®úé,é[4¬¥ÌÌ',Œã#”2)³oW­ê¡vä²H{…Ì·8'?bæ%ô?‘¡l6F&Ïô’­¬ÐØ,óKêÎYÍÇbj}¥ÕoTÁpa ž67J¾#"ÇÙ} ?É̈½Ýïÿõ~ùñöò—ÊÙû·»û¤§3ó´=³*pæ.Œïyâ ì‡ »6ž`Aã›7Öï “Ìg¶ñ/hÈñê6û_C¯p¥YŸ•=žrÏÒs,ýfêÜïQ#øgþ=æÅfRxbìß[K¤…ñ(ê‰Ô‹Às¬u(üIPGxâ¥k°$ïÁyäí6¾¨yÿݪõ ÆáÿnŸý7\/ñ ™ñ¡=ú¯0çß ‘º°±“ÿþ¿¿÷àUÿ%¸{ß¼QúöÇßúÿß}TDzP"ǵ€}&ÖTæjOì"ˆÊý:üÏŒŒ?ŒÁíf­Vóßþ9ßÛøÓô߯uZÕ’õm½oÿ7•ß‘ÃUÆKézï­ùè´ÜϪ }k}žY3Çb9ùj5ÿxÇŽ½¬ Ù®ÐxOñ›ì”×úÛãNè»Io³ß¿ù×éò»þ¿}ê]l‡£”94šÔÆ!þG«Ûl×zõ³ÿÂç“ßjÞúpÊßâR‘Dü‡UEô`ÝÿbÏ0±¥(·Jº_¹øúÕO“ûÍøUæÆýfœûU$wý¦—£Œ2Jw®ÀÁ£¼÷›ÄÍ›RûxŒÌ%ЇEW=VãQ '€$ú€sbï¸/½ùØuΗ=L¾´??` ÚŽ{£†G‰š½+û³½4¿º+>õsÝYâ¤úÁ5j7{<¥Ü¹ãÔ Òa ]gé}~‚'ÞÃ!ë¿XÓ¥hSb©‡†0«µ»óýì;‘‡«€1SñZ¿©LæŸþ¶«pWIåöÊiP˜)ÈGbì‰øJA;Kç¸Uë*ö-tî÷'£ñî'PlÞ°Øç,ñ”)ެ<©Ð™–õ oW\¤¬½éòÏë·1ôô©šK‡9ªuŽT£ÑCÊ’ õÊ™[9Û¬wU_ŸR™ÅáÖ^®X—hþ||`ôSËóôö'¡#2šwH0ñø+±ìiaE^Àñäu>Wò<û_S Ù¡ép £ÔŽ'‡ã—ËL¿ØäǶ¼œ\mµÔû×-ì‰Þ+NA0±Q¦¸ÝÑÖø~¯¦øn™å†ÕŒ‹‚ÊdöÿÈÌs_ÄÕ÷Ó/q1¥úKâ:”/è4Å»×¥x­@”vÕéõÍùÕ0¥_åå]3 €=¥´ÞØÙ+Ñ} ¿Éâ]‘«T·ÞmÅ!] \~™çBÔ³DcÄs@áá/u£T±µ9^læ¢¾ÐÆ/ u)Å:’Ë¢[Ï6À’×·M×þÚñŸoy7ßß§¯Rÿ­¿ê×›[ÿÏÖÿ³qøOlŸP4Äf{~ÌÅší@=þé?þ§WýÇÿœ ­þ=*&ð…—àþ)¥AÕäËœŠçŒ>[µØg5Ö€¯_!Jö5½=:súyÒØ½ŽÏ'f>6ôÕ'ãK)s ú ¨‘‰¢f4´åî¶:pŠñ›ü…}çšv ½7£®Ðš¬¬â;>I°@ !œÕRàT¨é£)ê]páÅ.žŒý˜Šoðýâ÷*ÞŸé6q  YaŽ-‹ëbQ›XÇ…·f«ÌrÇ Ѷ]mET°\ea.ÞJt[f!æf^B|¬hj¿]yî·@Ä·²êÞxÌE¼1™š÷ž!ZŠU›Ž…™ënX,Å ˜0±mÇŒ2ÓÅœÊb;ú Ct‰¶ö÷*Ó‘û´Àœ%ømï àEy–yÜlÔëÜÀw®ÕäŽ_–p|°9”(ò Ʀ7žœ8 †–ð†þ¢ÉwÆV]ÐçÛÁîŽ_Á…MÕ \F/~Žf&íIdÑâ™âøzÔ~ÉñŸŠ—áuK†Š+´·¢¶X×Ä43ÓJ$¦ÝnækfnAÏ_hE®H‡4ÕÚOö ?Ç5 aŠú.ÇÈ`—ãñ|Á­a·ŸÞŸÜ€ãæ kÕËñÆr©Ù¯ø¦‹´ß—±*ŽZÝVýè˜/QÅu˜giðu€•Ó0AãÉ–bád ´tÈ^ˆÜ¡s{êW6ã¡SÏ\Å—®¬)kþÅv9A —¾gì{–þŠŠ*~@>pöúUM¢ÏÆÃÏñêûjN ýl ³œLã ŒI=¾ ‘äp<„©}vBt¾HDBpÃE8­oYÆ”Vì ‡€¯R ðáüZ”AÛÅ2•îÃÆÃ\VjÔ3Ð±Š— ^ n±|¢—xfÕ®dsi˜Êb`’dN±_ˆã„Àa#ý½1¤ƒAD,—%#s„•|õž$O{§ϯ~x›XE‚AUà/94ÖÛEÐ+7ý7ýÛý³WtdXëÌFñ5§ÿ ÿD¯W—"zËH'I>±JL.I›XJ6!›&ÀìÙjfÌW³;‹ÂöD¥{ÂYa /,‘ŽàýïŽ=)(?r‹A‘,”v·ÛÈâŒù0ZpÔðûÖ„ÕÙ$@@S²ŽXôH0) ACSÞô‹Yæ¸e~á™_Øm9^!¤µóWÆ/ Í}ÔM–×sh0#†î³ßì• Q 1ªW»@3jBÉJSù[L)*U h±Z hôÏÂ&œ½(¦¥ 1ÃØ%,ÉÔx§ÑLû®Ø„<ÌD½þSÞ”D„u'ä[ßÅ@"_xnBÒ*Ó&ŒÞr%’µÅ6.«p«Ým´Õд¨`DA™ª}„÷]X1|ÎÅÁˆLKi½Õʪ¬›bþöå tV0M D0^èZ¹"£÷Óê¦ HiIc[z7¦Z}/cz_+¥Ú¨¬¼gû`7ð¶DÝ~³¿OCû+ЊµX÷"Q¶ÅÏ>ž?ýƒy·œyÊ Ôûž=œ‚ç æÍy±ÓA<òŸ<²œWÐã#­Úh"Æ÷¥3–Îu&Ÿ¬;¤»âuûø¸QnXíN­Öîä‡Õîå‡ÓÆ_‚ÅR}-JMM؎ТxœÍ\*¾¼q7ù«6Ø,#Ejw¾îá¼8ñØõÄYaÉW¼DÉ÷K”ÛÂ*a¨dÉd}y])¬’ŽËg"ÒÂk²›Æ{Ç™Z&W"Z^T±ÜøZ¹J•\µlnôÔg¬’»˜öj¾5‹ñd¯]Ã6‡å>.Eo¢H¥Ùì†ÿت³Zåemuêèµüú¶³ù6¢¸hVC®¸}Mo@€¾À_9)†üÿ(6*Ʊt-sæ½týÏZ'ÿÑ®·Û[ÿÿÖÿ¿aþÿ‹óÛa”Êíð¦ß»ü*"˜0 !1`çߌñu"¤‰e_@DØ>_R €¢Ñ†æÔ‹Ø©øÖ¸}ò@}EÏÄt¯ âÉÉœîÿÐÜ­[ë38#eøøƒgJ‰^þ༟ÿ@Ü$zaùõàÎuÌñ®ü§…l–d’”»ƒî’Ž|FìúSN`@§Qoµåy›³>è’!ž×Ÿ^¼*(0«[Smn¯íUp+ÝŸ7˜Kdɉ3:¸¾`Z(ô™Ý½“ O<2!C,H ¹ý_«âšªx2’Ç,Ù0÷³0ˆÏ"´U·®JÍU¹›ÊÁ穼š©Òi¤7=ÖÛœÛEÚéÕŽ:‰.Ò’Ì3ê;`¸è–‚Zd9I. 0ô}œøÆ fë‹rnc’612g•æÀÌ9ÅF‘û˜Á]=nÎÜŠuy‡DFyÁA˜É¹dÅ®¬ò˜Q~¡ãPgöÜòÐ]HÀ¦bȹóÏ]¨Æ9zºåùHhG¬Ø£ZΪÁSØ8!³"ñJ¯%J¥ñIÏfkqÿ›.¿»eë·Ç˜ï-øõˆžH{ £Ôíªu, EÍú裮‰Œ÷<«Ë÷Å]w°  r×Iªè7QÜFšýÖ•b)M#fc)Ì[ë¨Ö*îŽAä®Ì®” ú /cf™êìà_—. šrIK#«¢•.. £n·þ ¥RcVZ†%¶ÖBÿ3o¶¬ ⸩y޾V_DfûGQwDÀÚURµÏ,ö‘\>‰ÐzÚ·D´ùm‹Ùõ'Àÿ"½“dƒå= XZýÏVû(Xÿ³ÙÚÖÿÜú6ÒÿszÑ»½íß~%Xßã,Xß µ“ÜB®³¨|±­Ç ZR˜ü¨M7ƒëÊçýŸ*n—Œs)ΡòàÉ_Ñgä/‘uýE±,.ù;¹¤÷Z%7µ,g? Êv$ñÉòH¼f{dÕÇì9YœdXdN¡6mí–W‚SˆÓž×!dåªëçÂ-€õôÜ^$9œün$`oKKÓym7’•ZÊF¡õBŠ“£ré`9¥%·“z–鎪Æû'aˆMŽìgiqz='4™PÓdÍý’CbN§b#Ty‰¿uœ‘+&"~•ùðuÖ¶ˆUŽ`‚x5‰¦È¸ãÊø®"¼8i\±D ŠäÙ“Ñã%("˜ÁguwIß!5ñ)!– ´á§%êíÍÑ[Ÿ¯º4Lcë…ÈÍJšÜܾ°öQç¨Þmeò…ù©H¸È…?"-§ü@b®§ó‹eÜY–jã)ŽVS–£XÀ\± l”tíÍ¡×H–ìÌÜö„ó˽‚ê.óˆpY¹·h~A ´íÆåMž”Fýâ 9¤k‘*GGµ£N7¿ ˆ/ÝAð ½'ïäD:ŒCwö½ï©I|Rd¡TxýN|†–þªòF†§ÑõjΟr´/Hc.%Æ NˆñÍ›ý©9»›ÆþèÀØgì™Zó{PV÷™ |øßc¿Œ&ü';?£¸”CǬp)7‡ŠTÁ8:jt;iÙ=;d÷-´à[Z7ÙÙ¶S’Ÿí'ÚݪhõY”£î< ¾$'Œ·Óév3;©Öàk·Öl$äyì<«ó¸ÉîŒQ7òþv!gwñx/†ÚDùþÂöQ·Þleshl´?#Çý|$ãi©îŒ”Ëy>OF„‰gœ…*ýdÿÇEA¦V“öÙ.€û?ÈÊzÿ±]k4·öÿ­ýÃìÿC%S{¿Ñ~€"o«Vþ™¹¨Pn­ÞÆeïºòoŸú7¿$Õ¡¸· `ñãJ†½›aexÓ»ºíÏW¯h¶™Ù5Í÷Þå´ÙÓSÅ }D3¿ 5Þ™`e‚Ù®GÃlަùEsý¡®+z1d-`|ö|é:¢ÿB7+Éë °È;nOô‹]ðê )˜YÏŸ-L²Çÿ/köŽö’nYb±a>žÐ™RÀÁ7ÙÏTŠLL`Îg˜2ÈVaÖÝÔ}ö)Ö^RÔ>Æ9;Sê =  ›ßÃx áÁGYAy$ž3WK‡µ×0¸ÙÎÊeê6)Ûêæ5Y–p}voÏ+¸òOŒZµmÏ¿3øg´(Ň{ ë¨ç3lu9OçsFæç‰µY8R9±;*bÝ;Ä5 -ê´}Œ"•û½OÃÁéàòò|hÌðú´ïYVLéO8E*>›ò¯?¬øMÅÇÖiM(w±q5:0À~„^TÈÄüFJã¨Ì+¨ci 6¤+wñïàmíiýó==%ßµa${TX–»Ú†t8ƒŸçžî„ó]7ìÅ õXø}1•,7CL`B”­ @Ë•»pHŠýÿè(\ÿ½ÕÜÚÿ·öÿM³ÿ8¿:«œõ†½÷½Ûþ×`þçyŸ6؇"?ô ÇXCë FÛãíæâ`ñ]A>¿=\]õO‡  .úg Æ›÷ùwËÏLFX¿`5P¦zçÿ§/™^Á5÷Š®€à X×ÍÒœÞ€Ä ]Ç©`<Â;Cƒ0½<4JÕdN €´]ºç´µ°Ü´6˜°þ^¼-P†èS. -­±Ï'8wÞ ´, !ëm1 žVçªÔúL¥ ÕPs#ÍåÅàLn9Ä ¯$Ø™Ëу¨ÎÙ’AÆUëh`ÿpq¹oîøH ÈkÅÊ”ª…¢“'  |e®³ôÇl•/b™¦:!‹…ŠÕ{PkºÌ*ÝÏ­C6œ¬™C;~Dù:û9$\m¶²íL´ý²ÕÈ Ô‘µ¦8hÈ«ÙEåT#H µÅе+¯³¯lê©òаÚaÀ‡‰ãSšI«¢Íø¥»²©ö.‡ŸWZô‹»ît‰lgg£Õ=îär•jŒAIàñg¼ÙßCð¶=.Ï–gÏà7þýs`œÌž¼ße©iúô[þì·ôÈî>Ÿè,i—¼@ÛwCæ‡Êå/ðßú¯ÇúV·y\?;=û/ÂÓÑÇd„=¢I4'qdŽ•Á—­çZ]Ž n' -1yFaÉ·òÙ0CÛ 0#ܴ‘ëÁíð‡›>²Åÿ5À›ÆY#7oBÄ'®´ƒ-fÞ¤ŠV¡<jã?ÚGÛú/ÛøÃ뽿Ð"Ðþ¬ùŸ/Êjcè­Sú±)©Ð ÔFàÔÈHoÄ}M0¸à4¯åâÖFf{†&¥Œøýd)1ÀCŸ#‰bA'²b4õI¹T§¯`¯!E¥v´šãn»SZº§Î«lÚ%Qw|õÙ¡­fíè dsz ÞdȺë0{ “R¦§†ðÐX¯(Ò­?0P _?Qr›ÕúOŸÕú^Äô”•ÎÚj¶Ú­V-1ø#IÔ²RYl½3ˆ¿ ÉŽ!9fÏs›y7¡é-8¡ùs3 &½ „I™úÊ‹Ž‰tS%ãÕúÜÙóõRH…ŠÎyå­FÒ‘;áuW˜?|ªsÓ›”¸•ø*¨ÖØ•?²Õl7Zjªi7®~€¿Nç7á7Éw"ZZÖ³ä»B/˜=¶ù®@Œîøzæ|Wè¯Û>n¼R¾+SF£®@¤ß¦eºÒëEÓ\#ú¦¤¯äžýW ô›éÚø.)G‘½\FÂd«Ùi·_Mõ ·ËÈTÌt¿Ìe¦UVÍ&ÔO÷m_Qn¢¬ÿ15aÊï# ÿ¯ ¿ëößf«ÑÙÚ·ößMËÿ âb }àõ„þ©ë‚,]` t-oX¶5¼ùtuŠòP8«’ÌÁæè+3„¨k[^…k”z£oO{§¹nD8µçýÛÊYÿCïÓÅðíkfæ[kš“c8ÿ¢ÕER§ì5ëŒàQÆôº|SZáK-5Y8½1S;~ò#Šk>š®ÆXËœÓÃŒ6ööø’Œ|«ÐGF€ùØ[S‹þp­\y<Ù 3ñè5Lø5{ŽÝ¿EùÁ—ƒ°‘-³Þ"â7+§LÆ.-Fâ5^œªØ¢G_´aÓJCÜ\ÊžXj3ó £ã=XÇ™÷&Ô÷ÈKIDq#VØ(î"B/(We¤Ñ=pz‹žÕûêÿÜ?ýrñß{Wg±½ ÖS\ ˆÖm¦¡(¨ÛþER{E¯øÒvý܇þ°ÚÍ¡ZņJ5 5Ì]±eeÊaeQ±Oì&3LȰ`ج“[¥j|°1,ÿ sgðŤ'u[íÊ:Ó4Ar…a Õbá¸< *æJìDU¹:T’ׂxMaO\‘•ÔBZq}ÈkþW‰/B1ï®Ý&×÷ $ÛÿkN«­Øÿ›ÿß6ëÛøï­ýÓìÿoÏÞSBHå²÷såÃMZJ9\ݾýÓŠœ!{ƒ^‚ÖzžCsþê¾MpCHmqi+O…×4÷§.ƒ5 ü1|ÝTÀè™*#Z<é*1vX+Í3#€É¦-Û†ùåžæ’_}B+Á¼ƒ»AtžýwŽÄðÜEÓýÐ8oºc64BüQ ytîjSÄet•X CãI pŠ™úcÐÚrÙÙ‡£$ÜïÉ;y›´í߃"¡“@˜au±]¹–ùqS‹“ A hÑ×Ï ¡ñR™ìϘ°¯¤çŽÛ„É@´ÐÈð½çÞƒ¡]²96‚̪ædrgW&rY"tÏM°#„´ØW7Ðý%±Ì£'˜R#ÓâÿZµŽrÿoÃý¿Ýj4·÷ÿíýÃîÿ*¾W¥s3¸ùJîücÛ·åš9ß·OÞÒš%Ü÷QL`¦""ü `ͧÛþ cKRÝ_hÄ×ïâšò/dJƒ¯sÛœô5oøQœÌ{½œ½µÊýÆÎLwûðSâ>ÖÇ ¦Tô×ãIÇs-‰ž”O݉䄅ëÀÍg¦¨'®5>T¦SéÁ é #”œUÛ::ÖP’¢SØiiOÑ_ĹžZ %îÌ|ŒÔMN¶Ïvq_ø®YjʨœëRŸËÆ®›|6¡Fp„áh[&8Sþ¿êÖyéüÿVë¨Ìÿ?j4¶öÿ­ýÃìÿ˜fCâåOêWBÁÞw@ùŽ2ɹ™9‡£—Êäx0P5sÁ¿Ã´¡WõÔ ‚ )›—b ž¶däöÜz”EJ•y”ô§"ÈÆ–pÞ ÉYÛÈ:döV® C6Lf€ÝØî$ˆ6ƒ¥õ«­éPÊSÁ7Ë+Ò¡ÚqV ç‰hzªõ쇂+lô‚wCÜñüª»9µ §@}`8U@FŸ¥4n°z+–†ïËŠÙY úúe|E©åŸDù\²îΗé2– ¿§<¬Hñ3-Ãx=Ìq€Ç}éCe*„ÉeÌà™˜7¹‹Yô 6)ã$7[ÕbMbûÄ jÙÑ}gqJµb¼á¼yôñãZ³¦ZÅÓSÂâ)\íþÿ|Ø?aÿøU>OfÖÌqŸNŒÁuÿ k~ž~xßï‰ §R†oð¬Óª×xƒ!€-à8Cº¹¾ic(×,µwN1Ï‘¹\ëŽÄЍ¯ÎA‚â‡Iãj¾IïÔÝŒÖ%¥gäbAIy0Ðn«ÞÉÝ»‹Ï„ÜaB£ä>Fµ¸¿Ge3S‡]N|M4âiq„ÝñQ½±M±y‘š˜1eÿÂÝó*x¨à •ŸïÓ<®·ºj¢Ù× ×× ¸)‰:i&Â\®Ã8Cñ&8Éøü§qÊüŸ¥=³œÕòÒRýv=˜ÿÓlµ·þ¿­ÿoó†ç—ýÁ§áŸ4ýžX8® É G°û—׃›ÞÍ/™&pÆ& |€“áb#Ò‚s^BöO$#7"(4'eeÿh'LÉÉ?Ú eÈýyÔÌr¾Yiô  ²Z^ÚÏQ­Ûhv[/öS ¯.-ÏDk/còÏ6ûh›}ôÙGGµãz·ÖMÁ¡É“td©¹¾sW ž–´p¥(^<K~Šd#ò» xöb9=žÌCW×WgDE/£umÃòô2YÞr§è,²’§§w·)z¯Žÿ¯‚/¾týßZ»ßéøÿÍÖѶþïÖÿ·iþ?a¸þÓ¥ÿ•Ò Vò·Xé€×q*Ó¾¦ç/˜³! €q¸Áe€úóÃ¥DŸ –EGß’Z.©ÒT–j:-Yõ•óÒ+ˆ¯pvºÇõÖq§Vž3PKÄ!?JÀ’p¸p?Itw\av¸¤G×uËtŽºGÍãf'ƒ[†Xa{"6ØrÙ'~QÍç›Xž"eO¨õ2|õàžëÚ_ÄåÊ[ÝQO–o”`Äbí4œʱخډqåÈ¢Ê,%ø>š6,¬[6r-sù ¥¡«ykË 7%2‡¬ÌuYKîQ-t(o¯nÿ$ø/(®V.éEVt»BØšë^ Óðߛ͆ŽÿÒ¨Õë[ü—íýoóð_n‡ƒ›>¦nUnú½³þMåö—«aïç F×B¶¯õ&Pó¹~l!X$Ü1 h:}ªŒátÂR !Á,,Ú»¸ø¥rv~K%4CüK¸)NlŒ²šgéæÃ9´Ý¿JèâµàdÒ–Íš×ʌӑó²³,Ö¹ff˜ÌràgϳRAi§–.¨òwÃÈ2¼ßW”êìÂÕÂZŒBƒQÈj/{î6ŒícèÖÒáÂ/œ—æÈu Õ`€\³L°šDN §TXL!˜˜z·ÙÔ*|ÅÂİR_Õ||juÚÉwÖ>­cv[Åí¡Ï#›Daf“e±b,eBâZW2òdÞºLŦ<Ð.M4CÌõœŠëŦ fA¼°OBlûê|W©ŸêÏ_Œ™‘ªñ^Ï›ÇG$Ö„6užhªPþy½ÛU66ÿü/0»5šÇB¢g[,â|M]4±uf3gNmp¼¬9Ö¥çõrÛuƒñÛë…èU3¼_hu–MC4¾ÑÁ_…oÂE Z«ëû ^sùRåÐøEÎÖëPvü—ë,*þĽ4þ{½Äuµ¾µÿoíÿ›ÿu3¸®œ_õþLý“ñxPäø×0Lj4ÎðÌg‰°æü~eÞ[Æþ‡³³‹ƒÛ?‹K¨DÑRzØg J°èãÝŠ½n¾.Îo‡ìõþk¿kÓ¼¦i>Ì­œVøìs¶Ža><'¥„~És¥Ìà/9;d]?ƒ>TœwÆé2€ÝárÑiuJ³•ûÜê·‚¼éZ‹©9²¿{sNƒV 7£€à#Þ³'•±cy•¹³d*q(ïïÊò”YŽq}S»Þ¬5Ú›ƒœ™0k xš]B ä×™p› ,v×HÁ쎊9u(å­?¨•@JƒáÖg7Õ¦Ám<Í—•”6€ŒPüJz¡´ã àœ`û¥/qëf(£µj\Zæfh²šÊ”J7›ûǵ‚õظsÅ5¡…Qb_1U”ºÞ†{@+¥š0ŠOÙRÜ™•g÷›E«ãÖQÎõƒhÜþp¥J+@„¾¦q' }içɰdy"+‚u²«fúf‰~|°@9ò¢Ÿ³¡i¯5ju Ç›ýP ˆ#»pÅXeç‘­L‡û>d›:L…"\—ŽÌUÚ«¬T¶b¬sñ*ã—&¬šõW”=µ—O–›6.Ÿ@pÁŽ;juò`gï<¶²0~8Îoîz¸»ï/ö•qš4ƒ/@ñVr›°‚ŠàaûÇõ¬~¼ÞœÏZ‹a$ †P‘WPñjµëíZ§›Ò:—À)DL£¡ƒªçƒì휚ÉCÓß@©:“ì.¸è'sJCÃ_4\¯Ádä®ùù.ÕõTïÂî´1VÐÅ™$Q—w…–@§ÍýlXÜÙÌ ±¨ÜÊëE\|Ùl±Ž;åõ½ëb0Xkºæqø•ëX ô&Êp»µëZ·“©êpñ…u{]¸? T0ÕÕ>óµ<¤*— `(˜pFˆà<ƒµ1JÐùÇé»>Àêv}`swYìdE}t¾!´]6KY¾ÄEm€ïM•l[WÛŸÁÿçÁusO+h¦/ߘ–ÿÓî„üíFkëÿÛúÿ6 ÿ½ÿoŸúW§ýÊUÿçáŸØ(å( @É¢‹Þí0 ýÝZVd3 Ç‹‚$î+²¹ëÁ-ƒ&~E$øÀ쯋fâFºfªdxõì)^-òžÏAÉiùòÒ¬ú-å¸ÛÍÖñqy©6£ž×ƒXȱW¼à3pª[k6þ‰Ü{b®^ÜÃ÷Ïî ËTH88º9¥4Ü[n‰®©v«ÝR³A"\S¾¼ÁUÌöŠ.z´¥ÂƒvTêÞ€¦ò- FýÛVâ·íÄo;…¼ íÖqWTHô.h©>Ñ«"ÏBØõ!³ó{(ŠÌd»¡Ge$8(Ô#6R P'oJèü-d`¯f ÜO/UZˆ­n7¾ÓOöt*ð^Š¿µšhÁRÀiáû¢}O¹ñB ì¨Ói½’ÇA*ƒQN¡]¦ùD#E’·Ð.M…À¥’ 5PÔ÷!Þò~ Rü²‰4Hùí‘J~ª$ÔÐ:Ĥ]{S‰À PðÒOPDƒ¥8‰Úö‘Hí$ÊsÕAØ÷çrËlvÉØL–‚pŽä´äòV·Ø& XGí´¯Î_Âìÿ~mßçè#Íþßé4öÿf£³ÅÿÚÚÿ7Îþ/jCÿÙП#›»é‹êô 8ÏL Öæƒº´@ó}MÓ¾˜Øµñ7Ý9jJ1ÞÓÁQ¦Õž&‚Ìõ×®M`$ÇñJ‰wXs‘sØ+¸ºeØë›Çõîq£[ž½žx#´W²¼‹@àÄËód5>{FMó¸QïoNFMpÐVÝ\õ©eRD.©ýó{Œ!gޱ õbŽÇü¼0f`&5”õÄ!Ÿ9Â3JÙ׫Á–×°#Ã<´ª‰#ÂŽLÁ‹Ø Kߦ6}ŠÚ¢¨qœYvÛÕYïæ¬2ø4¼þ4ôóÔ ÷ éÐ’ÍÂFtƒU>U, ¼ÏÌ6¯ÈJèdc8pmŠÁ ñÂ2Ñ-“ÅÐiQƒñYP«ç´SÓ–?ØÝe§5f'F£VkUjJ½iÔÛ'µ£“æñn¥àDÂßH!Óð¾9;¿úÁ0Öê“€5où-Üã—ß.,¯_hŽž¼ß§zŸs{ªFèǾ Äå½k©ïçµâ9„¢|5ð‚’Ò4¾ñ¿5Œ“™Ëíé$Ä_èÎ^Z±¯æ¯X9Æ2mítá…û)I]ý3x :n ãÇóþO·kp¢ü(~=â×Ö^—ëµµ\Z,¸ŠãZ,¾¸Å¯µ@‹eÏtN-¦Y;êt3zÛ ÃË#ö_-›ŸkN`,—ÃÌ;n¶´„Ý·¢Úh±Ñgóµ¥¥â+óú‘]1ûgòšïmˆh¬€‘=úêÌoº)]Ãè‹ìñìü6­SÿÕâÃÌS)ŽŽ·¡¶Þ¤›c ίüùOœSHvb,ÞÙ1­z§– 7·!7©ÔÊ×Rh%«Ù"—Aš­6À‡°€½‚÷€ìÿ!õ¤\W@ªý¿©Æÿ·ÿ¥Vo·šµ­ýkÿß0ûÿ5Û't?£}²é®s±°æc;Ð@úÿéUÿñ?gÂhò^T:Kpø’BoÒçL‚3€njú{”˜øŠ†ÿ¨]ÓdQN'@Úä¬ãP& €õ_¨D1v~ñ8êFÚ÷(?žp²GSËtOà±|šUèèaúUļ ž•Xékd¢¯©Ó§jy­ããVMhyökº6iyͨÞpzˆXY4И[ÖØÛÝ „ñéá)sG5yó‰C£íRoûÛMm ¡œeO‡†gcˆŸn‘Ùl5G»¸…ÀÆ ä¡Q˜²¡|Ui d–\yhCÇn«;¸®=`&±KBkü-ŽþÅ7®³t`ŠƒÂhTk”Él{†…÷,VÎp:5¥÷jf~Æ—ô¾ãy¶À7YÍÆéå'ãô°g05‰IÓF¼"ƒÉ6|K"⻜ŒCz ÇŒð=ÀÌáPŒÎ TûcÀêËZ š°Ø Ýß¹‹.n•à@@`´(>5Ê|lzãɉ³ÀÓÃ2ÞÐ_SÇWœ…ñf4Å-Ú-»;ÜbÂ:Þà+Á¥X–, Ý7—SÀ)¼h2Éovx5K€‰u2J|çy'¤Ûiñ«¸PoU¸© ÓÌDL+‘˜ã¦HúaDthŒ$YÄþjZ‘ %Ò˸ƒ7ÉýäŒ4:æAî»Ëñð ¤EŽÇðb„¢ÜŸQ 8n.È·Œe~c¹|RŸ>à»2ÒîXʪ8j5;ÊGñðåX/â… ®¢/ì9/Vk«‰M6(Ál&¹[b Qîî°÷ü=³.lº€áG|Ьg [Ö8ŸÓK¬*. (ÿpC®‰CM¼ ÇÓÏYã‹mÒ‹¦1<½V8+Ó{û‹5'ÚèˆÁ…VåéŒJup sù€C8d€h0FüØ…NIh†GG+¼É\Ç}bÞJ~¢y •o<ãÓÜþ£ræÌàz‰ I b •7ʨåžV™½A~TwEÆgª@ä²ãÒ¢ñóÕìy‚µ‰Ç‡Œð}ƒÐgr †«qËgÿ iÍœ êZùiw)ëë––”¿œ„‚¢f×ùÉjbÈ¥¬ã_×¢4(õrЊ¯Ê™„?…&b…3¹ä³°yQR6‰s¸ä»O \H¢)1ïœâ µ\Ý•w´ð Pc—Ol%³nì‰1wüöài¨®tΉ(iÅòþÂã§­˜!’Uœlß+©síV³±Ö€"N²ŒS:Y¹ã®àï™@ôäТDZ­34ÇÒƒ71+]g`lÝ­îïñÁœt7àR.™üPØÍóhšG­v«-”;aýÑøƒ7ÇüŸnŸ(bÿ×-M%ÿSl¹LþþÚÙ›?™¼6&O€Õÿ©„xhUpË‘.Z– ÍþÔ âÿtšÛúß[ûÿæÕÿà~ºÊUï²_ùp3¸¬Ü^÷Oÿt š¼„-¨,JðÈ&ÐöÓ®¯×,;Ûkz"Ø·)™ÓRJ!è¦Ìª Ñ“E™7>ô†¼:ÒõŒ_[FŽ úЙIGuv¹ÆÌÌÊÅXÃí–I?àV·GÆÉn½]oiáX©É;ñˆ¦ÑÜΆ²Gå.Bk'WƒÈÅ€\k·Z“ÅÀ»È„†¸¥uh<>8­ÏÕødîÎUæþ,¹›…BâQïF—3çÖ¨,È ¡9ª–:j5rÔšÛA Ür »jU S`â¦S”m=EPÀ÷=°Í¡k©©Ë…ê: n»ÖJ®YAv”{.5Ķ5–ä03cÅ.·ä™úàB^„ˆc&3|7ñD†ÊGg5£=‡ÅZsœ YôpC*"/*nH{ IÍ]f¬ŒQ¬ÁVXâŒäš= k˜ H .¸óæ‹\WÂN¿§˜«Ÿy4ŸWb‰´É/‰U¼)ßdéDõŠUPY®²ÙîQKüÏq#ê7û{HhÚsëÑòìüÆ? Œº` °#úô[þì·ôÈî¾°¤fhL“¶¿ù×éò;RW+—¿ÀOè¿2èÍøV·y\?;=û/|<0&# Ô“DsG0„D°Vz]Ž>†øVÙü·òÙ0CÛ 0#ܴ‘ëÁíð‡›>²Åÿ5À›ÆY#7oBÄ'®¼A-fÞ¤Š·ˆ<ª2³’jù HZ´®Ø+œ.ó/ÛJ±–膇vÒ´éïNòB¯¯a¤†™…µžl¤>Ÿä†x>,©ò!_%°Z–ÙÞç­y#g!j’ûBàÐÀç1ñ'øÃÇHpHïÀCRäíuoÎ À5: Ãvj9+åêrY3yÖM‹¿¾ýÍ8!c6¯–;±­é˜.a^ÈÔ„ªëRmS­‘ßß¿=bYÁTpwì'dàæ=š_* Óv=ãÍþþ¯w¦û›Q?0ð·¿ÿfì¸wpàWêÍIöþ~]´±»/$d6ª‹r©Š?Lnó(kàSu©ùkÕ_¥1‡ºïve=géhàá¹ ÀLŸÈI%lN"Ê[mb ïɲÒNþËBtAÕ­æ]üíãZ+;òˆæBÄ’tQŠŒy¶›ÓÄÕÆ%ÕD2uè_3AÃjO¡n.qû~$*G‘µ½ >à¸ñ^6T%ƒhs¹æ§^k´ò$¸%ã2lf(B 3ý)*¶"™q6௬=Ùî£é’0•<þ`Zg\=ëY[B°®ƒ.¯ÀÑ:n´´Þ/S¾ ´nñÃÞÍP½ŃÃÇl€|(3±·ÇwYV¾jɹ.ñ“õf PbŽÇZbëWçs ÿìL£K\‡*ƒ¿ÆÒ˜ØAÁÂæ s|ÃÓ…8ç½OÃAÊ´éM ÎøeûÓùðc¦Ul¦Œj­ãf³Ûh}ýÐ?ÉFŠ¢ÖüФ•`ÑÏnÃÈWj™ñXóƒâèµÈþo‹4vlÉ÷¤<»ý¿ÙhíÿN½³µÿoíÿfÿ?¿:ž÷.ÎÿÙ%¼q®€ÌX}ñ.‚LE^Ç)0Ík: "ø¶)‘ÿATÀ¼qÇJ‰Þƒ¸©âEÿ^0j¶”‚ÝÖ±껦à Ž]¾ç *Îúëò6»íºI³!€,aæ!|4Ñø›k¶x^§W ÿjvR=Hº„0hÜ-–-AÆE2SM]8WžÈÐH¡…r…±ø³‡H4TÇ¢&½U^ѧßóý!ðš`¯íŠY›µ%­ŸW}0ñ¢·JÊ!¾Î#%Op<êXô, ž„É)|[¦2ôa²ä¾ü½Šˆ'ê9w„¡,ð+Á®Ç$BŸ ¼11Ž< ² €#úúkUŸ\( "j[Ðø¿fz1–ÓôPÕpÊ‘`>ƒ–@î-ÉpÌ ™óTO$ÈÉž‘‰` ~ÆÇÂu@ÜÎrE‘v;õV-WBÒÜè®›åĈtŒþ® èñ`£GOÙÂÆ€ ã¢wùþ¬gìsòC÷øÈ ºøÏq­ÎþiœQoE傼w¦>#f¹Ï¨>H"»Hs9ÿ»f½™R€Z;å2 ¦A†÷.'Ké‰@Iª”Xͧˆïd/CÒ$ U({þÅ™~AïÖ“€.‚LgƒˆPøªÅ¨'*Ò€˜7GÛd!Gõ„ííý©ý™½^½¯*wL@ÚÀv%¤ÀCrßD}oέ%H³Ïô5Áò¡×äа–£ê“°yÂÐñ¸ÄµØÎ”rWlËb'ðk±"„F]xÒœ”!@sЉ¶^>*ÂXZ¼y~)Âæ\+Iàñùà㻸/tr¤;ȳA6ç#g…7@,ï´rÅÉPÇüµw¨o™ù$ S“.we®c¶E1rÀsØeam)2±'Ëž}pÆë,Ú5¤5pÁ"×;.âeYæU±Ö„‰2‹,ì‹Ë8çk%|‹äJ¶[ ½.C:½È§£žr¿3~Å”\ñ»53íéo¾ŠÊ3Æ¿Ñy²¬ßü/Iùõ{ö¥=þͨ׵’ð£Sée'F@·‡Ö”còÍ>ëиwÕþ¥Áü®Î8ö $ÜþýÏ@Íz²ÑÝ?7ï-ׄ;ç“÷f¿^7êÆÞ/+×Þ3ö~0ïM¸öÃo÷ì·ÿí9_lk‰Fõ½¤ž¡‘4€×›’ýýLC:8(‚ «Ô/”† `\j6(DÐfLŠ‘To*IÔ͘Š— ˜¡“£f£›;Ÿ¼—?Ñ‘1m_Æ©ÉۉŽ®K‘iåsi†ò³¿énUàf„—r-eà®-69Ð9h 3^„ÿíZ§ÝyéXšN™¸x½‰B12S+ކ³þE? z¥ä·aC¨wú¯68»ªh„Œï,!<&«*_NpØS¹‘2ú{¶pŠÿ²ªÌ¬ßÌñp¶ÔBñÛüßmüÇÆÅô†Ã›ó÷Ÿ†_OÖïdfí üh´:µVwc?‚+#£ãy¨´N Ӯ̈°=¤Dçshæ#\Ä›¼4Ù¡]’'Ú&Ý2—P}bN§A닄Ƭ2‡›/^ºË[c顱‰äæ0>Àk>vÜŠ(CkŒ®RåMˆ"÷rQÞ–¥uo¹zN¶lNlußÛE™žz+™¢OJ*Ûe “š*oˆÏò<òŒ¼†”×cZîx•v££×ÔŒˆWZ”ÜjD ÚÐ7'’l÷)ú×n_Y0Ä%1b&§Ý¸pÀL9XØU#בÃû°½ ÊÝ“ •b´Î,“TcsØ.9¹9/„Ï`/™ùÝ;4f+oÉ#L\Þ&ŽflXS/‹£š‹qb>y XyX•N3¢(’DÚġ·¨!ðf` Œú»§œ”äî¡\`–k’cç|ª&±+ÃxçÉ< ˆ;½ ~¹7Ý1!È` Ö?‘QÕ#À”æoÏ'Ž;“U7ÉýïOíPq<9uò'ϲC?¼[òÁb6vè6V>‚4ˆRtÔ諟ÉeÏ@)-|ßûæ®ïƒR¬v ÞÞ7ýOëœáíÆQ«Ö͇-¸J§©ïZ•àçWÃÖ¡ÿƒåuhÔŠ8BÂv»ÕZÔí½tŽ²ÂŒç«…ˆéÁÔ^cðÇMÍ×ü">?ÝÔ“h‹÷¸)àö+hÌFk® G`»ÑmÖþ€³™"‹ûÇåùó#syuÓõ8£y¹®@òÿ±âßÌü 5Süíz;”ÿÝèlý[ÿߦùÿNoúè“§P?±÷¯ä¦UŸàØuŠòC}n׌ï¯èÿ LÿšÞ¿ÀÁ¸‰~¿àl”áíSÏš}}êܧï”úy–¤îN·ÝjtU,¯5Ýz*O²¹òæ4ôì9Õ†—ßÿéÏK~…Œ®iÏ—y»•’Þ³'k7ºÝ£®UùÊ>»àœæw×½ŽßëŸÝU³y²æ$—Èé˜M•ÇÏèg‘°O^<:n‹g(RSËœ3£ °] «`Ü(†icÈë"é4:5ø_rJ/;~<錱¸õ<ûÿP+x‡ŽwVìÎæAì2ãýÐÏ*Vgï™=1›Ê÷_ð…úøà€„°°+ ¥ÇÏ=‘«+MA¿Kô$û°ÇPª¦¬²…™õÁ`@Þ2î:±pmT+x4bš¥ó´+Õ¿TÉh.°‰y:sFh~4ÓO‚ógÚo%€ lpßåBý­ð“ Šæå6,&Ð;LM¯ˆÙÃ~á¿Ô݈™çó¹sö^,]˜RÚ3c¾þÐ%è`2¼Ú[kzý¨ÙÌ i½¯*d¬Äh@aiT4¯s§s8Ïjÿ× µëߌÉÔ1—Q°”¨}>åÖAÔCX± WþoÞOÕÊ«,j_˜ì•±ÚØ…_ÒUxËOäâ?YÍíßA’ž(‹ÿ .õ‹—ƒå´‡I¥S"aç¤ò ®çóNÔþfïÓÕù¿}êûÐî!´—нë›óËÞÍ/Æ_û¿Ðç{™É.à3uØn§!sû©SámQÀ]ÄñtuêÍðº1ÇÍ›/ó,Pò3×,“Æü´T­:˜ò–Ì©ÔÔ7xŸ×âðnô ÍÎw!‘Új´_Þ7•Á8›&_-ꌢ—£|PÔqŠë‰½\ k] é½³Œ%hG€ÞD^/˜þ£ãv#Íë…JzE(kª|¬±@%™ò>¯Ü%s˜`1Aݶ&)±„Þ@Ñk¶x0ÉÒ¿#3­~«aŽpkî‘"ƒì)w˜(.&R…5 Ê_ÚwöÔ^>Qeò ¢WÝd—dš}t#œ‘Y,¤ù»3v7À=é Þ-œ÷׌ÿD²ÿ—õÿ¶ZáüÏz³µõÿný¿›æÿM)¾¹Ñá"okˆßxYQŒ¦¡²£éÊ ŒÕüº‘µbµ2±¯äÓM¯§ºÄw€i9ݼôTq÷­^ô¤˜óÖi€¶'­xÚ¨kß˃r¸°C Ëêº.CèÉK¸:¸Ž ‚=áÛ6 ÆÐã1só¯RX®RF*wbŽ,2‹Až1#]òI†šY¬Ü…ãAäDzìË­ˆ|Dš,w%«t'TÆrÆWì ¿eó¡¾å¥n*çø-ým–QŸi~-²–Á•#»×.‰ò1B½¹û²?Y!&Œï* Ç™Vf敉kYbËÓ]—óãì}åz0¸¨\ö~®|¸é÷+œA烫l¬¡ñÑyD€³'»1”n ïÁYMy)L_Æ YPŒÀ[Ÿ-kQp|“¦S >×Û\ [ø0ƒ®p uE…qK T©*ö.¦œØz4‹êÊ+Ï*DpZɶwIµÚ2“~!àÁAz(=êÃXKpje«Œ„D ’²fµjÕuˆRxêé*¼¼ÍL,Ëüó«Oò*µ_¬àö .^1ÿ¨?ŽŒÊUï2û¹ñƒµ T!P¸>}ü˜ŸÛý?¬å hcàßc‹9ó0͘…×+Ìpvd„€Ÿ±_ÊYË}b Ü+J`¾à… Ã×Ç ùÜ HÖT‹a¢¿/üT«T‹a>dUiÞg¥\š[WeÀÿ÷Ŷõ “—ôÿÕ:­ ÿ¯ÕÙúÿ¶þ¿MóÿýxÞÿI\ý‰@I[C¡‡LJ*õË÷¨Á1å²ð_Ñ%œå5]€Afmd¦gxRÊÈõÔΕ“=µb†iy+A-?æfb =¥àº¶ZÇ:îÇš  £ f€n–«ky ¢IÊÎvŽÕÐâ¯>)çv‹EºM0ŸØ-“!KC~¬uŽšõFbZc’œÓr¦åβ28­Ã)åá-œÏüXz‘%Œ¹4œùô‰Xçù8‚CÈ2­?̙͋R™ t(#ÈÈ×»+ÊÇùDEgL2  #ŒhY0×jGÍf'ðžvt¿N­¹=÷*TÎm½|1 ¦uôü{µ£öñÆ`ìÕŽ@xAŒ½ÚQ÷ò˜¸²MÚhÔÕÛØtåå"å´0_!Ü1ò'v+_,š?•|]LÌž¢WKë«u›ÍV*\_%$ë3% UÆ L¿ØnDŠN¶«m.»¶¿p7À®­ZMòÛ¶Éþ»@g-€{z…üÌÏáÿ5·ø[ûï¦Ù¯oί†T#ð—¯Ãú;K±þ^šs{±â©äª9ñ2ÑþëK Ù21%ÁêË*ëïÜö/ú§ÃW´ôêó¹¦WaÊš&Þ¤YYÇÈ«ÎAæ]åØ(Ѹ«LŠIÄ”€).‚ã8.…žR×3ŸxåvZÇZ9å5 » ‹²™uéÑŠo,bâ%ÖçÝcAZyÞð0B.ÏóKÐÂfÏmv.bpî ®±A•»’@„Y°77üK×ýÔñ<ê‚ïxúÀäbéú«‚ñ%~ó1þûˆL¢ÙU‚ˆó³\)U˜P{íPfô‚«´ÂŒ KQâöõþzµï¦O\–O:ÛÜœÆÕ0!÷ÆÔ|œ•©ÌÞÇZñ˜Ö•ˆIç¼­²ô5ª®!L‡¼p<­uýÝI^SçZ~!é’ 1/ê ¿n–A¼¿½ ¯À€²zMRPÑF\^y­ ìÎ3Üùjvêçó·¼ Ÿ=™ê‰9«åbµ4ØÛÏ4˜Ü>¸F×ÝdèÉ… )ãê’_±çî‰>÷E7ÚE©Cáãà€•""•„¯„,žÇ×Ǭ‡ˆ_0“¤¾‹à6çd ,BËat=ÿWG, æc†W”æØRŠsE‰]ÒÝq…-Ü· ˆØÊã•”²”@Cñpé0…è0ÊÅ–&„gÉœNG^’IMNbÁÓe¢×œn W= '-o6Þd¸ÑÌdñÚN> å“^8„‰·B ì•µZòVáµÑ‹ÇÐÒÏ÷V‡ÈVdîmú*RWÎÌžÛ³ÕLlI–æ‚·g,ÄE’ó¤TZeµ/ö˜:—¬ÌÛ˜8I[ ÝÏÃÒheh4fpY˜Ë’ Ìe’Èùï^`?"_8§ÐÉáù´Ñ­üè7£/UšFÚçùÝ`V»¦ÕÙÊàöT.¶Æ¯lú”¢cÛõ–pú+¼*·f¦=ý-Uô„p üŠeqQá;ã×ÂePöÙþ-ôü —oö÷ÎÏöŒ½ƒ›>ff¯·ŸnøoýËÞùžŸâƒmôm ÿݺaü85ÇöÌv ô÷â§äøýßžóņ«ŠãÞÓ“ Ãø‹ãYÂî]šSzÔ£_ôGw›4åÌY‘ë,½ÏO Ø/Ú£»-ø²?ÛKžü«»òFÖã3ÿE}T@™ê“Å­@ãÛ!ÍÔß(ç‰ýF³ÄP$Äd°jƒü-JøûÞhï8^œá†ÏòHž»mÆ èÞ»Ößæ0pãŽÿ¦3©c¿¬\[jsè¾t¾P‚ý¦?}œä[fèF:·æŸc$~ÓØÚ5ŒKûó²~~pÜ;“æà^ü¦=} Ä:.lzúùÅ‚ƒ“VÁû-° ê5iÆõjÉ—±Àß«KNpN{G»YSUŸ%¬ziÕÕHФ°‚5:ikKÃÎ'‡Ÿå=â/®ïoPíäÛ3¿R³”¢màâ˜yàQƒÒ9'ãÙ’â—èŒ=A2b‘ÂHøÎüƹâ–¤¯àC¶Ñ/Ž8{°<)9ŒAøÔpƒ(´Š¤ûƒÌ®8‡TÄb²Ô9dœP©Ý¦Œf̵\¤~Á^ãM¸{tòì úËÇæ“7¢R_›G1ÈÇ]N‰¶cK…ƒ¼ä(Ѿrï_k”Âú÷9JKü­Ý)(ðغ?؇b¬šQÁǶMØ;ÐW—x%}Iç!ßY€ûaêS4Ú¥½[<¨´à­á=ßM¼¢-$µdŸVÁë«íCc <œxÇþÚÓx“·c_&1 ³ª‰À@À3Œ‹sgÁ’»ÉĹ?†“o Â$Ý0Èê²î¦zÝŒZmþ´Y¯§%C*×Ì=dD Û¬ 3²ÊžœÇù¢¾‚(ªS†Ç ûQ?—ó@ UÁÅ–¾7ÏÁÿSø÷‹ÿã ª+ê™?àoO;uþgÿW ÿ× Q¼ GÀ2æú×Ê1iœ‘ h…܈Ž0±…”2ýaÿ”ßÿ×)¶äDÿÓÕÌ òJ,ö%@ÿê%§D€nØòˆÂ°Íþ¯,·¯ÖoõÎz}‰×Ž$2×mm˜d£oÎ Æ÷‘xüÃàpÉ OzŒµ…ˆ^Ó nåjuß°XfQ4-2hxj@¾O%>¢$28ýrîsˆ§^áÂÏ ¯ƒ×2}N®JCB8À0UuˆW·£"n$ä§u,ßm¸žú7PbÇ훃KpN„ûÝCÄ9a§¢G=á9ðÙÿrIÏ‹SR >‘±‹ŽppÈ”›é*[¼˜Ðl•P¢ÇÇëµ1Ú NHÆojoéáÃ2‘sëwÙ„©n€ŒV×]þ„Øgdz >„÷ÔŒhŽhYx„Mò*lÀ_ESLx/2{S9þÁ-²$# £îmñz9£}í<âißÛ®[º£Ê»–‘‹,hIo!fè}âìþ Ïø¸&»ÒX^úiX„ÊV£¿Ûðÿ¿WϬï#?j ®~Çû‡ãìdÐ/=³g%øž'ð†A¯—‹Zè}NX¤VùÝRøÏ Sœ˜^&ÒV/xìTº7Gê>Û¤tZñOè*³-¾3ætᮉ> ÙeФæÈt¾Z»¸ë\êˆ{›Ú`d¾7š¦·ÿd¯ç°Å_â•O?¼Å‚£²o’R¢«%åÚî$ {»·Òöй°#Å¢ Ä[’Ó[FŒþ#³–^GZü§ešþ/ÓÂ_×øOÿT ÿá4™ß±öC&òR5À“Q:âu`q|w~vS%ebž% ;|1)ÈáCP› \ƒ¿']‡ÓRu¢¬¹{ÒtpgÍ{Ïñ›KoC j«H´…ûÖ꛵²C-†ð!EÆ^mË™T,H[[èŠ23̶sP³vŒòx²ôÖN4Ü€±k©´.¤ŒÞ†@ús\ßO§Ó¶Ú†žï‡N‡Ü v™KuRý_›yçRx©ÀÄä Ä9 [Nš¦€dTV ãœ~(wù™Xͼ9 ty,ßÀ³À‘›…¬d§Gí¶[H§c¶Ï:]Dfž'h#4xÒoÐ öxˆOð#m‰×!{DÝü|«—UwaH !<Å*åÅKzŠ0à6Z’6Äkª6àÆô»²Ad¢a*ì?§` (ìP!u-æ3}O)¹:Ÿ„—7§ê X;x’¨±‹ŸÅgÊ9a@ÚÛœÐiŸ‰Þ€ÿ½Æ5-´õÆ¥ZyÕ’*ž²ö$‹ðØ÷MÓÊaZܘ™'”'·ðb£tš³×^¥:ªš‹¨„RG4"Ÿþt8 TÀ_N rÈøMb¯%ºÒôŸ «ã8­ñÿÿ¯,þßüx3¹jŽ>ooß‚+Àób¾€ E&k—†Œ©AæÉ$Å#€Otòç©kü‘vé«4¿)ÀIÚQ‘Ÿ+áÇ~÷ÐÏXßåôäÉýÒ(•ê1–Ÿ}8„‘£~gŽw ˆÚ a»„·*8ë•âPèöÚÆY»_¾CAèªl¾…ÐÊšEÝ /æ*À½§ŠÊ¸ 4}—„H$» rªI„•ª„$~Åw•¨%òôã—÷3¼ bFnÍ )æã8ØUa¹g¶ñNX‹æß8 ïÉaôýsâSp…ÔнQÄz2кÙd/ÎMAI&À«da{¦…*ÂMVF2b~€C7Ž>N&x¯{>¼9:PnaêFïðٞݯ(ƒþºˆ~pÏì§V Ž}@ÁÐÞÈ:°áòµ°P'ž™âÊ—Q|}t݉  äL¤%¤ ؘvnN¿yÙ¥…†­ “²@jFÏo¨ä¬‚@ûƒhƒ…vC’ái˜¦Ãüh?9‡þv6s§°“C+È ˆ5‰’½6+~±hŸJ; ¢…G.+L; «¢ I°­°WË‚àÆ·C¹X†³Ÿ`”ŒÃRz\uõ¡ÐðY–(ü¢áÍ­2™íÀSŽºeá‘©§\ˆ¤lMU%ÙéºfÕýNù)S0Û~²²£ÀÓâ¿»í^$þ»kàjü·Æ«…ÿŽ~Á”Ñäêjx}ñ]k@ÓýhsíLñV1¶gú<ÆÝt3Mn.t¨¯VHúupÞøï ñÆ;ª¢Ñ¢¦A ¸ndY)Ò AsÇ´6¦B˹6)¢Dç-= ÊÑÝŸá…u§h§°q«kôĈQÞHÇexe]ßJ㻸¿:Æ™U|WÝuoOq¯Õú’Y>C™Ö²`ýµ–rùZÊù£»-ë´+ x0›Ö|<"“B9R¥YG5Z9ƒe˜­Ðh•Y(@ î ÎÆ­¢³”hSI-Ò¤(ß‚® ÄÉJj¨’i¡L…\Ó»Õé‹ÓUˆÈTŽ@œO@8í= Ðî‘}gÃ4ŽOÈçô¿=ãøø(J÷p¸¿  |ZG쓯..’nçe€nþRŒdcÚü2¹½ûùfŒÿ„òÜmôw§oœ·Ï­‹ ä«ÑT~ÁöŠ=Ï ©è1 ú½¾ü<@„ëo€½ ÅÂ’ñ&•i3ZŠC'!¶¹g+KÞ8pÚÜø‰Í3èáùäæîO|™¯±qßy«ægܶy¦ò/œoÛl„æá¯ytæ«L£Ûˆ ààŸÆ—þçãðö®y5¾û4¹@!ëd Ö¸C ~|üO£{Ù.A®´i¯¦ë.ûÉvç`"nMèž[o»žb«hPÙˆwqÁ4àFÍÿŒû‚ŸÿörrZ­VB¹ÆŸÈн¼à$Š˜züå/’Ô`Y½NZRÃW¼»ú$äÐÏÕ*‰á|ÿȹØü¬;ëù³8?œ€ï/­|sn_šsÜGìÎUfÏhg÷éd"ÃH’Šä Kå E†2‘ù¸m†ÆçS6CÏÞÕ"wñ¡àîõB%JÔšªä3É‚ TBs0AÈé+Q¤ øJˆÑÖN’úª¯úª¯úª¯úª¯úª¯úz£×ÓsöWPcl-sql-6.7.2/doc/clsql.pdf0000644000175000017500000302211412570445324014322 0ustar kevinkevin%PDF-1.4 %ª«¬­ 4 0 obj << /Title (CLSQL Users' Guide) /Author (Kevin M. Rosenberg, Marcus T. Pearce, Pierre R. Mai, and onShore Development, Inc.) /Creator (DocBook XSL Stylesheets with Apache FOP) /Producer (Apache FOP Version 1.1) /CreationDate (D:20150830001408Z) >> endobj 5 0 obj << /N 3 /Length 11 0 R /Filter /FlateDecode >> stream xœí™gPTY€ï{¯s ¡»i249I”Ѐäœ$Hèn2-49˜ÁAD$)‚ˆ8:EE¢ €y”qpQQYÀ³U»µ[[µµ¶Ï÷¾:çÖ;羺Uï«zÈâ٠ɰ> ¼¾¯³3(8„‰½p€ H€ 0áìäD[oo°+kÁ?ÄûQ­Üïéüóú¿ 'Ç¢/s,‡›Ì^æËÍIà¬ä§W8=%1Ø{™éüå—™³Âß8c…£¾qÑê?_ûe> ŽµÊ„S+±ÊÔ®fGóî[^¯ÂNä/?_z¥—â·VCte?Ì(.ËOár˜ÿáÖþ}ü]/tòòËÿ¯7ø÷Y9;ßè­åꙀå¶–Àz RòWNå0”Ýtôü•‹8@g ’ÏØ©ü´o9Ôêì€(€¤€0¾-—–pŽGåÅñú¶ÊoÍØ:”¨˜Ÿ(H2O:˜4Çwç7&CÉ›’»RèËéTÔïRÇÓ¬ÒªÓ>¤¤ŸÍËàe djeîÍœÊrÊ:žÊfg÷æ(æìÊßf»­n;´=b{ïåy;&w:ï<¹‹°+n×í\ýÜÒÜw»wwçÉåíÌ›øÎù»–|‘|~þØ‹=µß£¾ù~pïÚ½•{¿p nê–~.bÝüÁà‡Š–öEî,6)>R‚)ᕌî·Þ²T¬4«tâ€çŽ2fYAÙ»ƒ[Þ(7*¯=D8”zHPáQÑU©RYRù¹*ºj¤Ú®º­F¶foÍÂaÎáá#6GZkåj k?9ú Î¹®£^­¾üæXÚ±  ýÇYÇ›¥ ¿œàœô=Ù×dÚÔÔ,Û\Ü·¤¶Ìœ =u÷G‡»ZuZëÚm…§ÁéÔÓ/ ûiôŒû™Þ³¬³­?«þ\ÓNk/è€:2;æ:£;]Á]CçÜÎõv[t·ÿ¢ûˉóŠç«/ˆ_(î!ôäõ,]̺8)ñÒìå¨Ë½[z_ ºr¿Ï§oðªûÕëל®]é·í¿xÝòúùæ7ÎÝdÝì¼er«cÀx ý¶ñíöA“ÁŽ;¦wºîšÝíZ7Ô3l=|ùžÃ½k÷]ïßY?24ê?ú`,tLð€ó`úaüÃ7Ò->Þùý¤à©èÓòg²ÏêÕüµM`"¸0î0>ð|ÃóÇì‰W¿%ÿöy2ïùEù”ÂTÓ´áôù§™»/7¾œ|•øjq6ÿw±ßk^k¼þù›?æ‚æ&ßðß,ýYôVêí‰wFïzç½çŸ½Ox¿¸PðAêÃɬýŸ?M-¦Æ~®ø¢ù¥û«û×'K KKBº€Ð„. t¡ ]@èBº€Ð„. t¡ ]àÿØVÿã,²r96€_6·¨¬@-Jh 7#e¥ÊÛÊdoMÌäÇDE§¬a¦&s™‘|.7>s¥ö7û  endstream endobj 6 0 obj [/ICCBased 5 0 R] endobj 7 0 obj << /Type /Metadata /Subtype /XML /Length 12 0 R >> stream en application/pdf CLSQL Users' Guide Kevin M. Rosenberg, Marcus T. Pearce, Pierre R. Mai, and onShore Development, Inc. 2015-08-30T00:14:08Z 1.4 Apache FOP Version 1.1 2015-08-30T00:14:08Z DocBook XSL Stylesheets with Apache FOP 2015-08-30T00:14:08Z endstream endobj 10 0 obj << /Length 13 0 R /Filter /FlateDecode >> stream xœu‘ÉNÃ@ †ïy ß ÌŒgõ•U@+u 'Ä¡”¡D¢ MhŸ§©ÔMÕŒ4£ßþ?Ûò"Ó ä\µO`‚é<[l4 ÀøVЏNZ§‘Ü€tpVíGv8§õVT0ËnòìúÁYŒ‘˜ò¯msZjŠÌ!i¤”RÞC>‡·óÛÞxØ»x‡üYæ=Zg˜mpÇxmRÝœÁã²øL[”¦}FðhˆÄF‹VZrÿ%­Šú£ªIåGªgdk•lo¥|Ð,½Dtd™ wöþ¤ž.ÈI¾éÐ̽ÓÌÔNOÈä”2jS{P¤ºN0BèOŠC§óR60Ë̲Óõ¼1Våø»ç]Z¥ŸêwžÊ¿Kx*§ØAîsYÖ0ûsAyå endstream endobj 8 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 10 0 R >> endobj 11 0 obj 2453 endobj 12 0 obj 1008 endobj 13 0 obj 288 endobj 15 0 obj << /Length 16 0 R /Filter /FlateDecode >> stream xœÅU[S›@}çW|oÕ™¸Ý —ðئÕiÇ[:yP¬ #°qAûëû-@Hbû¢£3ûñ]öœ=g!ŠGfñ|aj=Ô9áÖ)Çfî@ uì@bº:ßD¸TM¬`ne…ëú‹Px¶h»røÊºèà› }wü.Áø‡00JWJ_8þ{¤4çUÁ±éëJǸ&ßfK@Qå0Sa›RR+]¯‘*¬ÎS­;ÏAÛcÐí:Ö'üpcâ;ƒÌ0Ø–Ö×™õùØ6tl˜Ýuß>Ɖ`>¥”c%…ëƒÉôêbzx ³Ÿ8"†#ö˜xþØ÷}ÏÃï\êüœ<Æ‘Ülâ£=Tî—áuY5¸x_ò)Îà”À¥Êe¶z9‚Ó@‡9ÌœK åÎc©µ„K‚µxAÊ®V sßä“LÔ:•Y1‚YHZã¾-ˆoÛâ7œ;›v·×>¶¿©¿½à„R²ùpáÈuÑǃ8oã‰Z¿èx¹*ÚÔ wXûÄq‡#NQÈ&…’5q¥]óˆ"6qG͇cÈá(ÛW›ÐbtðJ[š'ãÏÿÊ6U›[iݱÄı…ïñ’—Âîp¿ûCÃ3#óû¦w6t}I¹Ô &S$ëÚ€–Ë8/¤–:ˆdè{Pwp¬ƒìÏvô1¾7æ&±¼ß4Qiª2ÀË6‚iœ¯çJß#>jßÀæ ôV>¹!ÔM‹hHŠQ—È> endobj 16 0 obj 671 endobj 18 0 obj << /Length 19 0 R /Filter /FlateDecode >> stream xœÅTMoÛ0 ½ëWðئIòg®¶C j`‡¢×V²Jv»üûQ–SËMR`—,1 ‘Å÷i? ÿŸÜ’­T yž|2Q:¹’xLE Lû´;lÄq‡‹?„›ü&-aðƒ<O€3(6óœg‚f‚1Æ…ÀÍÅÊý <ܼ(uûÅOò­8™ƒ+‹wÒOWûV"¦ù~ÁŽàTäLSÏé—‘›²’ž×AâÊóïâ¹Ï)vÊÂ-F9§)ÜlUËÀÞ›î=á,"l«ðXß…Æ. mdÙfqC· Œ#Úô=ZX“([­âè î¯w÷뻋LE†¹qÎXÌ“Ó\”/–`•±}`W»rßKó± eªíMWU¯ºv!ÐEžØ•”ý;$Ç8ö]àGç$ÕÍRš9\õl¨Öö¥Öå×ì5¬¥³{Å‹~{—•>eöÔ]54²íƒêZÏÆ`½ˆS¨ª¤µêI‡Wš§N7¾ª~ç•Âwšç+¤îÞGWþ)›½Æ~àP ¶ÜJ ˆÞHÀ±.a«;kKspѪkš®Õ<&kÀ®6\ÀyUj¹Q­òJ_†5ù ™€* endstream endobj 17 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 18 0 R >> endobj 19 0 obj 549 endobj 21 0 obj << /Length 22 0 R /Filter /FlateDecode >> stream xœÅ]oÛ6ðÝ¿‚èÖ GR$Eí-qš!C‚$°‹hŠA¶éX¨,9’œ4ÿ~GQ2%ëcÙK×ïx¼ï;ó<¡ˆÀÏ™ùøCËíä¹ÂQä3äÉ %$¢3¶¨Z ªÆ‚Õ+øX"XlЗI2!èÉ×o°¹B¼NÈ1»òðlòÐovÈO—OÐÓäb>ùíJ JÐ|í\$<Ìü ”¯Â Ì?†æ[ôõä:)²tµ_Qš|ü†æN>Í[Æx”ýÆ<”:”Ú—!fðßÇeœ[‚“öN#x‡-z+ÛlÅUЪ¯UÄ.­=ö;hqf¦í¤ø©Â‡óÁØà°je ÿOöY'ŒFöÁQ«"„ЖQehýÊ$kÑl¿Û¥Y¡Whšn·i‚n¢|‡®·»XouR„.ç{œÄò( uùe8ßhôIœD->¹Û(6aá Ü*áµDy,‘*’€<Á»²§7³‡›Am8%ðá¬GzÎ6”nèù”¾è,ï0‹·¦ºcD“vÐütý[9ó0((Õ§ïç««ëáÀp‰}É ñ…ß=Špˆ–eÒŒ© GÖi§¯Qò„Ž- 3†ÿÞeås¬HD&« zdL‘‰²ó8ÖOY:½U)E'/Ú”]›,Ý?m*HaR­ wíâR/¢°n¢dÿ£ZÿP²Zýâ0K~„¼O_uv?=­À«Lë‹ÙeA¯7ÂdU­n£e–æéºèZ¦ä‘e_¢d•¾æè¯{Üu%VâÆêúì÷W—Δíkš}ÏÑ‹éDF7Xp^©üa=a6ê¢qe<†}Ó+„ï*Ó¡›Þ~†ÈQ¥ÅŸ¢Ú›¥2³43(9†F4XéSL,¹L#U¬C7»½ ©ƒcê4"8ÀT¾Gª#¡,$—£R;t3ã ?ïÂÅ܇IDªQ§wéîv:¹-̓q¢ÊáÒÓ”éùí¥ìæ®{ÈðÁ<ð÷Í;¾4 ß\ÝvJ ‰ D®ŸñŽ ž$ä2°¨{¶n<92}Øõ¨UX„‹0×yO?bÀ2Œ1Þºt·oÆÖÇ“BçÆð˜=,è©)3p¹:E¾Œ?~쉪ÑR&ZÄÛ¥»Oóâ)Ó-Ù¯Q±A/>$± ¯é€%f‘¯U”éeÎï¯ËÍùôåéò».Ð2M]ΰyŸ† &ƒ:ŠôĨ†:P-*4‚{2ÞPÇ=̹ÍÅÐñÒéÒ1÷ú˜ûK&á®#j”y‡îÒúêîòbŠ¢¤ÐÙ:\ê> DšCE3:ÚoºtwY¸Œ5º›^÷°åTb. â|EÇØvéªÛñ×]^8Í!AÎ-‡ 4EÍöá¡×®hÎU9ª@Ô/œ¼ã¸UÀà +zäÉOI¾7-fvy… —Çi¸Ò«±±Q¸™€ŽÂ*›ff´x+ÚzŽÀq5‹ 3²KiÞkÔïaæ«5ŽáJÔ*oŒ”l”çû&OÝýsRêýá ÷ÃãÇž¹ ™ísèß-@QZ¼uÁ]ì£Æu´ÑñNg(ŽÜ :ë¼’À£–¤¶ïý}÷ø¤™Áù:ÙC‹uÐzŸ,S®EÕC¾…2ý¼‡‚sÉÏQƒÀ$òt@ìÂ,ÜjÈîO;tXû,qðKïuŽ¢zŒX`Ð?žÒ(ܨºî±½£c6aØ3W} 舣¢†Š[èçïP‰{ðV1WaÞ ž‰6T}ó@Ï;DøX¡“UêÖIZ8 ñ"³, WÁ²Î¶¨ùfŸŸ:pê–U¦àCÊ:Th3ÃUª¬¦h(ºÈtø½±µÑ¹n)Ú­< #jÓ!•)’aéLiaR¯ `™nwàÅE¬Îcg½ ±CÕ¯âpî°pË•éM^ö¾OÛ§‡›ƒ«Äó ­zœ²_¯£á¬dø¤“ å9Ö9%ç­ƒ«ÅÙö-ŽÅ²s7þó0ù!+Ö@ endstream endobj 20 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 21 0 R >> endobj 22 0 obj 1513 endobj 24 0 obj << /Length 25 0 R /Filter /FlateDecode >> stream xœÅZ_sܸ ßOÁ¹>ʼniQ¤(©}Ê5M›ŽÓ¹Ô¾¹v.÷ KZ¯­´YIñ¹Ÿþ@‚©¿Žû:™1 ’?ïñàߥúÆ>I»Ï†ÆHè. )„ êäHÌ8 ¥šå ü~¿p äç]µóÈ_w¿ü 3âÃÃΛŠÓÌ7»Îúê‰÷Í×÷Èýî‡ÛÝÕÛ€0Üî­‹Ný0Žã(ŒHD¹«ŸÜÉ/ïªö\g]ÚuõòWrû÷Ý_nGÆpæÿŒù uÐÚë-öáHõ>Â?qÎÀ@·T½ GPpmõ¨4›f~£"8D{ð÷ªž5Ãs­Šoºøúyªh4¾ºýߨg³mTkÖp¥ŽÙ}ÊYìyž/И÷Ez®›zß’Ÿ‹*«4nÁ""< >“à /@î·E™7ä%¹ä!ÈE•óÌÂ^T<Ç4’A‡œÍe¾O>å{KÍ—tU†2¬É9· éN§²pUÜ×g ̊êÞRÚƒÃ]wçä\¸wU–;¬3’ñ*µ”›¢Js´Ëõ­§~p…ù"´f Y;¨ª¹i}Ì-z(ÚƒEí!Ï<¿Ï¯f¤ÌRÞ\_[TΓëw?X€>z´„}B çÙQªß޹3‚xâ Ôß9= 2²y{Æúçë›׫ç(VD÷Œ•öl‹± 1îy<0±ôÓ?Þýk+|˜Òy gÏ1Ä“T:ñƒp+~„€•½0^ÚÐzìÀYrgrß*`v —WOç‚Xn "àΪ®.ßäwER‘~Oœ¼e+n6½h„°ï!ˆ’^Œ¢^gÙ`ŽXáãpëŽ ¹ á§·oß=µr(iØçó¹rJÚÃfŠŽ*azÀE«ÿ'µ…B×,Ly8îª6q 9aVkóÊ£HÝ'ÅÒrŽ ‰;¢,^,©jWÏŠ¦=w]H}8éÁÂôœ'-ž\$$®€sž¶5Æ’öõ³måúXÆ‘ˆäsmåAH¹ á(ðxÓV~Ôb}άžxÓYµj)$}HýãÕ^ß¼yûBy*غÖFŒêëCÄÂPyöü>Í¡LÊËs~¯öèñûUøP@6ÄQ£Í¿ëΌҤ2£¬6c¾Þ=šÁ©kX‚ᆫéêb Îã®ûô”jÑ{ ÷XÕö€•CrñjJr·ûžpkN’P'¬,ëS®!ÿ-9žÊáyZgÃ8išî˜b[+eõ4ú!§êÖûrIËÍÓèCšôU²ñ}¶À;XЗÎySX…‹jC×ÙQâÐÌÍ—¹êšóUs€kÙUY4§«çC¹ótû}qµjW¸ÄB†¦ë÷,`”ÐvÅ‚3÷åúp‘?üøÝTS­Åwd%>¾\°¼±tòtÕá$WõĹ­:ïßO&~î«Ë-„'Í ¼<0ÿ‹Ge=:•IåÀ¶v@×ä‹Òjòå .=÷p8`ØÔé§¼ufU›Ÿ÷Iš¿Z]üØ5.G ÷äÕYà¢:ëLäÊPÜ 6zcIµp­å‚Müdj`ÀœK:‚´¼4 v«Ò+KÊ’á²e ‰+ÁIàH2eé+–·…±)='ŠÕup“ §.[±ÁÕ«Ä‘›ž›þ”̹­>\kXŸø ÀÜo€NÿfÜÛ…H3¶u`˜š;Om50¼L/L9ËÌ­Ú‘E³p’TúçÖ†µAÝÚ  ¶6hhjƒÛÚÚÀYý‘@™&[k0dëöÙzʽž­áº<7gšañ/¨47b7òµ¿Àñ•ùZ¨7™Aà© þSùõ¼Œ-|"ŸàÏÓy[ Zÿ8 ÿ·na.aôÞgmi(ë1¨ì±ˆ/ˆÐUƒ¨îOgYÌŸ[UD„:Ç<žtÊ7}~ÅñÐ= 4!…`£{T OWÛ~ÕÅà•0]r1絋O›¤Y¡“¥‘¸œ„€¤}ýlS9©ÇÁT.åsMåxa? nrÔJbSz5Í[Ò±Q ?’ãÌ… Ò"ûÖÁàõŽÞ§Â àºïó¹Äg7ÜiÒó(#3iÔªcªSEd޽+Ý=Ú±SEú©¹óÔ©"H^ÉL§nù7ŽÆú÷å%ˆh@†öѨÁ@’i1Œš $9múF‘Ójô :O×Û èY…4/Sf&ZJåÓÉÊʽ–‚î¯ÏÔ¡™^ÁzÅP†ž:ÿñ‚ÉO„lÌ„{ÊfgýCÒ8ȼH|“»®R‡gäõl~4$÷'˹G¿ë èŒméE¤g94äÞƒé¡(K—±›|Ì0ô¾5pÝÓê!"ˆyW·¹öOxZ¨·Š~³ÀL^;ã´®öÅ}w¾ºJ¢Ôßà¶’Š„å'+b_¯Iq•;˜\ —ôÓÜ#ÂHÁ1^¸2KÀìŽãǺ;[tè?ýjädÓÑ{v¦$.(*Èx]Úvgs½ÓÔÚY­?DÀÍN‚ó'v¿×sÖ endstream endobj 23 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 24 0 R >> endobj 25 0 obj 2416 endobj 27 0 obj << /Length 28 0 R /Filter /FlateDecode >> stream xœÅSËŽ›0Ýû+în©qlÏ.Õ$U+u‘R3³@$p4êßצ6C‘ºJ ’ïþç܇/ˆQßJo±`ŸÑe°Qˆ|0EhˆYgäj}ÊØ»¤6{H 'ø‰Dà zzQÎuá ‘áÌåG´÷ðµ‡ÜŸÀ}NÑz%–®DQ€Y,„Hâ0¡ƒô O‹¯ìÚÃ5—UÛ,_ ý†¶é(™€²ÿÌÞp0ìM‹™úclúÎ'GäW{õxf^M»ë\5¾Óúk% ËÃo«rŽAß*y‚ÍãÃî~6yuM¥p¢§ö e–÷Vöè7èñb9 endstream endobj 26 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 27 0 R >> endobj 28 0 obj 459 endobj 30 0 obj << /URI (http://www.lispworks.com/documentation/lw44/LWUG/html/lwuser-204.htm) /S /URI >> endobj 31 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 407.813 339.935 416.813 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 30 0 R /H /I >> endobj 33 0 obj << /Type /Annot /Subtype /Link /Rect [ 345.551 407.813 540.001 416.813 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 30 0 R /H /I >> endobj 34 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 395.813 246.94 404.813 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 30 0 R /H /I >> endobj 35 0 obj << /URI (http://www.lispworks.com/documentation/lw44/LWRM/html/lwref-424.htm) /S /URI >> endobj 36 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 372.92 338.535 381.92 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 35 0 R /H /I >> endobj 37 0 obj << /Type /Annot /Subtype /Link /Rect [ 345.548 372.92 539.998 381.92 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 35 0 R /H /I >> endobj 38 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 360.92 242.5 369.92 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 35 0 R /H /I >> endobj 39 0 obj << /URI (http://www.lispworks.com/documentation/sql-tutorial/index.html) /S /URI >> endobj 40 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 338.027 316.017 347.027 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 39 0 R /H /I >> endobj 41 0 obj << /Type /Annot /Subtype /Link /Rect [ 328.328 338.027 539.998 347.027 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 39 0 R /H /I >> endobj 42 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 326.027 183.06 335.027 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 39 0 R /H /I >> endobj 43 0 obj << /URI (http://philip.greenspun.com/sql/data-modeling.html) /S /URI >> endobj 44 0 obj << /Type /Annot /Subtype /Link /Rect [ 77.0 73.2 272.088 80.4 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 43 0 R /H /I >> endobj 45 0 obj << /Type /Annot /Subtype /Link /Rect [ 276.752 73.2 441.872 80.4 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 43 0 R /H /I >> endobj 46 0 obj << /Length 47 0 R /Filter /FlateDecode >> stream xœÅÙrÛ8ò]_š—Mª,˜ïy›œ;[Îärʉ( ²¸æ!“Tÿý4Ð ’œ­©ÊN¦ÊÝMt£o4 ‡…O<ø·’Œ‘uµxP4Ÿ$Œ±"E1ñCÊ"RG¤«,€ üÁEìÈÍ¢^xäíâë-|ÜŽ o*N2^|´ö_¼_¾¿­Aà³ÿ‹Bÿ'Tgô! ½ñ+pšn¨rÃi@Á½Å§RyZýEED{ðïI;øHȦµX îÃÎG®ŠnOO— ¨§”СXêÿL¡$)õD?cpÀÏyÁø0ÆcòóNúc£áM±Ýòó):ï-³îxUÎÊÐ#)×ЛC-«ìwÉÖzËÖà¤&‘K½‰¹Z¸¨ eœ’¡I p¤Œ¤ØÕ- kÈQ¨ènÀ±Ï (€nÏ×…Ñ=Ö}þcÀ¶M;€¼ZñÍFf¢ÄÑgøédSש‚Pš H ‡­›ØŠ^ƒ²ŽGÑEB R4²U†›Ï¨'¨ÂâÉÇKËâž›µ¯¯^¿¼Ö¨­Â—¯þ¸~M5ŽŽWb1’é®H×þŸÛ˼pb¯e£èý™9<æQQ@¤‚*6gT!jü ]¥0L:k“ÏÐá+ƒƒz|ÿYö-Ei¦,`Vc0] –âÒozõºLÎx`"¸’Cé€ÉäBg/„Íè;Pöùú>¿3+¶mSiD¤å8R ¥—ç"]ãÜdÓ¬á4‚–$dVÈcp"Øáð8˜X[å÷˜¸¡(÷ïyQŠc{ 4uYÔ+ôBˆæöP˜ÊPž “ŸEÔOÄ%(v©q>`Œs&"'øœY«¯õ;ò²¤òg?7 ;ÜÝñ[•$(JXOÜz¹ª1¹°yÒÖÐOàÊê&ûŸm ÃDÞÓ8JÎØ*†;G|áÆ9^¹Sˆèø)MæÙƒTé7…ã.\òúÑHQÓH[ñþȹ‘ià a£á“® BQ›!¸NX?³æ¼ëQذ>Sæ`6š´\Ãr¨£=W;iâ¬QÛ¦,›£hšƒ‡;¢‹é÷¹,èy`f QfÊú9~Ò+‘‹C¨zTý®B0O}éä¸È[u»Dl©!<¶¶ƒ„”ºc!~º$ãˆÆaоž+7`±%4 B˜Å£øÛ×)_Ð(ò²,Lß®ï÷¿_^GZn¡p’\Žþ²<†áåD²ð-cSßÞ|y{¹ë«X ×µK1­>áõ“f¡êKs)·ŽÀ‡À!Ξ`x;y2ð3;ðKòŽ×O\U¤E{—לcaiÁjlV˜š]¦’àLìM#?K!Šý,I³èÇ4 "\{–Ñÿ0õ¼ÐwmùãÅSß|z7Ä¿åÛeÈÜá/lsnWÜ“Œ¦^ày™üdÜgvµÂT•RÂh½6)ÒêÑBþ*Ö÷zwÜúL`ƒˆzA”e‘SeKÐ4<ûggïé7¤9çO¶{(—øð¶t„7ó'Róò²¨7ü‡ˆi9 ªïS\€jÆzûÄó£Èß‹`¾ÌTx%^ŒÞ5^Šó_Zô“¨C†Ÿ…4ñ|B9Ä=1=¤$Œ<&Paªòñ‡ §8Ù\¼–÷ñ‘o+† /U÷Dª¼.ö‡ ídB3–Q?–ó_âÐð‰ñ/æ$Å(Ì™ÍööÍfnj͹¥¾šã$¼áÛaÌE9‡Öúˆ/~ƒÕ"–G:K~ã|Ä¡[ކ ý°+ÊbOÞ¶03uûCMŒñ ô”Q>Œ&bšôëñ¼m óÏæBÑ †ãÆ"\~³“CZjÃX©ô¼PøcsPÎJêa4Äk¡Äv}xû“Mh+.Lƒì¼†Ã¤Âǧ@¾¨¨ ·@¾=ûôêÅ;¼nåê™Ê1?E\#H§(ö§íÔ.ýùº1çó’㌦.˜ÒÂfyg•¯ºÔ±iWÅHtú,=»élÝ¿›#)óæ*ž¯wÃöDÔÞʹSí4„Á"~9±Ól4ïš›0­¨¡î+œõg¯hžEíÚ=-€ä'ììî³ucçVù#˜GJ¾íɪÌë{×^t|è¯p”ÎáÑ^³u7»ÂXÓ6ä©xÜë[0 êÊ;'Ûâ€m^ß¹¼3QXÇX8›Åì½çë ˆ mZ"ú¡xÿž·âé˜à“·Ôö¶õ=ßPýƒßƒýóœ/œ‹ƒ2qß#•øΠø+úaqzÌÄ¢åÄpÕûô¬¤ã[,†c==¥éÐ2'Vž^#šùX`âX<ígÿêÈobRyӴ䆯È_¼Ýt¿‘%†§T†þF½T½Ø?­=4dzËg3 ó ̯à=Çr5rì¥Eôn°HN0g\Šf±¦k‚bÈUѱ3–:äßZ?ÿ~\ü :µÝ³ endstream endobj 32 0 obj [ 31 0 R 33 0 R 34 0 R 36 0 R 37 0 R 38 0 R 40 0 R 41 0 R 42 0 R 44 0 R 45 0 R ] endobj 29 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 32 0 R /Contents 46 0 R >> endobj 47 0 obj 2460 endobj 49 0 obj << /Length 50 0 R /Filter /FlateDecode >> stream xœÅXIoÛ8¾ûW99@¬j_|Kw¸I3ñ (êb@Kt¬©–D’íúß÷q)[”ë¹d”"õ¶ïmL^G2ágB_Ad£8½ š…9¾ y>²\ÃöPŽÄÚCýª³°Û¼øG°Ø Ï£bd¢ßF_¿Áa‚L`ØÌSqŒùiôØÑOOÌ7×o¢çÑûÅèÝY&Z¬DŽmx¡išVè Ðpìˆ>6Zäèëø®Ìó²xzœ£Å¶)«g×ßÐâÏÑlqä’cÙÿƒKÌæ ´ ¿Á¢}tà¹æñI'$]Q™B‡Ó€ÂuÓ£L„N¼¹!|ÉýáïA?Lå†Ùõâ85ÞTùpVžAiFx”þ`øß³^©îaoܰ—ÚŸÓfƒ®‘Ó o× nð ×DÊB­÷å6KÔ§¥\6›´–›ÕA}BÖi‘Ï’€åª&Ò±–ËŠd¸IË¢¾Q§•ÒƒWé­Ë,+÷$Ñéþ¥ª×-©RRó vÁ²Í´ÖÌ GhüoÙzÄ÷͆¨53OmËgÇŠ7-䲬’ÎASÊe ¾7Õ6n:”ü%#?ä¾"1p׆$üìHu# {]¾áþ½ûà÷Z_hDa`ú}Ÿïæ-o?¥,ൃ(ò¡oöx•! ›¤ì@–*V‡~ );ŽhÊL`'ÓpypùŠ—¯Ypùònþð$7q†ëšç`z!qº>t%nʽ\CÐr³O³LnVD}´­ –y|›,ˆâLæ©0·H~­(Æ…NM8’ôArݘþI`~[µbƒ‹R¤¡ ìR¬6²âiEš=!…"{ÚáÇMS¥«mCX âbÓQÉ[JË-Ñhù;ºö„Á«9iºE±*¯I±EÙÉóOAÚÉÂÄAqEp¤·5Â0ês$ÆYv¸A5ÞÑ,ƒuUæ(!8£{Vau™9G  é6§;pÝèFD 1‹2‡¼©uƒ«†‹Ã¨Ni¥#ò³7½/©@ÔBH‰ªSAkcE3Úz4#À²,Ãó H'¼ÄÿšÝ.fhqû~>C³Ÿæ_f3´#êÓÑçþaîÿžÏQ±ÍW¤ZŽpy}Ó÷ϲéhàY§UÝüS`ÀN ßá*ÞàÊñ¦^¼ã](J]Hÿ/âÝàBñ$ÇivBSâ-s@¾](Ÿ6{\(úCœvHxŽ ü u”th]áËkôèù£´¹{øøéöþ ÍšŽéÛn›Ï#ÊM\‡€·­ ©H&¤hÀ|­ñ-6úû•íZ†EëÛ C®gA‡üBÇå¶‚­[èñeA{ ¯jñgE[ñ7èŠvчêÝ_Í•¦‘Ø>L^Ðd™QÄ5ýÁµçœö€ŽZç‡}¼ð:Ö¥œMûv-®Šb»Á»Î!íjrsµKÉ^mŬ¾R”%›öb³ÆE|誩:ZÄLà|"SmsüòB:lbt÷ùÚËðòÚPDˆæÊbî 0äìòú`¶ñûj==×§.벡çx\Ò¨_³)šP°&ÜÚ¥Ë!P{ºÂuèµìH¢_Žys×|Oo]'ß#4MV“ï)LéwÛ½…h™ø=¶5šÂdRl³L#€Nè¾€æðBðhW&ÿ"Æw˜¦ÏhÊ]Ô‚öATØLšÐ£a‰´¸à8&u wŽ×5µð0ï–cÀ‡Þ%èLÒ°ZZ`¤J­–ÛÖ ´Óá8dª«A¦ãæ9VO‹ÐE^úZ€¤—R«–9Ð@DF´æëP›4ÒÁ¶œ&üž©èØK6‡4¼–!Zõ¤üŽ ‹}f¥V—£EENg ‡«Eæ| z¾iŸÔ§µ1Ðà±Ëû‰†#®¤a#m ƒÝïußc·¤‰úÛ’¯mºS:D&ì/Ól€¿×Oš¿€·ÓûÙ¿¥G?ð€3Z endstream endobj 48 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 49 0 R >> endobj 50 0 obj 1486 endobj 52 0 obj << /Length 53 0 R /Filter /FlateDecode >> stream xœÅZ_“Û¸ ÷§àÜKwglU,YÞ·\.×Ig{t}ÍÃù¦C[ôZYr$y}ÛO_’IX¢}J“Ì? A*_' åß™úY,c¶=L¾"/b‹˜%²ÒŒEó NÙ!²Jõ"Dl(ù$±gŸ'õ$d›üö»l,X(Γp8œ~š|"ó«–ð»Ï²çÉ«É_NY²Õι(‰ƒ4Ã0Ê–I¼Tb¶:°ßîÞ7‡CS?}zd«Sß´%¯îg«¿O>¬.LJ¢øÿ`Ò'­ƒ¶A/t,ÿ-½Ú é<¼l!‘`ùŽ«'L€'90·jªpéðìß«v„ÎŒZqßuòëQ±HÅ ò‹xX\]þïì³Ñ2ª¹­5Ë¡5ó\…vª,É20…±õÝúnÛ޼~- 0Œ Äadr_„Yd${(6³/e]°‡/âu,#÷’_fÛÔ]ßò²î;öP7ý¬>UÕX~>÷É÷¯GÁ¤¨xíX&Í|2e]ö¼}fÖÂõýX6ËDz뻚ĸoîõ‡Öm}'+ëgéöÐ7ÍÒë«¢šÏ'…w¬ïŽ­èÊBÔ½oÕ¢ÈëŽÛ.Œbˆ‚dÆõ½WÓùØ9뻇 ïĬç›J0\'îÙsj , ’³±hµìžÍ’¥ÜwFtàYÌçsÞKÏ?}øyöï>ÏÞ?¾{zº:”†r”4 IìÅ©qàÛ¶q°ìýÇ©ëªÊ/DûžšR7íW¿üçÓ •Éœ”†QG~KoÛ˜Ìó[ò§‹?·âØSc8A%¡÷¼.*Ñy¢d‘ ¦ëÄ‹hÁ ó$X°»®jz‡šc_ÊÄáfR@Wͳ`™ÉC=V 9šõ›NŠ–ó[òNƒ¢]ý—>p®x³={þB:÷ ÙÑç²ßS‘?UâqSì®ôTšx–$OÆÉ$¡¦–ÙnFºàr'Ë XÎgרÔÕ«§Î5pKíÄÙußy§@oaë,Àeí•á›æÅ!ñ'?+1µŒÍ©§b-$´‹Cœ[uíß¡˜ üµŽãtÐ/õõ“Qu:(d© §˜Y 2Ðê(°@{ ÈžôQ娡ƒö{‹ 7P¾¬dEáZêÀÒ?‰?U½ë«ca¬ÂÅÐJg7ÄG¿Ò# Ï¢|‹“µãì…WeÁ”áp íJÑN™L:²‡è¶ü(Š)ë¶kšÙ†·l#äy#:…ÿ#±o!e®zÓBŽúÙHK°„…Ô¬£&i;ĺ¢Ì2Øm^ Ïûr»7@¯—¦Ž¢ÝɳBØ%2$®·¦•‡èì­< ò¬Ìä&ª-Ù´EYóöÕ2llbûÎ’0?ÐÄ)Àx)Å9°HÕ™PCÌHú@0 t-h˜Q¥•%̱© "ê¬8ò¶ÿ–ž§ºüzòEm–èKcž¥ pÔXÍ2OuÖÓ‹4ê@™9µèáFç7@ÔNàpK]tD#´BÕij{è˜ ¶¢â*£:u׫ÖïB9ÒX8=_ʶ?éL9PÕãy‡ºôŒ^-í­¸ü•ñcãFW@Å6Iu(ûvð2 eú©Ü ^hƒ£X­îÌR¿4É-åýÔbé¬Ú‚3j\ð?`™¹NzîÚæ@G±´ÙSo+^/ìŒeUY°qÝäÁ[¸©šÖc‰J%|XH/%a>ð’³y&Ë©””!)fàñHÛìàF˜ e,8èŠîñõ¤å²V´]†¾Œ˜‹™¬×¬UEÕr4:ï.tð8KÝ/…i4 r4*°PGÜR»S½ÅÝ )¥ •ÆN\ß'4µ£å5ít[JÇ»TÈM Nw£1ˆÃÂ1¦éVô§¶¾>¾ÇMê9`œº}sª yF³£,Ît½©Ó;ßó¤ó«›û©m~nË^oó™¼cÕ…¤^¤¹#IØÑù¹ÝŽ »Ý›€¶C‘‰ðj€›öJ?º*Þql”£†å€6¤§Šrã²aš6º,Mê@r‡ÃÔUKÈK!-50Ýöm†ðºÂýÆÓÏ”?W´í"7PÝ©ê赥ͩH›Ü€îðtÉb1Šs5@¢ö†­‚º5(-›ô§y.±é#1Ù#$„äŽÄ¦Ž„dŽ„$ŽÄåd˜6†Š\¨Úì<=”Ë­¤LÏäËg0‹¨Q`‚[)ÁúÂóR S°?-Œû©´ ŸÃîÕ#ïrPï,eà)ÍclÜ@)ô!$¸ i:sw[}—±ØzF¬tc(_;dƒ `!vê­"Xeíþ–G“èmõ{xiÊbË9cjç=–ÝѬoÃpÍË^Ti¯\jeÚµç›8›ëÇêÏrØæ§Ö|K! ®7"x×µЦÜ&*$my€K!2à>g:örŸmN=nÀ3{ aIÆmÅ×S oF‰ÆÑ¢ ÜÖÇøLÍ… ³ÕÄÊWùðdÔ†eö¼q´o“ˆàÀÊè…Ýœg€ž°¶¯›Ùèu2Ÿ™zlO²Ì£ãûǧO7öG¤„—R Zx„‰}§ã±i{b×A¡3ؾ7­èÖ÷oHç+¼Ÿ˜·ÏZ,‡g¬r—^x(ôÄzŠJÑ"\^|LHAdÞÑ`^F‹4w¤Ys@¦T’ˆ Õ#D,¶Áûª™–*DžB<BV²‡²¦ƒs=C=\Ús©8:Ì1V£KŽò^¼gª] …‰{‹2Èd€¬ˆaZÂëpBÃgwÂÐ牃ÊQjð€ðVs_Ý<‰¼GËHÆQè3ñöæIæq‡Ñr™æ©G˜ú¥åqnÚ/„gKL4¬ç¥= !g,ÄñØ6rça‹h¸³€Qˆ£¨‹ 8h\,ìKB8Ýk׋Õî6÷„…ÚÖò·òŠÔCÈb_<púL”Bܰ×ýèî¢\“ήћ+×÷&âß®núò’»7tMb”B}Šåæ²dhˆòÜÜss}›Z9;ÂV²¦仑,)As÷©Ã üh¨é~ùõ?~ø×ú.É×÷?ø>~gÃØ¨!;;—‰zÚ¸†ço•w…k5_Ù2²îM#·G´ßêJt<8Í€"³)WSÔüÀrWûÒu&díûÄ•.†§@«¿Ô…P7Ž-WŸ«dö†•;È‹RÇ^U!¤A·ï:vªÕY¨ƒ^}•«>ìó­Èÿ/d=:Pá­_¤“Ø#¬·Ì ÒQU×8Dlä4áØb!~`›:Žù\ ˆ|¾×¡Ã.Ãq‰xËñ|΢h`Ûžˆå½Aª¿‡©í§/ŒnAt.•1§Ï`ø„í[.Y2̨ïìøl¡?Wiä,Z¸bO“ð¿ü¯(ŽS˵%¬F]ù\Ë…²øêÙËÓx©*;yÎxtüFa—KáEFIä3ÐÎÕÇ_6,Í-å,rl÷âàzà¡¿ 囦ñòø{>LÓæ]LÝôÜå!¨4iàÚÛŽó㫣ͭÎ2®;: ƒX]ÑT=VKáå*è±°›¾¬·Õ©Ä0Z‰ÉÐç¼4€#åÍË/ô‡‰R3"'r5®º”ü7¶O“ÿ´/ý endstream endobj 51 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 52 0 R >> endobj 53 0 obj 2850 endobj 55 0 obj << /Length 56 0 R /Filter /FlateDecode >> stream xœÅË’ÛFè[fª$†ïÇääx×[“rՔתÚC&‡–Ø1&Ù I¢|}Ð~ñ¡‰}ñj\EÐ@£é?Vñáo#Y’}³úCÑ’…$J)II{aB¢à„Ô‚ËB Á™8’ÿ­Ú•Oþ³úõ7xY.+ªN ^}rÖoüï¾¾O^V?oW?~HHà“íÁ†( ½$÷}?È#’{QXˆ_H¶ ùõî=oÞ~þô‘lÏï*ZßÿF¶¿¬þ½¹áÿÁ¥OÒéƒÜèþežÜíÑ‹$öÇoœL0tK• FH ®-^ÕjëÔ AýÁçM?|ë†ïz1Nïºøí¬ÈOм|”ÅÍíÿÎ1›m£XÛxSL½‰s‘Ú‰ð$MÑòÐ1Z²Žìys¢íuÚSͯŒõè£+ú^”B‰øi …ËÝæKÕ–äáw^µs (ª‰ª=pò|'e6ûšö=Ñ«ÎUÄñTü޼a›/ìªÍ®Ê¹d’.IxǪ—öŸ„Ó|I¸gžïŸïçÅÌUü=ß:ÖW%k‡¹Pà/y'—RÛò–p0sðŸö#gn}ó†ñ, F;b,^ k,…i´)båEÑt1Ä–´Um7e¡Š…tžzqƒt£ô;¸:Ô×58)Ù¡jŽŒt¬¦CÅ[²cÃ…±–ÐÖÄàR0UihK_X÷ —]*·j&ɳ¢Èbµ,ùé'òØÊuŒÎ¾æ©«~a“Cy.è¼Rë/È@Í,ʺ߳¾çY{s[ ÔO’ç~f_™]!Í\â›’+Ìý‰ û³)¦l^Ê’°ç ¾*¿"?^\H¯taŸ£0õÒ,€ûJúýG˜nfd–{~ ’Îü¹,¹'›<€Þ'‚f1‘'½E÷Ôy×1QxPv–Ä[¶øëBxu¨"« "Þiw¬ŠÞ³´w;þÊ,zaî:õu!ÈQ>ñõHQCPx™k²¥)ÛF Ú4$ÓÖ–hŸ½8 /U][Œýyª)F G~±t7¼dŽà4L[¼ïâý‡ªë‡5©ÙðCO^8pv²7È– {R%µé¾Cè+­jº«á§›ëd¡—å)dX¦À£ð/* ~])Ã"`¨ Qõ”«"(ÀŽM˜DN®|Ñ/›s¯%ûÛW‡«Ös¤úE%œDд…º:©fâ§ïY95èaG{fÜÑD(mOÁOížû¢“Ç“è”BµÚo0wm0é‚ý€YƒXˤ]NŽ(9L7Fd^&&Ê$‹Ìy»u9‹ƒ,‰‹a³:¦ñÌÂ= süµ°j6Ú_`k Ÿô†„ù2—Ó)ïÊöXY1¼`2ÌUˆ|XØ©"x'L|Rr½èq °•Ç'áyp$Ç‚y¥õY0mG…cY:ö°0q¹—‹H.ú†É„-Y`sO8hIääncÁ­ôW!¯»Xl"„Má˱ÚÔÑq¡ØíçBÂÏ¢›:4Ù9ÚhËaGº7M\[œ;œƒëYO›‰Ÿ ±‹üqì0Pùüܾû퇅¾ƒNæO?K²7·fÆgg‡{Ø8¸ëÊA÷aÑŸïúç{C‘%àà0VMÃÊ + )hµA/GÞÛ—2í;l%ˆì,]ÞG:ÙYÔŠ|qqwœ™Y¾Ž4™„C:•%Zk¦& “¼‚`xô‘!ù¹Ã>Ó1\ôëAšœ&ó/3‹€vZ†ªg_µ/µ& g6-$ÒÚØ ­ú U²(¹ƒ£QBïÒ©Cc…á¯(ü,|3»f|£ùr#»M¤ ‡}'¾XÒ2 Àv³é[Á(SEÁzAѹ»`sâ^‡¾¿Ý¬æ|r²½'8¬m ôÎ@;Îk&ƒ¬†;Õˆ«<к—¥Þ´eµ‡Âè E©ì¤Í€ãÙsí0ÕWWº •ÕXjÊ%WãpîZVNc*b“X= g7aÖwg¦%rÄ^аôE¢˜Œ­‚äú4fVù‹‚fit̨ÖC¬€±£RtËp™1ñb¸hÿEƒx¦Ï\7…ÐDÑ$42[—3I¼(£;×£.TE‡ÀMlpsò Š'©<ë- N»ŽsžNñß¾Âîy±¸|EÙ‚™o_a ÂPL4áµ]w,rqŒ4'±^]Ô¡¡Ñ««ä…9Úîjp¸ô eéÛX61]¦¦ùòÁþ¤pM6mòÇ 2/”ÈGñIR$^†E¥ªzÂ|ê*!ßË®÷_}1zëŠoŒ_~…ßzžËŠH~DîN­JÙ’€…+Á'Ý0ª­Ö„ÑZÄÜÈ é#m_ÎôÛ‚¤˜‘íÆÚjèéÇžÁo bÜÅG|Qùˆ'­”J¼Ü\X%üþãÓg‹©âYÊÏW Ã]“žëÁÌLŠhÕB‰VÅ»•&: Ð ËZÅMvWWz_ŸKí«$Qu G«ŽÖ=¯ÏMë¨6q‘˜8-—¾‡¦âSñ(6ÒF«VFÇZÕp{¬êÒbBÌ3¨ºÌ ÒÀ‘h±«W5RB¢¨«©š„÷GÖPƒîõŽ5pÕ¿Z½g™2Jky×кú (Ç66Ñù_ˆO«¿8R´ endstream endobj 54 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 55 0 R >> endobj 56 0 obj 2006 endobj 58 0 obj << /Length 59 0 R /Filter /FlateDecode >> stream xœÅÛnÛ6ôÝ_AdM€XÕý’.ÝÒÎi3dMÛ¸è†$h™ŽµêâˆrÜì¡ß¾CRi‰N‹ èÜ >çHç~#}7r ÿÆì+J\”£»–æ ÈE^Ø’‚9¾å¨@- œ½¥®„àK¼À}•#½]ÝÀÃ9²a3²ûâ8óå覟=±¿»~ÝŽ^LGOOäØhºP!ò\+ˆmÛvbÅ–ç&ìã¢i®ö_VEQ•—ïÎÑtÝTu†óƒ4ýu4™n¹ä9îÿàÒ;n÷'Ú…¿ÈâÙÞzøöö­:º¢r…ž Eèfò6uí·0D€Âñ½Ó[¹aë^l—ÆwU¾»*"(V¼U ޳3ûß9dƒ,2Ý3Iß?F®my!T¹:™gÏÐÛ:+tNʬ|BQº®k8)p–#<Ÿ×„ÒC”.qyKPÖ \ÎÅ÷n*Ô,‰‡®ši fŽ<ÔX½" •dƒªÙ_$mPMV Ôfå­°-êª`Â;¾¡ßjaÖ­¸CŒ—;1d ã!ãt™Q”“†¢5û#œ±.Ó&«Jœ#!åé)Ä´V70H|yãBò 2áÆV“zS‚6Y³DPô¡lðç¡q?×ûiNïò£¼Jqž?ŒI‰g9i\<'õXˆº> sì~¯÷U]`ˆ!Ú›Ê0ÊZ@Õ}9a°/'{NØw $f5mÆ%.˜¸U^=â­qq¹ÞÏñ·ñúý¸¯ä /4Fá0”4‹G¡½œÕ츬è ?Óê>ƒB²ªúvϨ#6Ô߇:ùJÅ»ö®Ä¯9;$;­ê9³îg%mp™~%h®;ôú¾Þ‡s×Kq¤6JrÖ¶O¤`ƒToPýÏÑfIj‚®ŽÑÍ«f|ó5Q2”ÍosÃreΗëÊ…ô~ …ʆÈÛ®ªuCˆm$qà¤AÖ»ˆè»–'¶ã…‘8¹'õC³dCî#XâhŸ|NɪQ8˜­V š@a;g‹ÁIƵ“$´ƒ ç“éN£Ä~ŒU7šÍk “QÑ ®Œs6u4¯p‘åÖ]«¼ÖXgWYm,…MuŽf«îùŽ`±1hÈqâ÷|f„–ÿHD(1߇£a$ðIt99Ÿ¼|$²—ï%‰‡¼¡ŒÎ† éÀ’y‡hfÎ3š®)U–ŠçTÛW-‰Z%¬Œ¤´O›'tëÕÛ7mŠ…ql+™Ô^ð-n8ØaÏÑ‹:ƒ-Ž)S`Ȱ…ðy;”Ûž¤m-ÙaÌCÆ ç¶ÎMCfK2zìTÁeHg¶‘çÅ–D0Xb_pœfåœõ®p—>Öûè0Üõ[æ7Õâå¸VÌb‡›á)à’«$R­k ž•š,Å"Ç¡’¨iW&·¤Ñeš~ÍÆ%)MÌm¶Üšüªþ¤Q6JÅO;óÍ"½È=žå²ä°×¡±†¼¬DÙ¡í¯jØÊsB+p±Õ7‚¶Õ,‚$ºPÀ`Ó¡Â6Ë,]*4­JšÑFSƪܠ˜®HšéZÏ3ºR˜8»)¼Ài­ÙÐvo+ª*L'ñ8ê…DúJ-Á ƒuI$¸e üÐ(1©Õ†JlÝA2,°Š™K¤< äõÊ¡¼óOß"ô°ÓQοòêP&K…Áó$éyÎ ‘°+ˆá.á:V "IìöšwÁNNPë¼)›u]‚g0 Y¿µaáòø5£³îhça:‚в½–€ÿ»c»yØøÐNÂÕI„Üb6'–Ã6a©X™u£P6‹ëö8"(‹ß@¦Š$JWÀr›p:¤Ò^ãóªEdî&|±A·o“å¹ÂÄ8j‘N?i º!(9eÓI-í%Ò]8ØlG¨›l{µ¶rX«3KÒ =h÷²6‰ÅJäÆ 9p¯%2ë8ÒªXe¹˜“íf­$,ÂÙ×,IrMðE]+VMVd+‰âÈØ²f@`»=ï墶PšËãØ¦£ ­„‘V‚çê­¦²$ÈïÎ-\\vHëAOj»æ„ ôM‚]KVþ+; "ZmÑð.¿¿ç7ó‡ÍIèX çzBí×€Ý-‚Ðvb;Ò~`@¸iêl¶†Û¾a‹ØÝÔ`¿Rè®UuƒŽŸ£~äkm|ùÇåÑÎ~™¼™ŽO¦Ó÷g/>L'èôââ¹AbìLÒ,ÊXÀ²E•(Æ7ïnsN4HLBƒh†ëo¶ÓzqòÞ`kèö½ÿ¯¶†ìw¥m[Ñÿ½h]ñ_þd™¸a¦Øý~ðà†7pðýäüdzvñæä|<ùý-ÜŸˆŸÆÐ1:={9ýóÍÉo“ëƒçÚ€ïFÿÏ£¸¾ endstream endobj 57 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 58 0 R >> endobj 59 0 obj 1807 endobj 61 0 obj << /Length 62 0 R /Filter /FlateDecode >> stream xœÅXYsÛ6~ׯئ¶g,–‡¨Ã‰;ãÚJ«ŽâKjÓŒíÉ@d1¡H™‡ÿû.%nR'3Ú]{|»X|jxàâ¿&ûéô|˜.ORæALJ -Ea¼–ㇰI‡³YáWþˆIH,à}#i¸ð{ãîgàâ‚Mí«ã‹GÃ>q¸}¿¿¼ Ása<×¾v]×õºtÀï±?ÆK¸;ðx¢}üßqx¶·–»=bT‚’k)7J„m6ËÔÉ_ሠE<âwo®Ã5£Ø.j|Ut”8Ý­jðü½ÙÿÁíd‘ÙVÁôêÁ´ºà»NÐÆ*wÛžæî ÜÑå*Žf<Àé¯"6s îŒí5ðó›ó!î‡æèÃèä„·ýáÙxpuy6löÿ¹†ûÃþ»ëáàÞ@pdQ¶ëŽd¦7þÜÂÝ<ÊòâcB–ô^ i%¯ì~¶»ßã§á©g—»š»uÔà%÷‡o·£ñÇ˳w}8…îüÁý‘Ï«òú5 æ°¡°!IE ÓŒ&S ò8- J€$N>ÑiÁ&N‘+s(Ԣ߯£ƒúa4¼7ÿ>þÕ‡ü)ú¥ I¥‰e}k§r09ÌæšÄ%…–·ô™JŠeгçÉ ¿» ®>ôûŽÌ×)xv$;;¥õ-O-Jº–bÚR2M—+’<ÃÁ*£y4£IŠìû®¥~¾'àó«w×g—œëÛþhpÑ¿.–æÅLûžòXã¦Ç GÐ C8¬î4ŠvÛ YÃë¶: ºhöZöü¯j¨HW4#x V|”+j¹J³‚¾Lè””¹r=R1-Ô²RQO%Íž•¾E´ò¤¢HElˆš\,H±ëP–NÊ\Éq7V’gKƒ ñtA’Gʵá¸ô€Q…H#…—Í_ 2‰•pIV«(y<®ø8ú¬Æ¦i\.•&Ö"Õˆ0§V ˆ¹=S¹e‰Sñ£´¢6 ªŒ<§¥%ÜVX —dxÐu٠Й …¼ÄD¥’‡¾¯}·í¸¸qÜ–ß±xA úXÅ®‡%Øs=‹`×9ÕðKT¸ž]»í°#F¬ù"x%ƒf­W1IºÑÌ<Í–eL c2³¬˜Œâ z@b-£_XSa~ÖÑt±ÇàÄPŽÈÎ4GrM?•$ŽæÍD]aUO»!­ÊÂÐ3/hfÁ¨Ó­a$ëÙo9-8|ÿGÿ¶¯ÙÏôy“f3-Û@ÐÁä¶Äž*\¡Y†¯fg…fUá)IZf#ÊÑÑ’ª„Ú;o‚°ã„-|´¼Ð+oà{ë/èâb|Rx^wkó«,]ã’k Ñä¼L¦…õDö{n½>ûÃþù˜oUvsÔ%#X‰™`2Z”™ÁËÞ*gâÙ†}ÕTæYºÔ\ÕÅ83#Ødˆ©¯îHš°]a,O5M4© öxOËE'pý,9ž$tv 삹&Y”â)‘¢Çoâ B„sKü ¦LŸ.Ï »š*Žd%+Y%QqRg†³âXqUª95I®å¬5;za&εÞ±iÊ©žžÎil¿-‡µ •'9®C¦k¼{Î,a !±©;¬kȲàô,rkkG‰ßŠ£©côÍŽîD‚ŒâX1X;Sši¸µs¯Åî’$~6Ö «;'xªeš•Øh¿F4f·êŠÛE!$Zq$Êà ¹_sƒ®ŽD-É4D±f"cYd¨Ãp`°ó(™io%Žæò†$•˜W+!•*è ûîrB wª Ñ®$Æ{Sn®U(É šd`ñæ†IºŒ*` ¶a¯†-^Dp‰ït«:å$œˆ«èý\ ‹AÒjž®eÌÝᬡ,_¤e<Óóœç@IKEFxp6R”lŒbúBY”µP7÷H­ E¿pöÞŽ$=ìsxÇî†A¨twJõºÉwal¹­Úš{l;øò;ÉE¹«§Ñý‘e5{¢Ú,ЧPdµÈž_µ(ßQVƒ¡%D°9þª¶¬m¿4T­`ÿ+sÑä_ ,v:uPØÓ¿úPa‹*d¯Á—@²Ï1õòÜãRèÕaÓß$^½fXs9 ’©³Ç¿À’æ¾BÛ˜Ðq ”X´¾•ó ZÛg¡:8Üí þhož$0Ö}رƒbGVk²©êÖK‹éù¯IêÙêf'AÖ µý:H˜¡{Ë þV¤_¦tUoÜx²Yæ¬+²†´üv`ÙoÕû„}mbË«ÀÖÝ€¸³`Wœ¥|ðSгðn‡æŽ-ú[uàPNÖÌ3ñÝ ðþÌJl“E¼§eÁåxSûÉøêzÓøV” endstream endobj 60 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 61 0 R >> endobj 62 0 obj 1814 endobj 64 0 obj << /Length 65 0 R /Filter /FlateDecode >> stream xœÅWQoÛ6~÷¯àÛÀV)J–%ôiKœ­Eš.húÀHtÄEQŠ–¿£H™”egoYS@wGù}Çãý<󆿅ú¬‚Òröll>ZDÆ´Œzd‰Jdä%*Ô,G ƒ= „}ŸU3Œ~Ÿýø ƒÂàÐÍðár½óÝìÖÙ_àwߣÇÙo›Ù‡«%ò1Úlmˆâ-cŒ±(ö’¨mJôãìB”¥¨în¯Ñ¦mDÍiqþm>ÏÖ›¥À'ÿ¥ÛCÏ¡?hÿW^Ú£eˆÇ#N&ìíÖÚohXôÞj¨0Gg¾ˆ5ý=É[Øe1NwÝütV¬°xñ(üàäé¿sÈ&§¨öÞ“IÉ„±Ê쥢EšËýY*Ê­^¬Üâ•1‰ŒÅ¿?×<]¸%A·G¾^àãGôgÍ$ÏXÕ ±Eßyöȉ>U©7uÃ÷û³ÝÞû­}£xºïZÑGV«]? ɶ计¯¦Î1žì:°]”f‘Á@†Ý?\ˆ`oEÒ!„Ú÷Á'Išå.YÁ^=¢¯³´‘Ól,~7͇|Z…¡ö¾:G‹x ‡}Öä´±ZǬüT¹óò‘“°rZ3Ú8nBC²^9ƒmm•Œ6ôJ6·&ßµÅhÁ&g¥Õh•Yå¹eõë©™÷°sZ´ÄizB~˜D¥•* à #«=R­@ÊdlË+–Y[Í&•´&-Kú¬ֺ³rg ©EûP8†®æÍ-DãÀÚZÚÃý¹ãé¬"sÑ؂Ѻ²ª9Ì)ê&Ég?ò£µëà’ÂmÃj«Bä$+¶žµ|j~‘V{n¹>^­JÁÑ!ŠâÕñÞäÎè¶­RukrR|HyXÕž•ªî—ëëõf½øts·ùõæb½ø¶¾øúíòîôUÂá[ËY@/ —N)^Gû VÓ—Èœ‹¢]‹Òj6ƒ{‹+¢pýh=ZDîà&p›É ³¨­RÒ'›ÕêÔ[×_¡#a{<‹">ðE\¢‚mõ…B)¯k…U6P;Žô‚«à•†ç/½±¨Ê¹µð­•5o-ÛxiZÑ´w.ÀÊæÇª˜®&ZӗЀáÀ³~cK_ZNnî™Yfß_íäú4–#1ók¤FIBå3`ÒÚPzæÌ£•èhƒ “g-×ü‰u\:Ëéèk¹sì6ÃâVøÎ»Ú’hðÓ'wÔä㻃ŒcG¢–uöš« }— ”Ó õñ¡2Õôï?š>‰ˆ‚qBâá7jgŠß[ížÄ±‡x|À¯ŠÞ ʧ¦æ}ÿt•rH×^«„x’ÎLÝiµ’Ö´ª8s†MÆöò(šÔ`xQ€áù·š"»¸†v’ À5ôá ñÛÍ¥(Jæ>ôr—ó4?A=…<ª™ÃP?S ·Ü™ùXñê0ÏDÚ–ð~tLÝ‘ 0c®ÙvØ2"C•͹à¦^+}`¤dZ‰p‘¼A6MQ‰L6ƒ<@£Cì—Ø79—{™ÛM¬U6¦{ééÌBjët¯¥"Û˦Ì+ñd„ðMà›`Lãòv¨HúdìÁõÂ@*CF^Á+:ȼÂóÐ ­¹€÷×ðržócêvö/¼ê  endstream endobj 63 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 64 0 R >> endobj 65 0 obj 1277 endobj 67 0 obj << /Length 68 0 R /Filter /FlateDecode >> stream xœÅTÏo›0¾óW¼c+5žm0ÆÇtí&MQµ¨H=t=p6BR`úßïq’Þ²¦/Ïþü¾&¯ŠŸ‰yHÅ!]{¯]äà‡]K„À¬¡«f—Sð¾Â‡Ý„Å ž¼Ò£ðÕ{~ÁÅ (þzôð¸üèÍùf…^|¾ËÀgü¿00ÚTÚ\8þKÒ†³· º¿â7ôwÝv o{ر³ÍRÑ9Ý=-[Z=öyRÝÉ ã>v /7œÂOï6ö>}À(ÄËÝ=—>vHÄ•ùã¯áùЉëˆ¿y÷ñQú¶ì(E3{ƒÔ1ÕˆRÊö4µÉÊN“•ô¬µ5âAW„†Âì,ànOo§÷`QÃ^F}ùfdä£~p.ì╆úÏVW“æ}«a³„¤( §R唓€<“ǧ}ž=Îg'er±ÆŽ†,i’ERëº?@Žø0BETØM,’zœÎ#TD°H)É”ƒƒï•Nu¦ËTÃ,¯›s)t‘r> endobj 68 0 obj 624 endobj 70 0 obj << /Length 71 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_AdÚ±FR%[tIŠ ]·.Þ†¡éŦc ¶äHrÓ`ØßQ¤(Y"º¤ˆøvÇ{ž»#}˜„áw*?aLÑ|3yÐc…ù\æÑmnh-Wu´iÁG-‚Æ ý1É&½™|ø“ „Aàq‚ûêjá›ÉûÎþrõý»ø„þ/Hj¯Ô~¡ð/ôjçìM ïÏtgÆÛÑzC_ÁˆÚ[N­5Óú« QM…G}8p ÛyÔ¿ÞæÝO^Ï&ß^ˆ`4[¶qú0âE4–?Í6èÃKD³'—³÷¿2e/ʽ 0¼aŒÉ¦Ú³¡Æ¤ ½K6B²pÀ"Dcó@®”ÀÉÅåÕùoogÓ‹óÙùëó›Ë¤äáÔ lÎC2”¿¥4ì „ch¶h!–Én]¡ER%wI)P~÷—˜W¨ÊÑ®^ƒ ´ `ÄÃ1}\éû=)ÒänmP»Éâ±(ŽC7¢ë@³§í(e±ï…AŒ1åZì<{jìÍ—¨qƒãåj”Å}e$ <JË(ª}wýÖiÕnII[š-ÒyR ”åv½ç¹½á@Nêä¸ÎÒ*MÖ¨&É ø!Œ{ ƒ(¢’‘CæE``ʔ؅(çEº­Ò<ó‰!¤$þ d­CŽC/—»l.ÅUOºB~7ɼÈU3ÕS~> : ^ÌdtÅe§ÞÞ¼ñRÂ\þPXm]­’JÛ·x¬Ô=mZ¢>&3ê$EÙˆë¡Ouð*Ñe3—–ͤJ ­²/«¤—·òx ¤g´Úf \¦Õ‹ÒÄ6 ïƒÇ2=®©³èið¸Éc‘‡eˆ‡>µÈ£mRÀÙV‰Â³˜íû&À«¡ÂÉå·L©^M–jj¾TÇè7#Éù*ÉîÅÂôïžÚ©d½nV¹i:s†2êE>€cµ˜>ϳ Î'Q4‚Äñ£8Š)·ˆŸWé|ez¥¨Z3OtL·œØT÷ý·G> z&èÃñA2qà±m¢ÚYé™ëβÒ4“u™›N˽ê×Üë)ͽêU­Œ›{ ‡…Ü qh±|‘–ÏÓ?ªáÔØð¸Yk[M¥jwR[ ôøºivß®6&‰……ü à~%”(j§f³«î”Þm/q-k²EwëtÑíaÔxíäuÖUصb®°êžÛ5’XB0ÁóC\¸Æg£:T¨\pÂê É÷h²8ªŠým–iQJgN9ñÈž·õˆ¾t¯›$ÍÊv ¾£ÌÒŽÜ:íêUŽQín½Ob¸gGkRv·”YX§”©sJ·òœðA„‰ô·‰RÃc龯6¦ê´³«=(ܸû¢cUç”.eÍ´Ü@v4•-ƒâ3Ðn¹s|L½8„ڛĬ½sà¢.Ð&yBêÔB–Øç'P°T)¤#„W‚ ãÒRy^•¹3_åé|¯f}$>< wm}©â$ÙÖNRHž)Qˆ 1e^F¬=X÷ `æ`ÎD‘3*ÝÙhzË·Jó*Ú1æ7êÓ1ÑÓ‚¬iÃÍÐ4›[B­Éû–j@ûõ¡ÁÔ·l7^úp!ÃÃn(ÖlÛÔ¨Æ¢ÜØ¼—¶r`³+ûEšt"÷{º·Eþ)]ˆ¥r—Vªðsj~ìÉ"sbQõ|…#âm™V?…’ ‰¢€Æc þ¸¨Lï3p‡Xð&³žz<ŽX¤ßz—Ÿ“ÍvÝž+¶#A^ø Iæ7Ï#ýsk;¢n‡©Íà ³«øþ2º'Ðç6E/n_-DV¡£L<Š2Ý@KÔŸÛctÖØ5­Ÿ•g›§òam5‘3·‰ß|WÇèô§?áïYý×<ïÑß ŠÇà*þyeQòCpdéU|ïb`À°Ã6/«ûB¸€D.wu€üòóÍìͯ—MÛìAâÑÕ… R€]Îü\ƒÎÒå´¾!Jt¢6„qÅÆA® )·º* ®Óißåè/3й“¯-à¬,ñ‘œ›YÖ‡.V‚>_u±;‘Ɖàx$!,Dpê"î"¸ÿEÁé:G8sñkƒ_ÿÿëûÉ¿‡‚±Ü endstream endobj 69 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 70 0 R >> endobj 71 0 obj 1593 endobj 73 0 obj << /Length 74 0 R /Filter /FlateDecode >> stream xœÅ]ã¶ñÝ¿‚OÅe±V%J¢¤Zàš&Áé%‡3Ú‡4h›^+'K>I¾Íþû9$EI”vïåšð ?æ›ó¡Í§MDBøw+²‚’ÃeóI¯E$£$fz)e$Jš’ ÑpJ*yʨàp&ÿÙÔ›ü°ùõ7Ø<’.¬*†1®Á ò–[•¶´þEAD}ðwQpP#ôÛQkøõ˜‡äaóÝæ¯ß§$ Éî4ÄyÃJÓBþCÉîB~}Eé7¿‘Ý›ïv3ïe“ͼ(y[e@tðj†a4ÒIy6Ó:¡JïøE R$9¡E²TžÏñ·?¿{÷Ý·;‚—ìÑ" 2*R:¿ó_J³Éù(\»@­à½ œšº‡¾ljÒ7€yÏ÷¼:óDAX„@Ž!¹ïoµ"aî,Û‡AåE‘EÚ>žêžÿi.f âhQ¦£D‹<5P8?I ] :! ¢/E¶ÝU…ŠrÏeò—âi…!?Ì.•§­ø³ìún‘Í|¼VØä6Æ©Ûþé*YÅìËL3hצ©–9|¡“bŸ—.ü£Øʼnߪ~9n˜'pÈßþnãûùP¢"ˆó 6Âï¿inQ÷áõ‘ü›W7Ñ- ¡%4 1<<šÄ«!6Ë ‘÷öò ¡)Ô“WÞÿdá=?| Á%áòTì‚óƧgøxõv½V¥Hñn-TAÀZ¤i×w}[ÖÁ4;Iõ òRTT¤:(b[á  ¯ú³p°=¡Ê×Jß.”ƒj1 ZÖ‡êvî ^;Hs•¦à•»ßuÍ¡}Ët›“O·,™è6òÁ–Æ›†g8K;­õ耳b¹#Zº{WÞvÊyf×.æx×,AÊwkepŸj9›¨öæ—·ò^AB^Ý:ð·ƒ/gÑ‚“ï3¦ª—§îSõ»6Àâ;¡`è‚e¼Sæ!âÈQÖ²ý£îŠV^c^U»Û¼D#È 䜂ú„Aʺì—‚d•‚#¸vÙ²ÒMEîeu¿ú}TA}V•mâŒ@°šë¨L—à‰‚Ñ¥âæÍró{;ýŽÓßíQ¦)á,i_!Âí£Ò›C©p(œ[8~™".·Ú¹3ÅdXA…>ÕÖó†hMt·ŸdˆséÝBXx/ªæÑb'•#FɮăÊ]ˆ}VµÉ¢˜4|°9ÞöÔUu¸¨ì0g¦È[¬9YðŒéU8‰' K“om„Ü=[,Š8.Š0ÉW:|ÍîÊ*º…ŽF€‘õ’¤è ºRŠöÞY,8(w`è›öèn›€6<+[ž‹œ]þÆÖWÖ6ÈÝQxÍ¥ÇíÈjwë&/$ƒYKç7ñpVÙ6S] ÜXa~ªøC`±·' .·¾4 òÆ –¹,vËi fmÏ…{ËŠ>ÝÊVX|üôQ̶¹ ç-$m`‘f¾¹ŠÚC®ój Žõ8+s×ÒbE\®ýÓ=Lcµxt'4ØÂÁ ÂK6 :’äúJQ ƒDÎ~QÂ\^ïÞþ´hH(@Þ;ë¯4Vc& Ã"]iÕ½4¿ª‰ªNĉ$\°¡„(Zá•`¢A’ÇPβÈÃn-¨òµ‹÷ï;­©}fwÞîÓ°ý€èlÔ€)DºÞ"C 8ü8ß>–7¨äˆ>Ô#U7=9œyýðE!•°€02åiâá´lË8¥k§S‚ÔƒE‹¡ÉÓxœù}JÏ+LŠoö€ I+®­è`Œ“}ª4ù`\ßËSaœçK#Ø1ßRþ)ºC[^Ýï¾=IÙ †õ ‰ ”õ—ʆÅlqý;JRra:»©ÃªÂ»×œÊ¦(cUŸÅdò,C£ 8‹ õ¹Ç=Mé<’ýXºéƘ’EJÃáíÐß #CJ»‚Œµ<Š«qåW*×¥’’'j’$™ÆäyÈú0&A׋vV‚æi-‚äDz4 ã0õ}A‹ Sî +‚±UgWϼJGcÁã–CmJ•§¨9·{Çnó3âhW†~¹TªQ½÷˜’±jçòp–7“Ää? Î&÷£A!2ÌÌ\ztLVçFh貊$cÛ ÛéWžyV‡ä³BÄ6L†ùP‚®Ù$^ë™@­€p®}ê­èÄ#mÕ$õi'íÍò©âй<óQ)¤ž{j¨„YOFœ‰&ýŠèݲ?˜™—²ò~Š(( ï/Ò,öð~éç0š™\~Š+ŠUôçÄŠCD #ð̜܈ ÙX-Ó¤°é›B\ܹæ»6ÏÃ@L³+÷• z¶“MèjÚ¢L~ g‰‡ÐËÒÍ Ê%4ó ¼¯ç"Cš›à×ÐÆL+uD=h?CnQuÁþubÜÿz2} 3B$,uÑyýÈÛz»ÀvvÚŒfq0“¥þã†Ú«Jü’€˜Ôê~@÷7ç$¯ºfÀºò¡æ•C– Ô|+S 8W l¦PÄU÷©Ò>Ûê{Žú ,ú”Žã‰Òòí6š4©žÌTa kç3u y—ÅE–YS‹¶mZËÙQmç/«Ê"~S©±å¬Ÿ%AšË?hA"™Óö‹VÄÖ®[þªRFŽë,ʉ›¶^\>F³¦,a1åÈÈõc4w£ºØ=̃E¼feéDî Wõ…aá?7 V%æT}„¯ms?—ãŠ(åø0à{‡ÒO5ÝŽ°¡Ý@P*ÌÓ|àZwæÊ߆‘#¢Ž;G¬Ï%÷ižeÍÍG’B~~¾çm?, Ý­y¦¸ˆ]@µEx¬-®m æ0Sî+kViÍÏ!Þ=:bÆ#N>õób¢¾Ñhmá){ž+‹Â Vck¨ÿÔúzˆÏªÇª©~œË2 BÈ媹ÓyþQfk×å¤%{ýe¶r¿ƒœ`’O÷8 ò"…òguWUaÁ³Ó¦*À{³½+¦* fªbÒ¾÷ª«"¦* æT½=€NUÀ¬ ›ª€ØbUÐr¯U–ЉҦ*ØöãT†§Üêª8°=îMåÐù6Þoþ×®¦N endstream endobj 72 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 73 0 R >> endobj 74 0 obj 2388 endobj 76 0 obj << /Type /Action /S /GoTo /D [72 0 R /XYZ 72.0 720.0 null] >> endobj 77 0 obj << /Type /Annot /Subtype /Link /Rect [ 437.0 689.364 479.0 697.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 79 0 obj << /Type /Annot /Subtype /Link /Rect [ 136.94 495.156 178.94 503.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 80 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 336.948 162.0 345.348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 81 0 obj << /Length 82 0 R /Filter /FlateDecode >> stream xœÅVKoÛ8¾ëWð˜5wø{KÛt‘=¤("´ t{ÐÚt#@–RIiÚß¡(K²eÉÙKÖ6,jÈy~3Ãù1ø]ù‡±œ¬wÑ÷ŽÆˆáD莤4a’rEv¤[+’ûS£߯ðáâŽ|ŽŠÈŸÑ—¯¸¹!€ ‹k™o£#ý~ž]ÿØÁøÿb·¡E¥Å…ãÏМƒ %ápg\O¨­BhH ºýVÞEº{CÂ2øž³~ÀàœŽcçáó)ò-z“D¼W„I¶Cžsë?œ$;òå‚é_IòWt•LÐæMPôº{gÐtD5vàS‹¬é| .ݤ;œ:n)håÏÇáåÛ77Wo“ÕõûÕÕß×·ÉíKôlLÊ4jZOüù9fÐK äÛ¦yC~¤ùƒ#Û²"Í#{«Ñæ#³¹R”YÇ¥œŠË¶+÷3«›zÖmvŸÜ§­q)·½v"D«)ïº, ·næfÊD÷ÇÍ |$£`ëpøSZeé¿yé|*hK‹­5ÌîY}x“_÷‹ a£8«Û%y[Ša¹@„²Íè=­¾=ì\ÑŒHM9~ñ8öoóˆ2%((Ÿ  ¦œG”ƒYà™0`;Ð<Ê'xsÌaa7 vªâð>åæ¹_„,‡3«Ç›eá– š˜Æ³ _îq,÷õcZ«c¢«VGR1?¨#aUY½"AB™op‰ÿÇ €K mÊKsB=ŸÍLø‹!–qW6×EÖdiNÚ´^Êh¦bª„±VŠŽ=C£Ÿ 4ÖÔúê3‚Îw®^WÙ}“•ÅbWeA#±Ã@§2i+Çx‹\„>·kQ Ëæ.«G§B¥÷„ÑÞCí6½è—ë4χSm)†å|Zs´T¬sÊìsy͵@vmãX‰ì½þtdÕ(›®ó?!2nâË´ìy„ñ:s¾H.ø{ú&B§åÁQÄ!Û­só·ˆ–ÔÊýM4a=}z‰½¿Jk·K‹&[×þFó„ÐÇÛh×Ý)Ì®}Æ=¡9¶-º ¾ú™îîs·Z Ñ ³Ætà ö³'( ©Ôïø.·[ –À›_K Âe$Μÿ7}~¾ÁºÅÄ€áe^—ýx8Lg^”©vDkdz Ê@0o&ÍdÛqóÌ`'ñ±Bb+RzïL³oé[&366 'þ·:?F¿ne  endstream endobj 78 0 obj [ 77 0 R 79 0 R 80 0 R ] endobj 75 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 78 0 R /Contents 81 0 R >> endobj 82 0 obj 939 endobj 85 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 163.5 216.08 172.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 87 0 obj << /Type /Action /S /GoTo /D [75 0 R /XYZ 72.0 720.0 null] >> endobj 88 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 151.5 196.65 160.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 89 0 obj << /Length 90 0 R /Filter /FlateDecode >> stream xœÅX[SÛF~÷¯8Cb$VWK´a†€héP¶2i&æA¶× Ô–Ia:ýï=»«»V®ûB¹X»Gçú³—ão þ*ì1ru˜¯ßrš# ;'Y6h¦ª[°†|lÁŠqÕz1‡`ÂÁ|D¿ ¾<àËx¶:.<Ü×ì³7äÕíx¼÷'Whüe‘eª†ãâá‚£:"fþ¾ /îno½ ÿðüߞ߈ÃÐôÿ!Ž{îwœgWÇ¿‘ÊSÜxa™¤ù¦–þ’^Q¹ACÐ"l³W«<_ùS8"†"ñìƒTazÍzxUãý¥02¢:ÐÞì¿2d,2ÛýÁ˜N§œý' ‡0rÐÐpdÁ,H+B¬«I¼,‡YM(¡Ù6‰è¢_K<ûJçY9}W«r2£R¥iÝð6ZФœ èO®Üvp†a©ºfº®m˜0Ó, £Çw…pc4ê.miÍÛ ÒS8ªfñvµ¨E(ŒÖ“ “–…ˆš«š(õRƒr48rb’Åå°MwU‹Œ\ײµ®Ñ"Q K³²Lâµ’nè¼#ÝíÐVzófO•—<©bü~§QÇi4Ò΅Eˆ¦ë;ó8аœÂ8Úí­©íÒR¡-öpÉ4U2"’ì1 •n– ]5 ‚bŽ!ø8ØÙˆö:­½+› Á e4IÕBw%,X‡±5°5ÕÔ0nRxçýÖ›M{«]u±äm”!˜Y.4í«x;,h”ÀADŸi®q”øcz§ë—ôÛjzØÅDÃÍ´iéÝ™;ɵp%I]ïø˜×Â~>•± ìrÑ0».¾ùùâfr£üþ?Où§ry?Ÿxð—éþ²/ÿ>“¨3íÝØÂ‘Ô «’½r^ (· ÔÙ\GÀ·)Üžò›Ò©lÿkc‚’x%‚è0Ípˆj½ïf¼<…:©´6Øè„Íh/²išI–ÊÂ4Û™àa’Sør1öÎ}O¹õ>=ÀEBƒŒBèe-\™Ÿ–q ~œxÊÝÍ%Îà#†Í6^ †2¥6&Ãr]Ç2¬šR•ž¿¿û\é˜Q Z?Þ(7ô;]É”á¡×Q&asI—í’ζÓ!¯»_a'ðDWYíDßÇŽÁîcm¶iq‡‡}VÃõ•âýq=ñ'p{}§E½)þ稪*õN—@:‰·ÉœžÊ¼4$ ýWá ÙO6É×^÷'¸Ù¿:_ItXD§Ã±7ñÏǾrÁ–ÈtèÇwcx+–‘K´S,åò=ˆ‡4([yó‘-ëZÀ5ö>°:è«qÉþeŒ$9ëšxþ=`to|x3=”:ìH »©§X7 ow- ™Ç®$;=.P–;nj’\ì$¬z;)ûV¦¥]Y²ÃÊ4ÚØÃ¿ß8LÛWÇ2…Ð$\Pð–K„,í½ë0sޏj;¶5’çì2FT·ÑFBí (HaZÙ.<[…é]—ÄürÇÇùM”šnWYeýÖʦ¥c)¡XxRÕ ¥qe³âÌjÔ͆I¥.ªûÕÍ‚ÙCË lX{Ð{é×4•°  A,‰¢FºPŠ˜ûS¤ëÖ.U*-è2@(K]G°^»º„ÎblÜØyÁŸóõ¿ë×X [²žêyiðzâÁ—íwÕý2ÐLþ–¼õ%®®ã;¿ïI[{¦Ýrþ“ög%\*|Iëš¹–Á»V+xïÇœnXíØú‡Ù6`ãkËfm öÚˆ¸BÇ5kàͪú²|ÒXY9ÝõÃe8šd¾òqg5þ—( P»ü½Tä8©±Ð5.¹6Ç> endobj 90 0 obj 1627 endobj 92 0 obj << /Length 93 0 R /Filter /FlateDecode >> stream xœÅWQoÛ6~ׯ8dK€Z£(Q$ƒ­€ã¸Å†,]kaÃP÷A±éXƒ%%–¼Ôößw”dI–)ÇmÌ"úÈ»û¾»ã‘z´ øè—f±õXÉà\¿1Ϧ b¨Æ VzUk@w#|”‹p°„?¬Ä"ðÖúø 'ç@PáÉ"]s…òÄzßò¯gÈ‹ûo#pú¿ ÐЬy¡øÇí"9{Ì#û3­ÄÕòFZ8tKJJßzjUEºz–@Êaɧ|öò bŽcÅð圸·®ë‡7 Á¢©sî¢ÄTê… †ç”]|‚àkdÿ…CvEí»&ƒÐ1«‚âìq*2Ë+N%¥Û0V%)C <TÚÄgz½(FïnoÇ£`|=¸ëád<Ò@­æpצ½{”˜RÊ» â˜|Pùf@¾T°Š²Ò„³<ú[Á<Ìû0SÞý¥fyfï¨pϱ‰$h×/í¾Ù$h%Mv:ýQó¥Í!%wª¨M¶I~Þ)Jƒ3‡0ÛŽ®§¢Q|:Ì…gX9K“Ù¨ù`Ç/ëL=üô:GkÁumÉN·40\ßob•ä„É~W›ÆŽ©8&l"8ÆóJ ½€õ9X|AFð¾íJ‡ßã¥Ýk•ÍÖÑC;¹ÆÚÆ Î¨G%b(ÊàÎU4’uQ‰­%º&ë•úrªÇ¹úwͲY]Ò}ÕH"[Ù- «UÛkšb­ÌÖ*Ä‚jwÛÖ$osJ6¥´´ª\{#-‰Aé<-£Ù–!Æ%Is¸S*Ù ‰ÍÁiLQr½P(+â¡åy”=‡Èuzt!-ÚLÜî#Þžªïõ¸Í=l$Ü­6Þ(Ü­5­Ä±ûPW _Цøh¦7*™©Lo‚8G‹­æ]7»²äÊ ôƒãµ@wLÎ¥ÁUoC1ÅFˆc¦ \+Ø$sµˆÔ »mÙ.õ¥d‚•&ÆŸÃøaÕ@0U™ë2ÛÃŽ+Ñ{ul˜XL/:}F«bzöU±-Þþ|cXÉdŸø~zžD+8ËbÅ­ãœÁÙ[ã xz—; ƒ|û àò!ÍòûµÊWFLÇLßý8º™¼¿üön¼ý0Æáe3¬OWøÇ.¹ùìß×Ãxr¡PA>KÔ“Ê¢¸æP> 4âmÙMH‹Á¯jðÅÿî^›p{¤›¤“óë9ݬ!’éù7`q»ÉÑõ—gÇÖ;ÌOÓ ŒÌèÀ°Îÿúò£üFƲÍç3Ò‘™1s¾º'0zjO`n76ð|c˜ î»ú»» FsãÅBŸÂÇ® £%$Þv}²»§‰:¡­ú”Øx Ä»”_BÃÂWÛú-¥yI@_¾ëÛxÖé7…â-á ïتÛ/<{iñÖ£¿ÿŸ‚Á endstream endobj 91 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 92 0 R >> endobj 93 0 obj 1081 endobj 95 0 obj << /Length 96 0 R /Filter /FlateDecode >> stream xœÅXëoÛ6ÿî¿‚È>,)j…"õ,¶^“Ún]¼ CÓŠEÇÚôp%¹n0ìßñ!Š–hÅØ‡. ì»#÷»yd>Í\„áwο˜ U1û¤d. ¢ùr=‡ø¨@ŠöQÎgé(ø’“€Ø ßgå £›Ù‡0˜" û.'”ogï û|uû&ê’ÿÇ ²"òBà/tDr|މÓò^* R)‰´Í‡riõ-HRú#¿ú{7°=ŽÊïg£‡ÙËÙåk¹-×}‡$NDbþCв@ÎIxñ-œ]/GÙÿÊ!e‘ÛÖÎtÈj„1v|™ •OÒ¥wIÁ¤S–x"±ƒŸÏ¤ÂÕb¹øaq{=·x{¤ªVpià`îXóŽtñëç{óÑ kQ»a¨Œ¨Z£¥I›Ü' p÷²UÛ-À=×Á1†Õ¹Ú +Y­Ðë]¹j³ªìtÇ*ˆßâ8tU¬nË6ùÒ)Æ£±ïD”ÀZP=B¥¡»¨v+Û%eŠ~KòkŽƒ† ¸>q|ƱG#;èQá¹8°¨-†ùŽXRóâh·Ìïe«¼jX:A8À0X²e‹CM\  äStÞ´uV>(&eͪÎî{/bIe)D.k ‡3´ j RÄ~“­6zvÖØ§Ë¸tƺI«ª,AÌR½¨ótæ œ˜ï ºjë ¿¶æî±”:$ô0&XEi)ñgäùZm@-¨Y»«Ë~‚Œ…¤ ÷¤@œ#Â7VzÈ>³r´„£%Ë“ °Mé\K¶KŒ¬ 6—ñüAL6Õ”æq\]1¬éEÒ!Åe£$ÂuÛTán¸êé¬ÖÌš)U]Nc6l1Mocàž‰è+NמÓË –ùPˆ!£ "‡Ç„Ptɨp2ÑÔHÅð€³Ê1•µ¬.²Rì µN?ñèyÊaFÏd[0+wîè½SêÚ~›ì¹æöÒCoWIž÷ÕÓàiäMÄY4)[ñB'<ÔX×U1o¶l5q‚‹Gèb× yøkئ!QeÜ™T¢.ýŠå Žª«<Ès¦rÄÙ:[%ù6iYÝZ•Áf9qŸ1tò±³O•‚çá)uAVú9ÙnIäÚ€ÏOäŒÚ´Ñ6©!ð°Y,­“b0]®s¸ƇI”’.‡’“ÛQÒ;•É}Î’ž9~¹ =‡p; bß‚e•}ã?¾%á¢1±ˆ¶< |ÇI…pa¯öTQPN©÷d‰ª0wGY/‚CÜŒ&R!¡Xö;u‡'¯I¾ÉÔ.‚lé5Ù—¬iQ’×,Imeâ «ê×f‡—hh¡¯7/'M œï*†Óºõ nŸÉãÓY¹Êw)ëÙTmó¦É~10¶©šöù”e=åYkFö>Nm«ºí×MZ‹ï>ø¹©¹Ê{¡*{A§;åíÛ:5š¨<µ„$i[Vl[§ã—ýäªqtVp€IÙö‹ÄöSâÄœ¢å:à’ÛȆ#§ÕÚŠ¨EÚ_TÖ–0ÃZVið¢áq/%²Kú`jÕ¶dY™cë#J}^øê IHÙAhz9œ‚­ÁæÙ_Ìlš}U§Æ„Ä„µªm}•†£NÌ£—ä ’‘.«Ý3$JnX‚xÖlŒ—/Ònóœ+!4™(Õ;îúKRlóþíf{Ïzð>ÇpYÁ‘ï©Güà¶ oèÛ»ó3Žÿ •lÏš¬J Ä×ÝzQ<6Ÿò»‹q, “vH<' Âåuñ›ï^½¹}ÿfþöø|!>çÝ¿HÐß^Dc÷êÕÕ?/-ËÅÞtlѳ”­“]ÞêöÌËÇÃ9ŸBä(<ð"LOÈn™å茟:yÒ2WÄ<Š[8Ijv$v¾G¦8ÈK½ÚQˆ¾7‚h$wÒ ±O ‚1Â.»?ÿt»¼ùåš§¸'y&WÄšg?Œ¦£|jžãa¶N aàŽC8µ‡÷û½³-𵓲³ÿœï€X¢i.}n:Œ2þûú~ö/+íC endstream endobj 94 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 95 0 R >> endobj 96 0 obj 1631 endobj 98 0 obj << /Length 99 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_Ad–µÂ½[7qMÛÄÆ†¡éÅ¢m­¶äHrÝ`ØßQ¤$J¢,²¶ˆÈ#ïî¹çŽ<¦÷‚0üŠP4[ "æ*‘ã"b[ÔAk¤ÆZ‰]Ú€V#øÈM0X¢ßÉ£ËÁ—¯°! »îš+•'ƒkÍ¿XÁ/î_GÀý_ eVʼPøçYerZ ŽÛ+Zâjy#-2)‰ô-–VŠiõ•@äPÆ#¿{ãÀMØÌ£Šðåœc´¼›N/D0šÎ›:÷H,ŸâEÓ5úrLƒ“¯hú~0žö²ÿ”õ²(|×ÁtȪ1&­˜ÊÌz*&ÒÇpÍePlÑÀ®#öûRá|4½MÆÃ£«ñðâæÓÕpòy|†N@ÁGÇÒVmŽåz‚A×`ë–R¯£@ñ!…ÊË /¶YRÍŠ%¯†QX„wa^ϯçE'‹j6K³Œç›4‰4a‘l.âï[ñ°áûùÆØ~}‹íH:‰®å‰tÙpù—º£l±]ó¤ÈQ˜Dè·pµåù~ì"{±(cAÀv©ÞÁ&Fí‘(riV” Uů•p·Lå9óÊ£µÁ‘¬æ"9Š“‚g›Œ¡f/¬7F|Ó‚VóªÎÛH}ÖAZžÎ½Ô—ZœSjP6æ·Gµñ!#ÖÁ̈[̳é¿qJŒº#T_kB»ºTxöÅ·Pˆ¾ñ‡]šEVÿf‚Ör¸P}쨫©.϶ÛÞÆR7&ä'-Ä l€+ÖãUN×b¢á8.Qýƒç³,ÞèWš±ïøÐ| ÁTÁ™.ã\T‰ ï•ã…º«ù\Ý’µ ¿ñf{XÚµ]ŠZÕݨÈî¨ëýEú 1éde‹j ¨†b¶bÈIÙ{i‡ƒt^ö¡Þu‡*'­¾WJÒ»?!N}{¨Ívév5Ó;Mq–ñ°àÚâ2Ô&{ïCjÛ–¡lÏ5 W¼ï?n¾ ê^àŽA[Gªz±Ä®V:Ô]\,÷0Ôtq©Ùª)+ ÁÐݶ;xêjoÎÜp-Í Û¾ß®eÆ,¯]¼R¢¯ns>ß®´5m_Äáv]ljzÂHa¨­ke!%ÕƒHy†ÆÝÌ_rÒ&HÊú}@ÉãdÆ÷ØÙ…FXÐaDèh.Ûg耵ï<u %íÞDbGÓJ@C˜kåå ws=Ë'ts[uäñp½Y5]Øô„²¡8¼Q}‡©â¸Ý÷:B?ß „Gè(á;žÇk)Aù¹=AoÖùýêöÄôÈt;žà±Qê*k§¥ƒ&õ{ÙOÃÔê^‡ BÓìAüé—³“ëë?àç›òç°ú-ýeû, çgç¿5˜sèanÑ«ˆÏÃíªVâWFXn7GOfÎï3w »I¼BG‡¢+”ÔD‚X°¸Iób¿t˜¹ƒÂ3€<­­íƒè>IZrCê$ö„Ô@c•ÝÏŸ&ÓË›±Hq3ì䙞ScžÖ­ìçåÙ±»Ùz"…Þ#uÖ9ûÝÎÚ¬ó¹ñ£ççÛ7¥fúqÜ.îWç;¸ºÁQÙÿa½•ÿgs=ø$‰| endstream endobj 97 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 98 0 R >> endobj 99 0 obj 1357 endobj 101 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 439.156 162.0 447.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 103 0 obj << /Length 104 0 R /Filter /FlateDecode >> stream xœÅUKOÛ@¾ûWŒèªz³¿¶j‘DÅ+$RÀÁÄë`ÉqBl¨êï¬_qœÚ u"íxvf¾™ÙoÇŠ?S/®ä0š¥ŽËA8¥Êv€Y„Û0R¶!ÖV W.… ðÓH 'ÆÍn@ÑaaÐv¸Üy`ôøz‡~8>…±q04:Ç60 ÃpÙ"=="¸Ô‡ánvºÃîAwÐ3/ºç=óøúòÜ\õ÷î`øÃè WêŒÿ‡zúyyù)sü»$?ê• Û¢«; Ôú¥6…5¶ÞŠËs+×"‘B,ê)Ö­uÐe´YÅ*/>|;%\â­PBЭ§ÿÁ-[;E]#ÛÅXž¦·­Kqœ¢–ÛÝ0J3ð3ÿÞOì, 2›¤! T'S“YìgŠu•d;Dñí^Q{3&§D8‡A¿ïÃÅéÙº¡à-Ã6úçÏ›â[ÖzüOßÏý3óêr0<¹î¡øu)šÕ¥…_–'$?âG¿÷×ãÚN+.6cƒ(PÐ C5ÊÒÊ}Eƨ$ÔA8æÉÂóbš(ò>".±Ñ !KÇnަ¸}ÑaÄ£#Jûߥ&™M©åy…cïe¤fY4M|d^”=ùZ~³\®çœp¥´Dã4„=0…ÝìAUâ³?Õ/ÓÚ¢ŠŒq[¡õÅNHÏÙ€1š& ¶“3Ó™mMI[ãp±!L•F”VR2Í*ÑoäÕ˹Òè¢0ùMe8oèÂ8zVµI}*»×™ú²áÒq§•µŸ€šÏû¨`§±%y¢yCÌÂ`2¸WFc<ÒXÁ n[DJŠ<åu(Ý8ÖÓp9Œt‚.%Ò²ôDÚ<èÚ·¶lbcºæžÛsÔ%.w¤'ݚ♪‰¹i B”a,麅KÕp3ñ'Ê çÓÉ;äAê­G$‹_§íÄ©EV›uï|˜mEäB;cŸlüÄl€V/™JR¤i´®oü«W:C endstream endobj 102 0 obj [ 101 0 R ] endobj 100 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 102 0 R /Contents 103 0 R >> endobj 104 0 obj 788 endobj 106 0 obj << /Type /Action /S /GoTo /D [91 0 R /XYZ 72.0 720.0 null] >> endobj 107 0 obj << /Type /Annot /Subtype /Link /Rect [ 450.0 250.244 540.0 258.644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 109 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 238.244 150.0 246.644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 111 0 obj << /Type /Annot /Subtype /Link /Rect [ 220.876 97.484 358.519 106.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 110 0 R /H /I >> endobj 112 0 obj << /Length 113 0 R /Filter /FlateDecode >> stream xœÅÉŽÜ6ö^_Aä0h7ºdФ¶Àñ8AÏÝ39Ä9¨ª¨.URYRõò÷󸈤$J\Û@½Gñ-|;鯛aø»?IFÐþ´ùª×B”Dc½Å(d‰Ð i8B•Øåd€àGmàˆ~ÝÔŒþ¹ùíwøx@ž6xÊNßm>9òÅüÍå»Ðü%¤W¤_üKéœÑ‡ˆáñÇqfÝ®JT­ÁŠ’->UÚÒúW)¢@uõ»xlývÔ'üvÂ1zØüx¿yûS„BŒî ç …• %™øCÐý ývEÉ›ßÑýÏ›÷3ïc“ͼ(d›Ã€êàÕcŽÎ$=›è3©#Ýæ'®å±KÉGbªþññîý¿no?¼¿GŠÎìC¤TMéœî3!É”€¬ }Õtåè÷ù.pßÔ5ß÷eS'Yà ŸXñùéRh–gA¦Y–„Ú8w/uŸ?„™GXF‚,"S¦µ>”VszXìÙþö…¿ A°ŸHóˆÐöXÔ+„x‹Z‘’yTãmÛ´‹"ñ懿£–w—ªÝÖ!ÁË"ŒI)êwíÃåÄë¾Cy}@ÿÍ« ï–u™!ƒðÉ’,‹<Ïb9ÄñŒâzƒ¶„]횦âymŠ*°XYÊ}Þ—µ³ötäý‘·v¡o,Ü•u^YÜe-ux^>0%qC˜ža ³ƒÓ„y : ×M½]xAnâ9»Û¿,×à½Dç¸àÒ[dŸ×u3Ï!ðaèwÍ¥>ë±’$”Œ#šüA»Ia3²û#%)C†F¥ó庩7zåéXîÃW^ä Ý”ª_â«#4¾{ÑÀµfµ®_1A–!¹Ètyçªß3¢wèG*NN ©;5=åê.û=ïºâRU/ÈZ†[w-—B¢ ¡’§Ó½‡wû¶<»ÕÜÛ³X@3B^“1FÐV¯ ÝÌBŸáösn Çj¡Ùý”·;-QËûK[K'©é&.Qå„@ ŒCΣ6â9(É’ê«emµ’-Õj­‚N2Ž ÌÚÇ€ucÀSÞïàõIr ÃÇ!¨ÁpHãI–‰Äf± VÅFÁ2q-š»ÈJ»¢iÐ0ËXL="_iñ*ñŸW&Ëc˜¨âÔÇïÕ*Ch²FïèÓ:FÜ5ýÑb«5›d0™†äakeæÚ5R×V6ÍmînÕùáÆ.5¢l<•n€,w†ƒë²(ü“'aQºFêªë‰ê„NöÙ È‘D&Ìá¸EÛœ ž¡J¢²GOeU!hR-‡¢ÙA…€’ß‹r$6ià/BÆi’¹-g ÉU¿ëóþÒY¼),Ü»M­Òø9ï:YŸ4^:LöǼ~p?ªIF5Ãù–½zÃ>‰¡5bêQñý/wŸ–#’D@œFª¹Í‰áC¯R¦+O¥JýÉ ùóžŸ«í°˜P4ÃÑC,oëW®†4L'¤ºfŠ…e©1Ì0ýÃ0È<,Œôþå¼2›Á‰CÈgÊB“Àh!;˜µ±$ ñÒäÐÈ–¨‘&É d“@‘8mM1o,QýbàfÒ‘If‘D!â8Î27ÏùqÖ#‰¦@œ$`P‰çÄFúJ7ަ4U[©]xrâ gá!Ô}­¶X£Ú*PVT™¯þÐŒG£$H1(§zÆûðœŸÎ•½úùnÝ4£  TsL¨~]pJúÞ¸çóUSª™ÑwHñ·5â]yz+ï>¿ùüf~ZqÓK€»í½gŸ8ØhzýÐŒ©W˜t¸ÃÜ•Ž>(ß­eƒá%LEʼn™ÛÈ4(Õ‚©z •_-?52ž.{Ö€ôϪì,YRhæø™t+$wå™ñX-ÈÊOÖ M|'6’¥W·—¤xB"ÕZ´kâ#ñ4æ‡Åâ…*Ñ/K²¸Àl`not¯o7N˜é“™2è ì0ŒÇ²~HdyÄ£qB1Ç,"5ù×å.ÄÒ5ÊArîÓóQ¼Ð˜SS̯¥7qíÝæñbRP&Æ“ÄzñZgA6˜N‚ï ¬îÓ TªJ¸(ÛÎn‚èÏËZ½å¨×iŠ@%„BV Ÿ™hâ„QÆãP]B…k¬Œ.²JÏκ’C0ýg)4[yØ®NÿY#µž( X[쀦ðzÏ#÷ø.ùcÆÆüŠOç6ƒâ¸”FXȲ$źþÞÂeHŒÖü°VI£„)‰²4Mœ‡ÏK³hhºù‹éF•Á9j&“¿Îs±]OÓàEùÊàs d]¤Óî߯ª¸ 1(X©>õjh™j¬ÅA¬Çk‹æ#¤jy~x± ÓW6QÄ\›`$Kv}ØIKoOùó¶h9ßZ³u׋ìI 7-¸U†„EkìG‹9¬íbYNlyù²ÛzvÈ®40iæS2VQ–xtc0=›+ÄݶË÷_¸Ž~Ìuù‘¨ÄØœÏMÛ_ê²±œ¶»õ×¼-÷ß‹W¹ËÙ²ª½ºŒ.hjI–ÇÀ ª¯ÍOÃ…Œ¬³ÌÈ:Òm®·ŽÐ=†Ûqèî\æR-nÈà÷eÁ~¨)âê,b¸n`G-s͹1Ëÿû´ù?èí O endstream endobj 108 0 obj [ 107 0 R 109 0 R 111 0 R ] endobj 105 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 108 0 R /Contents 112 0 R >> endobj 113 0 obj 2104 endobj 110 0 obj << /Type /Action /S /GoTo /D [114 0 R /XYZ 72.0 720.0 null] >> endobj 115 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 264.148 162.0 272.548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 117 0 obj << /Type /Action /S /GoTo /D [105 0 R /XYZ 72.0 720.0 null] >> endobj 118 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 252.148 180.0 260.548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 119 0 obj << /Length 120 0 R /Filter /FlateDecode >> stream xœÅVKsÛ6¾óWà({BOìÍN”ÖDNjMÛ™8J‚,Nù°I*¶úë» !zXv/.¥.Üýö <ø…æ' Í‹àÁò(Šâ‘eÉQ™D²´D¹ùÊ#Ø–‚Wÿ+ôgPý|û› D@à1 ûê:á›à«‡ovÈ›ãûpÊþ Œ ]Vº¼0øÇ¸KÎΆdwÇKœãÜ÷<àôØf+·‘¶ïÞžìýéßÏúA7Èñ8Zßœ »àrüôQ"JÐt9ÔỹKÌÃд@ßF4>ûަ¿ãéAöß8dY4ØÎ0²ª!tǧ.³±õ©wi’ºwêH „B,Á$’æ{Õ œ¸ ¿\_ ?_ü~ü}<ß_O&ã÷Ó«ëÉÍ9:C!Çõ:&Ʀ*"DDâPç-cñ¾€8%à`~­]¤åÆ-–µÖn1¯ÊRÏÛ¬*ÇkVÕ:_¸e»:ö¹cÝWU¾g!GP° l¤ÊF³­7¨­ÐßZßãmTã#Q•“„€?Q/÷%­!­®·BÏgPQ,/‰©Åü#Í×M7÷'óH‰ÄŠ0ЗÈ^îªlõÝk)73GB*”ÚŠfm–樃>‰*–9œrtY92ÏŠ¬$¦«¬q ¬ušç·LµÒë:kÚlî8àbë}G¾së®ý¬ŽwŽ6Íå)ЃÕ}Ë÷‹Ý¬Z-³jÝz¢žÍMöö;VìÔVÁ×ÍV69ÒMœGXq3£¸°S÷vÔèìË›‡> endobj 120 0 obj 957 endobj 122 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 597.364 162.0 605.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 124 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 585.364 180.0 593.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 125 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 532.628 234.0 541.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 126 0 obj << /Length 127 0 R /Filter /FlateDecode >> stream xœÅV_s›8çSèÑÉœ €‡ëŒsMnî&Ói&túÐöAsÅàvÛoßÂHÈ\^RÛ3ì®ôÛÿ»ø›CïZ=‚ÈEÉÎùÖË( \Äx/ò9¢v}´C=í£Bݲ÷DÁC_b‹>:¥CÐßΧ/p˜"€ï9Wל{˾:!¯nŸ 'ç:v®n}D Š3“"—â0ò !G!fn¤>.ŠwèÓêòíÍíæÃ]¼~»‰7×›‡›Ë‹/(þ×¹‰G!1êþ†î;ººB»ð pWíÑï‘ñ‰Õ ƒÜH;ƒLË@¢m«£¢/]ÿÔŽhRÇ£Ÿ‹q±£·Æ«_‡£n Ñbõ_9e“**ÛC0Ñy0^¨:ÛW¡p®cAýçÏ7(ÖQÙ·]‚‡‘ œŽ¯_¦2‡¢]§¢¢‘—S0sÀ`ëÝ?wS€ç->¯’ª,eÒÊt0Ø|¾˜jðù Mòp /^ÝBña.B8§£Dq¨®(ÓÀM–u¢ëŸCw˜â€)J]è;_2Y;}Գݦ4ºÞK5¦y3UÚ—C¥œbŸ†*ÖHkymЦZ4°§[ñ…Úåýÿþ¹Ý2„Íí…¡V÷®jO ®nµVm´¾ëQ/ŠÂÀ‚œ“% ÜÇŒ…„ºÄÛ¼Ahí©Å¹:Š:…4û4/[Y¦Ðƒ¤­ ‰$/òV´ú{UÍË'K·[Ã<å“—X-ÁIrƦ>ÿu÷p·%#€ ìM±v4†å8ÊZ$m~”vpÍ6¯lDkea+í”ì×gªòÍ4ò£GY(”˱‡VEUíÿ0¬(SÃ<ÊDiUfèêgOY™4+æB#êÍh˜æþT0ÿô‚ß‹¾@—cîù}…εÏö\‰és Œûº:æ©•¹¦ÚY\&òºøiø¤Úí ùÃÎü\)Ãhlo+Žyu¨ãèõC¡É¯Rîfú²ŽÙÎÁ¡ê١أ(²Áÿ¾®žj±Û‰6OlÌ@w¢ÉÅQcÅLí#µv&±=?jl]áqŠ5Ñm«C‘l)3ieJ— —*£Ý‘U*÷²ë,Ívs¨I=zšîÒc.e9›x}$,µƒ›š5Í£ù¤ªkhJãT¯ÌX|üÎãO.l?OY„N÷2£ìl z틹§ð:˜ Ð^@CHX`Ú(;”°Æª²A‰( ™bëetïüPØñ¤ endstream endobj 123 0 obj [ 122 0 R 124 0 R 125 0 R ] endobj 121 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 123 0 R /Contents 126 0 R >> endobj 127 0 obj 937 endobj 129 0 obj << /Type /Annot /Subtype /Link /Rect [ 498.0 571.892 540.0 580.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 131 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 214.212 162.0 222.612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 132 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 202.212 180.0 210.612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 133 0 obj << /Length 134 0 R /Filter /FlateDecode >> stream xœÅWKoÛF¾ëWÌ©°ƒj»/>¶@ ¤ŽS$0ìÐCœ%­$¦)“TlýûÎr—‰”ìôà:†¹3»óþfvó8b@ñߨ|Åa¾=:ƒ€ƒðËóIÂ=Ø€[{˜S¯Wø±‡p±†¿GéˆÂŸ£/_qsžFôX]%<Ýwì›úæö»ÆÿŒUUªºpü HUœƒ OÒÃNá~Ë­ ËC޵m¶—i÷µŽØ¥Ç~OÆAÛ0èp]„ogœÂjôÇtôËG…é²Åy CB®Ì‡é¾\yù¦ŸG×Ó^õß8e½*ÛM0è:V5¤”²ƒ˜ªÊ.&Òm´Ñ6¨È¸"Ô÷ÌùÐ |ø4¹º»½½¾šŽÿº»»¹þV¼B_‰¦©ÏúÒœÇçý3çažd…. JØfY¢°ˆÊhæYšêygiQG D ¡Š¢Jߪü¸K+¡Zæt²|E<*0—¬É>-£çZP S‚„‚£.„O%²ˆ ççØúßËí ÁOÙÖ¸%¿Žrøíw(_ö—qŽ‘è0"ÅKó<ÞvÃ*2“>ñD ”.ïÓu\À%.–._Žlª˜Ú¸½º4–ìÈqÊuTºå:ú^Ÿ›i]kß&Ñkl‰8-³F°>l²XËíkCèBœ®uº>ÜÕyy6?^x$ô—køÕúrÊœbDƒ;!4LOTÁ99r ã^H}ZBƒ (_í6:-”°®i–ŽOzÍBN˜1¯„Ð|û鿤ãás¢€ELÍŸNçVMÙì[…§(רéE¹Þdßõ‚¼ŒyNC¢L{‚Y3×ÏÑf›èâ\›réA%ê ]§<wêÃe?ÑÜÃÒP¡BÏÍìËéÀ1Çàq`Õ Uà<šÄ ×Ë¥ÉÌ9p ìzÊP¥ ×õmŽ Çè˜OqÕ¸Žšu›¡»hé(íï°ÙÞµ$"+uGmœ¶kÛ¶Žp[ëÌ;[u½[Ž@µÎÎz‘¥º6bC­r•ý‚!R´Íõ·Ý"ž#Þ0¶4CXf»Õº„Ò,QËŠh©Ë=d9<­5’C5½ÚTšVšïò3ìÃÞúˆ>'Ò”qçËûªÆ˜ïÙ¾y^´·»q?‰dÕ »ºÞ{ˆ¦qðRiÁÜy±¼ð6Ì# {‰zLÔ­4×õ™Äå.:¸l‡À(…"2D-a3Šp,³ªr»ÜMiÖ‚Ãm5þº›¦âFe©7Û²¥Û-çX™š²—•Õ¤K›Íšñp¡ÉŠ4äLÏ£]ÑZÎZÿR]>eù?­ƒy¶›%£yÇ“}Ë®ÀQS•ö‡ËŸû(”;Ê Æcã@'ÊýcR<&cËÛÄØ–E¼Â$¯‡2PD ó¨gÏDkx3uZRy$ ÃVW=ü¨ÆÿVOJâŒrD«»™²òüÐ÷|¼*<¡%ÕÙÇÙ´Í3­/o&@Ô w¿'„>sOÛ¾ôÕÍäþôeÊ”Æ$yø¿‹Óú¹ÔiÝB:I»ý r¤À endstream endobj 130 0 obj [ 129 0 R 131 0 R 132 0 R ] endobj 128 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 130 0 R /Contents 133 0 R >> endobj 134 0 obj 1177 endobj 136 0 obj << /Type /Action /S /GoTo /D [69 0 R /XYZ 72.0 720.0 null] >> endobj 137 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 678.764 195.53 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 139 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 666.764 251.63 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 110 0 R /H /I >> endobj 140 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 549.892 162.0 558.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 141 0 obj << /Type /Action /S /GoTo /D [128 0 R /XYZ 72.0 720.0 null] >> endobj 142 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 537.892 222.0 546.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 143 0 obj << /Length 144 0 R /Filter /FlateDecode >> stream xœÅUMsÚ0½ûWì1djU6¶iJ;é39$9,ƒ§þ[L¿ïÚ2–@Ò\(0#é­´»o÷Iì,¿v=x‡UfíZŒÇAŒ[Èsw!ƒvîBZïêMøq†ƒÞ„“ Ü[¹Eá§õð„Æ(x¶èkwÍá¹5ëů-ôâñ)¬­o ëë…ElJ䌉NÔŸÔ‹ ®¾ßÍoO§“ÛÅè ¿¬Éb@E0þ¨ÌššÜ›süy¤éòÀà:thé) Ã ÚCDÇ®MiÛ²vÔ‰è©æ£Ç³<¨¡Aû,†’¸hðójð"Ĩ@ˆ³Ý¿pÉÞt±ŽÝ‘ÁÔ±«>¥” 85õZNšÒMË•’,7ãÚñAPâégâtè›»rÉ8ܧʎB.ÃJ^Ÿ¬úvøç}/ímQ¤v¾Øq)¥½*ò$E^õã|P/ .óƒÀcm&/+¹­½„XâDíÃÆ£vxê­ðħ}®öqÃ<†÷é*Ú—I¾î–j#)©LÎ*%³­2kc’eY”Ý*©Œ'©tïŽÀã•$kÒ-—rî+¹0ùåR=å“`Yì—iokÙËä``$b,÷ÇÑ]¥Am˜ûª6ÈGóÀ$Ôa+¡Ú¥¶F²d½Q°D(YcùS‘cÝßrýº”:¾¯#Ì¥„›´*N˘ñþàÃ~ÔZð±ÖÚ./óøg=šÖ7"–Ñ¿ #ügBÅ ¦M %ß(‚pÏ¡´Î²=’KÒ‹9³þoæÌ endstream endobj 138 0 obj [ 137 0 R 139 0 R 140 0 R 142 0 R ] endobj 135 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 138 0 R /Contents 143 0 R >> endobj 144 0 obj 596 endobj 146 0 obj << /Length 147 0 R /Filter /FlateDecode >> stream xœÅYmÛ6þî_AìmR¬’z£ŠK€m7-ö¦—î¢Å¡Û²E¯u±%G’ëî÷ßoø"J–(i·rM)ÍÌ3¯*Ÿø³”?QÌÐz¿ødö(ŠòB³„ˆú˜h  |«C°†‚ý[ôË"_ôýâ×ßàaŠ0œ¤/N1ß.>tôË'ä³ëï"ð(û¿ TTT\üaœ³OΟtg÷Û]¥ÐÓ{°£uËG;ãió«hRÛ£Gí ­ÄíGcáçSNÐÃ⛻ūïD ºÛ´yy°ƒ9‹å Ýíѯ/¼àåoèî‹·wƒèf— ¢(u[c:D•Bè™M*²‘±I›ô>Ù m”Ã>G,Æ$ äû\3|wóþzy}uwõÍÕí[¤Y-õöcÐøñõž±¨ÏàO1 7ïŠuR ” 4©“UR T¬þ-Ö5ª·eq|Ø¢¬þ²B9+"‡>Å$& 84FóuyÃ3î°0ÆåqQã°ÛǼNþhc‡²J”y Œ˜´Ùdyºl è;€…CÔˆá=ùÔcÃ÷Ïe;PQNZ¾(Ò ÉnBóøDYåaTãŒèõTŠê¸«çN™‡‰iA}°«òá¸y]¡$OÑÏÉî(ªqÐêG8‚ì"~0â¤A¶S:Ø®©W”U]fùÃ%JE^Ô@uSô,Ýè"‚A!ŒS—KÝØLWèAä¢LvÙDŠVE±IŽÑµØ$àç Õªg€Ä êb@Ètµ¬3Nê3]¡âñT”)ª÷«b×õÊǼ8å­oVÉúãRä)îÕl5М8—åï™ZëæË‚á«o³z+Êa£¸„p]¢l3•âŒc*{ó}‡ä™È°ÐŸâFY…Æ % 0‡†Ç/pð¾¿y7®6ö¦X/Ñ¡¨ªlµ{×îypÈêcŒ>S»°)V<_âÌ÷päð$4It-ªu™ºmÙÕ]YȱOÏ ÃÑöêJ\h´C^ôÑ‹:h*»Nò–„£âwa—6Áš Óšå¼Ü2CVZº:ˆu¶É@Øhw³–ÏQ/à8–}IvÄ¡³Öû$œâÇÂÍæ h|F0ˆ"$"®€Ì£.Nz\²PàÓ¨v¾&­sÍrcIÙ¦ì¢QyiwÆÏÂPVŽì^uÀxZ61˜(&„X¥¨eÞZVo³ ÛÕ²g²ªµ#kM=e»]T")×ÛŽ˜–Ŧç¹'*Gƒ•}û g"‘-=†c™‡©LM8HìÖê±¥µJ³ØeUÝ®´‘cŒãˆaÊ aFàö8Ķ.òB/ÚhTãýˆøS¢Z08¼í"iÉNQ›•ií:Õz9ª4ŽpÓ"çÄwÀ˜;[}/žboœ¶Å`„øJ/œ³ÈIØTbÜëhwÒREL­U¼fÊN /é¡945\æS FÙ”DfŠOG9žêE‹ÿ ÊYÀ,ò¡IÁÉÌÂØ¡Kp¯ÇSІSìz±jk]­e[°IUµ®n˜è¯Z* À1rõxá;nôßl)V÷Úrªãz-DZÁU£¦£Is7Y }ÀÖΦ8:;Ïã˜Í2´PuÊÀ]qò”+xGDÁ!b®˜b`À!s°êõ©s†d˜ú$†Ã¼âQê55(QM±Z݉îõ¤;`´ÈöI½ÞêŒÒ¦ÿ+Ú&Ûœ?YH¡½À-f/—CçÒÊ#ñkKÙ‚ƒ&^e©(EŠí^'øy1n£Á³täS@zº•¯–påŠTéh÷[rârMcLL¤…C-3w´ n þqAl´gU‡cBá˜ùLæ.sHšÌ7N±6ª!òY â͹o:à³`0Hû Ö¡/š 7*IfÂÅ8ŒB=†>;\ ¦¸Ÿ/Y qÁ@<ÓOô¸qNGî¹Mo=ÉHj_´Iß”‘£jB6RñÒB਩M«ò¹´K“2vaé}¡fA½(ÅZäµ¼uš ;ÅÙΨ¥7²ªÃn稃­E¦Žfõ»üÔ¾•§N”ùq¿¥Ã+0%œ{E_1øyGâ½¶Ì›“ƒŸ–ˤÙOÌo%À ÍS…›ÅM£*/. ¥¢ª´ë J²Þê Wñ¿|¼Ä²«@:,‡Vqn¹òÝhµ…>Ž}ócÈ;ûýŠLq˯$uyÛÀR%JîTÙC£HŸð=Á‡0ÃP)ÚÈ|ú#Ùví¥Áõ1Á`…–ÍãÈ ¹?Ÿd—›²Ø/åÅ}yÿâ"…ä¾@¹8‰*Ûe6ÔÏýKôõþ±ú´»9ô¶î;×ôúæ{e¤½RBœQ8Àhªêi˜¬Aê3‘ó!Ä¿ýýÛw·Þ-øüýµú»ýúÿ§Ïaš¿þöú¿o†âù¤oÑW©þPi/x_¹`´£§z.ƒÏ‰nžíÐE- iàL­#a[zñmî¡#¾ |‡ï.^Yi£á“:Á†Ô ì ÂÈáÆ&ºÿüñöîûŸÞÊ·d/Îìš¹ãÌû™ýã÷£õ4†l&Ïz5|:ða_mp*.þr¼CÏ•”ÑnÜê?,þv\IÍ endstream endobj 145 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 146 0 R >> endobj 147 0 obj 1969 endobj 149 0 obj << /Length 150 0 R /Filter /FlateDecode >> stream xœÅkoÛ6ð»CÄ,E½¬@º¤ƒ‡´XcC×ô-щ=\INšýúERÔƒvÛ}è’º;òÞ§»S>/Dàw)aLQR,>+šƒBŠÜ@‘ü9¦>*‚}”‹[€jò÷è¯E¹ è·ÅÇOp˜" O 2×1ß,Þô‹òÃõ-pú¿X lè²Òå…Â_ˆ»äŒ|ŒO‰ëé†Ú)t% (R·8ÊU¤ÕS"Aé|ôƒ7ˆ=ŽÊ眠»Åëõâå9­·¦ÎC(8¢±ø¡h] /ÜðäZÿ¾¸ZϲÿƒC6Ë¢ÐÝ;¦CV#Bˆ3ò©Ël¨|’.½c—NYbàEˆÆ˜¾¸I†Õ»Õzuq½úûjyy±¾x}qsµ\øã I)=¯…8ˆÁêys)·”†S†øZ•Y›±<û‡7ˆ¡”µlÃŽÚç]oh±ßs0‰ È ¤œ7û2i³ªÔ<‡CÄØw¢8ª›ç²e_4clQæûÔ!Ä UÅ îgâiäYnf½KíÜR8‡~~àÏhDšˆs=jÓüË+TófŸ·_wÕq}¸P~àHî‹ún_ð²…X—)ú“å{Þh9à·Åõ€à€x ^œN„ÅdK‰909æ¼ë{ŽNЬéÅh¼‹‰†+ ™èõ$̱†™ –OUj´y.6UÞ«âeÕfåÝœ«¬žÊ©AÓòŽ„tâȆ%K^¦]ò-ƒd4ŒnÁ½GSTmÑi*OÆi?Åù"Ʊi츾?LðØ’ÙÕ« ´Öè`ù:Å‚¡{ýæìïVׇs‘c¬(Ûv÷9bâD¬my±kÑ–eys†ªµ¨6>e Ç_/ZJ=ì¹!^àIE—¼Iêl7|½­-Í‹±G@¤ª¦°ÚŠä‚jJ–žDtú ¥Ùñ$Ûf|@Ú<øð;âvcÛäÜ(ÀÔƒ½1tÕFt¬æ,¾ÆÑ„Ö±>›ã•LnÞB‹mîè¼x†4ÜžXDQ:WzþöÃÍ{›^×›é=´ƒZ•yÓ½z…~­Š]–‹6p}ñöõåº}ñÓùoQ¢î‰¤B>èíÉùt5‚ýièF‚×ÕnyÍyŽÞTuaN# ,×"K´Ö–{ñ4PßW >™ ôܾy±E¾:€Á!4ŒÜÿ’_Œœ¿Ý1ߣ“{ßé˜ïÍõu,& èëï¯û¤ .Á¨TkÞMÿj»åIÛÛóè7.õ‰C©3ú¬Ç#©Ã‡›žÀ“ª†¹±«ÊT}¢\.BÓúm’tÇðh[¹P„ó¡ÝÑö%´%s£ÕÚæB³̃ ßooõb'vŒ‘>l¨kµâH,a#†Ç*ä†ÀÊgƒ”ûbÃkƒË‰¡`ù¥¡Ñ&KR¸LÜÙ@îÀ‚”·¼.²RE¬£mjuÜåÁ0gÒæÂ²d°4#Ý_|Üö£=¼cyöÀ5ÆñÖp^1]•ž h ûŒS&Uª¾>Âòü»™JÞÂRõ0äÛñº3³é/ñ6Á·'½u«íàRïÿŒ0º endstream endobj 148 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 149 0 R >> endobj 150 0 obj 1561 endobj 84 0 obj << /Type /Action /S /GoTo /D [151 0 R /XYZ 72.0 720.0 null] >> endobj 152 0 obj << /Type /Action /S /GoTo /D [148 0 R /XYZ 72.0 720.0 null] >> endobj 153 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 216.148 270.0 224.548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 155 0 obj << /Length 156 0 R /Filter /FlateDecode >> stream xœÅWKoã6¾ëWð˜1Ë7Å-à4Þb‹`Ñ ÞÅfŠMÇÂÊ’#)ɺ¿~‡zÛ’÷’Ú†5"9Ïo8>yøNÜC†ï©£H3ÄU5$¢3‰6¨¢%ŠÜªÁj å" Öèo/öúÝûò&—ˆÃ«GÅÌwÞmG¿›!﮿k§ì±ÀÙP RàÂà§qÎÞ„d¦\3ÞŽ y9#¥n7U‘®ž¥!%YúS>úAZ7Èp+ßO9AÞÕÜûéƒD” ùªÍsÍaû̸Có úrÆÈùW4ÿÛÍ{è¿sÈz(:Ý3`: êBèžO²ºò©téS°±¥S1>b%Ýz¿d¸¸ž}˜~¾™O®§óéÕôn6™ÿóçì•BVj(&Ø83}!÷ŒéFÆÐ|mÑÒ®‚ç(GË ‚Ì¢|·…¿=gzÀ’ aªöW†ÁCÔð—2XRßMMÍ=[4½cA3û„8#K¶i¼Cßìî5I—(µÛÔf6ÎÃøè%ˆÂeëÒC°ø6±ñ%+T«P‡*˜æX€Y†0ÞWöÛÍÝíÍQó8á[=¦K”¤BÓc¢.ÆWR÷y?}QÇõ'~Ê$¾ XÅô1ó0ˆPÅQ“*–\#¸ß³tD£ظ|Ñœ–l×6[¤á6“x vj fZp±Òç²öM ¸€Î^ŠÜi^À5¯Ã¬»°ÌÏv¤; ɾìÌÄ-½¢¨³6FC ãs 1âT 8–±ÿµ“:E'ùXös­Çäµñòó¸ñ±"?ÊçâIÛE~AÆØ;Ötã¶¶µÉÕAJ˜ëjT hæìʰãÀ ­q鯡WvRt‘Ø@p„ã©/mƒêynSÜ©‡bO„í\a%(!JèªdÏ£Éí˜ÁÄi“”WûÐ%0EÀ*ªNqG'ít‘¾å|“Ùîµ?Š?õvƒ¦L«<Œ°1ÖËÖø¸"aûTT½“ŠÉ[F28&¨pG—PôŸ· |D\Ýô-« vÌä »¸š¬ÝV† p¸ ¤  :{ ‹8–/ëàÅ6/eE*Èlkáj×N­Ûe#›È‡ràÚ'Hß„7‘RX»ºÏó£c-ÔÜËæ¥}I õhc›Ñdûœn“¬õŦigý^hÚUYø8„ŠKþ}T /íò„SZR,x铪é™}6ÛÈfc&>ö]¦¸¨‚Q}îÏ2›¯ÐEUôö3ùý¼ÙeOÑýy¿nrÈÀa‘¿üZ± 0(Çì8¶•C*ÏÖ5¸þíx &1SÜU›ªSœ®V°…ਾÚõ B@‹)¤ñÛŽ<‰í  8hccõíäÎZ4²¤¹£´W§š/#‹{BqGèáO_tjíu'„u¤t· 7î’¬¹0¾äu³˜ämEDJ‰ aкõ"Rè¼õ~¥«Å endstream endobj 154 0 obj [ 153 0 R ] endobj 151 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 154 0 R /Contents 155 0 R >> endobj 156 0 obj 1151 endobj 158 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 204.148 270.0 212.548 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 160 0 obj << /Length 161 0 R /Filter /FlateDecode >> stream xœÅWYoã6~÷¯˜·$Æš¥HêZ œMÚz‘ÄØb»ÙY¢×Du8×ýõIÔaGvRH“"‡s|s’yY@ñwR~\ŸA˜Œ Í—w ÉvÀ„Ù€YÛ—\½kVø©™p±‚ßGéˆÂ/£¯ßð0ŠÛ=TW ßîzöËúæöû¸Åþ%†*+U^þ¹¤JÎÞ-èþI/q-½£VyMCJm»<ŠM¤Í·R/kêïQ?h玣ñðíŒSø>ºœ~øÙ‹Â|ÙչˑB<æ—? æ |=gÖÅ7˜]ÏŸeÿCö,‹¥íÖ„ŽYõ(¥ÖžOUf]ãSíÒmÈÚ©˜O¨c—ü^-0žÝÎæ³éÍìë«ÉÕt>½œÞ_Oæ_>]ß¡ÖÔÊ3Œ pKŒ=×ôÀ˜{(ÀN À*4dKâTª´ bõ·Œ t° z·–EãŽ;àŽ°õ)ªtj•Ÿƒ\‹¸ ÁñÈ9>±-Ï÷]ËoDã„9Z<?Ÿ2TçÛµØâWyñd®J¾íJá"—ë\2ÕȹØÒg„YŽ´u–F*ýÊÝ6Ë#ò²/],&Î0ƒjVã€Ê©F?à%bs×÷7Y¹Ý¼Â¢+ˆ_ÞåV-v%‹0Wk­²ôTü,ß'ÌchìÍWª€ àŒ¸pþdò×zg›5F£Õì·+™Ê'™·„£~ZžC¨mÂ]wA—´I“³‰>UœSÔÇ)–Ð7>Äêèa_fì ]µÓJ=±n¬ìhË:°¿ ŠôL£œ`ÄCýq.ƒh×îR¦í¦_°“ï:E»Œ¤–y¢Ò>w§Yש¬7M*IK™¥=ΠÖ.7'ÝÚt@»o{Ûc Œ¢Ôµ×…€øÖ›b…ð³TgP2Tí[hô8Âö…SóôF‘Ø«Ç&<â‹RG¸µùÁæd;”B.#´Äl[ÜÌ­e²Ö ¼$‹ÔrW¡|ª¦N*Æm›lŒÉ&Ö%øMÉe•…\O*Ûä¯XÈÄf8¦=jÆèõ_A²Ž»Ñ;498wˆÇËÑË…©{óóp^H½„1b Ø~Sá}²+㇋çäÂa•?þdÄ„zDZÎ4Ž©8j\ð{âÿ¸×Tûv‹ñ€ÿXÑîÃùûß¾ÜßÝ t8Z/'\p> endobj 161 0 obj 1127 endobj 163 0 obj << /Type /Action /S /GoTo /D [157 0 R /XYZ 72.0 720.0 null] >> endobj 164 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 515.892 288.0 524.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 163 0 R /H /I >> endobj 166 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 503.892 258.0 512.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 167 0 obj << /Length 168 0 R /Filter /FlateDecode >> stream xœÅVßo›0~ç¯ðc÷lóÃ~LµtÊ4U«Š4mU(8-*48Úº¿~C0!¬«4uI$ŸÏÜ}÷?›<;þºõ Š’µóÜú )bAëòDXð=®XrØû{oÈŒO{ v½”·û׎¦c>fœä= °Y õñ®àÓÒÐ’ €ù@ŒOîþ;·l´‹5ö4ô™Êâ<û«¬,Ð)rÕJ8ɪގ•’ë’©å*¬IµK)Óê¬w©GÙOL·Î/u5Q`€TZ«ø>®¤«^6²Ë1âÄÀ›NqœÏfW=ÚdÊB•¥çY¥,¢ªÜÚ™Õ°YÛI×Tj÷œÂaÓÉÔЫf¸c¨§Ï"Íh@t*r¦4Ó&Ï|µ’I½/÷/{Eö‚ÐȇCsÓŒ:6Kå*ÞåjXÞì¨à5@¼`¯¸q,”&Ýt+aØ'\_ÙD˜¼‹Ÿ‰ÜÔŽõáÈÔ®Ñs5)];a!ærÌe¿jö3À¢VxoËí¶ÜöÓVKf©HÊ]¡d§‹Æ™î¶YñÐÏ;I™èñ‰3€æ”M„ÝÇÉ“+ e¿ô“*{¨™K¶ê,-jO™&É«çcª%ž8hO“ó/tJB®/)ÀãÜDÞH‰æyUW)úm|¯"ñÏT4€¡¼æÕÓðŠN©G±Pÿµ &åU©äeI+d‚œv!…Äæµó—6x endstream endobj 165 0 obj [ 164 0 R 166 0 R ] endobj 162 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 165 0 R /Contents 167 0 R >> endobj 168 0 obj 680 endobj 170 0 obj << /Length 171 0 R /Filter /FlateDecode >> stream xœÅÙŽÛ6ðÝ_A @‘»*QGÐØMœb‹tÓfö¡éƒlÓkµ¶”Hr6FÑïP<$K¶@šŽ8œ›3#}˜„áï¥ü‰SŠVûÙ#(¦ˆEÅ#D€r´Gæh'wõj øQ›Ø¢_fÅ £ïf¿þ×Áà k‰ïf?õøË'ø‹óïKÀý_$2´^iýBá_´Î9yÀC|ú¤ç8‹ï°-C¦p€Q¼å£¶´þU‚(Pé£~'õÀØmG­á—cŽÑýìz1ûæG£Å¦‹ó˜&Hh*ÿP´Ø£_±ôñohñýl¾yÿ ›läEÉÛ*¢ƒWŒ19Ñ©õl¬uR*Ýf{¡”rØ LMq¹?Qoç/ÞÜÞÎ_,"³› ‘Bö¿£4î¤Îè­¸u“-wy½5j¶­Ê¢«&/ ´̓ÊÐ:ƒMY-P¹ü¢¬X£¼©ÑÛ—×?ÜF›Ø¡MHœb`)–¯E{¸¡™6\”œ$im¸»cÑdŸ aê`Fpà$š0Ô¶ÖHBÇÎJh͇¦cÎs¿þC‘‘$CbcÆI(¥.fÓ|(uI'ªª¬¦™p§F&‘K™MY­<š¤.ôì9ªD}Ø5çýOXÄQÁJu\U÷‡½( îdüýœí¢ž–ZÆCD†eÄǑۣ$8r- 1l4%²Ár¶ùj‹Öb“Vµ|Øô7çÅ:_eX£å=ÑÛ.Íã'_þ„<"z+Jm ¢,.‹Üо<4\eEQÚÕR ïi×40Ø”‡b 66”_ÑG“HrœÌ ƒR"å²Üμ½y=©/eÌGê%  !@ÍHäÈ_g(id(]ò(Ñ£kLqBבF´a¤aHzÝ?Ì“9{Ó;ìm6Ï,¦W¿,n›ÕÝb)Kš]íʺ tÿg~&ID!8‹¥®³¦íž2݃J81æ„™¢Ö¿kÝN]!ãÛžK'O.·°k}X­D]o»Ý±»Å:8ÃSÈYÙ%)Wœ_ŠzUåïûý«Cb„ŒBìã4Ö-’á+ýÌecè¹wRP˜G²Ç$Ž£ÎWˆ0z¸w"è#ÆôVUÌʃh3Aã²àÚ¥â^ÁpñˆjwT¹¦t™ û¬Èî…¬—UëËA¬KsÂ=|ªC#öALУ7…µ¯/,b:üášK(ƒ Êç{ŸåÛÞé ¬Ds¨ ¨¯!{+›)øcVåÐév§ÙGç×¢éŽ+'âb¿Èæ€ÅÛFZŸñ–7ò² qù‚²6†)C¯â8â3ÚK¸´³KË¿µƒ3 õ"Mï*`†(VâÂbšmRÏ Ž3WpûÂMaן¥9Md_÷ gñ¿Q±ÐGï×½n*Hº¾¢m1nëG@g4Wî…ñ€¿ÉaÝ„•½U“£]ì³f%g6³öÌ"ú,"§>;ž5ÅÄGo%È;aêòp¿mº'…õ-ÖÂ0uv{ÊûÖS#cXÔM·¿(O­¢¯ÅJ‡éy:Ðh{ºv¼ðÔ4H!ó0…©f|È™z‰Ïp&!ÈJ&.ùÏg=4z”U-Ëf‹d§ì™Y Ã! nOñ¶°Ð²SÕ±·úHu~à ÕŠõ*eçñËL˜’‰AQùäÁ>™BúH¥(¦Æ¸®ï„<›ÒT·O¿¨+4µeBÁ«CU©j¬Ö½{Toè·® ¥:WëÆU-dßzaWm¬@ßOÌ@SE¹ýóM½Ä$¼Þ bòt~`iê8Ïç0Æ©åß3]Þ¸\;_¨VàÂí8ë‡ÿÓpÀ?W³äˆ)pÝZõ&zÑFzo³Ì>»¨ïßC÷®Ë£FÞl:Øãg,b˜'Ü!ß?3/qÇ¿¯æôUÕ‚$¡lç"ÇiÞ«"â>Ò ›šá°]œ ‡Ê§Ã¡Â™Ù_¯—bè¿‹>³q„87¸ÃvŸ5 …,‚QšÄú”ù§lÿ~×½âr½ñ c$²!æz†wµ‰að:¥zö}õí‹×w?½¾„ÿ7‹ùSõsùòjqu}u7GO÷b_VǧèÍó[ôg˜¼xu=¿â=weæôøw]Wüîñ˜€ãô¿Ëó2 vÊÃåPÁ#Ll.õÞkaŸO8'g #ú æ]¾h¾ÙÈYÓ7£ò8†±š¥q‘Þ»‹N;h9 L…S¦àªÿ¢~Ýáuð«…s ÑÏöÙ±[,EÿäeÛóX„zE£ámo§¼’vyŸûtsÅ“t ¾š>#"’qÂ0ô ú#ÐUkîöªýÔ}Œntñ©úFêþ´„Qe½ÿai*MÚMòïßgìÊÞ endstream endobj 169 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 170 0 R >> endobj 171 0 obj 1906 endobj 173 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 162.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 175 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 180.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 176 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 602.628 222.0 611.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 177 0 obj << /Length 178 0 R /Filter /FlateDecode >> stream xœÅTÁnÛ0 ½ë+x\Õ(˲ìc[¤vÈÕÀA®­´+]tûûQ–šØmÒb;¤q$õÈÇGû‘ @zÎÝ¡³Ê5{ >:™—J@Ä> endobj 178 0 obj 457 endobj 180 0 obj << /Length 181 0 R /Filter /FlateDecode >> stream xœÅX[o›H~çWœ§UÉÓ¹0 DÚ•œÚ­²Šr3iµjú@`£ÅàÜ6ÿ¾ƒ¹f<&n”ÍËœ93çþÎ7‹V£ò&< áÒúVó Ì©YÜb#Êa 5Í!)OõÚPêVRÄ>[©…á£õå«ÚŒ+ÖÕm…gÖUÏ~¹ƒ_Ý~ßFèÿâAéö*ÛºPõh[œGÜÆwz…kùwkU<Å©l—[Iéú^9R‘U<Õ}o¸ ›óXGøzÆ1Ü['¾õî‚ÁŸw8LqK½ò¢à/áË›¼ý þßÖÔß©þ+§l§Š¥í6庪ª‹1&bÚVVÔ1U!KYeÈíõvxyÞ­fþØ¿™A%Óžt]DEyHDn)Úyoè<\®ã´€8gëePÄY Á]¶) ÌÒT†…Œ Šà.ÈeŽç…Áy› ìa¥Ø©ؤa©®‘ÙŸ'ÇCœ¸ž'H§ÙCZ?AÏ`Œ`Q¦t1V›ƒí¥gÊ6œÌ‹ ØäÚIB±IéÙªŒ!H ñ†`Ýâ:Ñù&IöF@‰ÑÚŸÁÓÙ"Œ#ÌU¢mWTrãõýf)Ó"‡ àSld¾ßÝ2{ÜC‚¥Âa»Þî Ó¥‰1ÜeY"ƒTA'ŠC…œô~,d±k(2XmaDQ\'Pa(‘}œ!ð"96IßK·!ÎaÙCX¨Œfrèüôloq2$ŠȺj:^63弚È<\Ç«>Ä=M¢Ž­Lóº\Û†SqÂȦj޽é·^ˬz°]ª¬v‹p³^«r'=VÛ¬-«íÚž–¬£Ôl9ŸŒ¯'£‹ÿòÆ?BÝžß·ÔèD¥\‹rQj„îJ”&]y*#yGï…ƒËsÔXs¨IÙfC¢í»‡ŽnpÚ2Ê^ëY¹]fóŽîI/Uçô¢,A3[˾å"ˆÙ³¦!¦v¡ALµ”A¸èé¨ÁÐϱ6Ë*2¡åbÛÅ2: A¨ã BlÏôîªéÏ`¹JºQdšã SõØçžëŠÚâm=ŸoßîúǨ£~6»:ƒê1y c{„Qnòc,Ž™gPÂ\MÉè™—A7ÇšnõLšŒýñÉx6ýòÿ¹Ô™×Ó÷דÓó;²R»£'ë=ö®çIÉ"Ë‹w…T_+Y¬³ï¥›Ë‡ü[òØó4ní®^¸!í+Å»_˾‰aíž^Ñôò,üWOh·‰¡¦šÎîÊ¢»P«é°vª×ôàx)Õx8ÞAŒr:.äohgzU_16׳޴.¦æµ]=ÒÁæuÕÇ Ä{©€Ž“cvŸÙÓ—gÓ‰:5>9›Î>N?ÏL…Sïï'3àü™ !E½ÆûÊmCF‡ÃáFùï̺áyq¸QÇ£gŽ‘Ã FÏŸ. ‰Ÿ4êé@úO°;ø‹’xȱO¨·’ú'eI˜Îçê%9z]wl±R'õšßY*Qï_WÖ/1ÍNÖ endstream endobj 179 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 180 0 R >> endobj 181 0 obj 1142 endobj 183 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 645.364 234.0 653.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 185 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 633.364 180.0 641.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 186 0 obj << /Type /Action /S /GoTo /D [169 0 R /XYZ 72.0 720.0 null] >> endobj 187 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 621.364 174.0 629.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 186 0 R /H /I >> endobj 188 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 609.364 234.0 617.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 189 0 obj << /Type /Action /S /GoTo /D [145 0 R /XYZ 72.0 720.0 null] >> endobj 190 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 597.364 198.0 605.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 191 0 obj << /Type /Action /S /GoTo /D [179 0 R /XYZ 72.0 720.0 null] >> endobj 192 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 585.364 156.0 593.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 193 0 obj << /Length 194 0 R /Filter /FlateDecode >> stream xœÅVKOÜ0¾çWøXküLœc‹ j…¨V¬ÔâàM¼KD6$ø÷'ÙÝ?A[ïÛÊ;¿’ˆ´Úô)’sÂÃC¤0gV„œ­vèîËů››Ë‹ÕÉ=Zýô.W£88eÿ!ŽeÍ¡&^W—ÁàºÄ£ )ÈxgPþNßkk‡¼Ñ¦ñm·Ò¶^íÚiÄ&žfuÆAú0È0Šq?|ªsw+4XZ€ gõ?9e“*Zßî`„š´ó :A "D_t'Ey–™¨Jò¬SUy/>˜NŽu¥×ºì哉’MbâN³~ïÄ&mçW@ë3Æ(V‚Â8›pìé,,üe§„…* þ¤#aÞ’²*û¨ÓÂèøýl|œXgƒ3Å Àd›é45qCc˜[80ö©£(/â$Û"H_6g(tNñÂé(Ù,ÚÎØ©¯phm˜?C=éBïLeŠ3¤K›2*’5I¯ó?ïQ¡×a ( AGà¢Ã²ôBÙ Þƒ¾¦eÞÝ„¾!¾ÀAóE©1üÈ–¸jl➥ÊÙKà,xœ”-¾ S©c1 óHJȱ˜§-䢫÷©²cÑ7IÖg׉ˎ.]YéêeX­ÚÐÝKÔ§XRø¾4lnòʸ[Û²R+Âkß«ƒ·É÷1‘ö.9cû”ç©Ó[H™"Ňn1 ±°ÿåÏXïô£YÄf£_ÒÊ}“Å"R„s Íû+L¤‹íËÎd0ÊìlnÑ&åb„¹ö\ð´QÏŽÔà9ª'ckìOŒ¹ÄÔ ¡æJxq}»¼v{öÁXÀqáϼU&+í˜ÆƒÖ[zçFdÁ endstream endobj 184 0 obj [ 183 0 R 185 0 R 187 0 R 188 0 R 190 0 R 192 0 R ] endobj 182 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 184 0 R /Contents 193 0 R >> endobj 194 0 obj 721 endobj 196 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 604.628 180.0 613.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 198 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 592.628 162.0 601.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 199 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 580.628 156.0 589.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 200 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 568.628 198.0 577.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 201 0 obj << /Length 202 0 R /Filter /FlateDecode >> stream xœÅRMOÃ0 ½çWø‡'i¾Ž ‡¡i•8 e+0ië@-‚ŸÛt[»QЄ4ÚJ¶ìúÙÏÏoLÒ;¨Œõ¦KöÖÄX Ê4!m@D\jXBãkXTµ¹öÈ„ŸÈy;–3„kvÿ@É |0Ü…«‹'lÜê_eðèýžÙyÂή4„äi»"a¸‘÷ÞZp\I_=’%ÜŸ\ÜŽFñE_.‡Éð|8‰'§ܰ8épRBþ§q=C Q)-é³¼–»“Ðv3­SØÄ·Ñº¡ 1Š„ÞUjÑhר0HpŸ`{yà–¶Ytoã¨ÍûÏÂ*Šp×9izÕ?òÊöTìJ¹pŽz~—îÝúl^LWyžMËÉ mƒÅ!¢ØÁQ†[§(áuŠ?§Ùk9_å)M;/ßÓÊ/è7‹¦Yàh A; F«<ãëŠþÖÎsM5ÞŠ¦n’e0\« ƒÎJj…Uýi)]Pî@Ðߥ?±(Óò½èŒÄ¡€Oó|6˜¥eú˜Y ÷—[ÖÑ•jÄȹµ’eö£ö%×Êz)·'~Ýs̾ Éo@ endstream endobj 197 0 obj [ 196 0 R 198 0 R 199 0 R 200 0 R ] endobj 195 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 197 0 R /Contents 201 0 R >> endobj 202 0 obj 433 endobj 204 0 obj << /Type /Action /S /GoTo /D [97 0 R /XYZ 72.0 720.0 null] >> endobj 205 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 258.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 207 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 509.156 162.0 517.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 208 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 497.156 198.0 505.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 209 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 485.156 234.0 493.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 210 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 473.156 180.0 481.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 211 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 461.156 156.0 469.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 212 0 obj << /Length 213 0 R /Filter /FlateDecode >> stream xœÅUMo£0½ó+æØ`ýØ>mv¥•¶RT¤ª(1-+iLµÛ¿ÃW0Ih›=dI$mfæ½7cóâP øs›A(éÆyé×(<ì—‚¨ï±6ÐÛÍ[–Á ‡î%4žáÎ)ßûÜ\A‡ß9 ×:ß:++³C.žŸÀ“³ˆ/ß âl”ˆûž >"éq¦š‡A¼û«¯Q-¢Û¥{ý\^?@üÃYÆ6œ²ÿÀfÕbhá·5fø^[èÉFà“éŽÕûõqµMÈ»5\ér7[E_µ~ì€tfǧgy‘±YL»â¢ÉçBp\ñ䤘œ­þ…%;ªb“{O¡cU%v3pj++zN¥Û|­a™e:­MG®<†PöŽ7U©½Ác>a(¼}” ½_ÔæÒkX¼íŹ`&É=¿ãÓrQ‡`ÈÑù\'uò˜í–ÉF»Ù®Ú¸f«S«V©Âq}D‰·!—R½­óªLPñ¼~Mû]¨ç› ¥|.»wyQÀ5¸ð$\™ü© ¶Ÿ'åhëÝ®ÚÓ<íúY“êñj7η‰1¨äÓÌ8Àör†…åaË0<Áav–9“ý%¡\±þ6ÖV§Ö6O n©sDlmV¶o[‹Ì€Ér®&ŽØIq‚ðX2-*ÔÏ~¢©Äï„"Ø)œöHkˆ SnfFˆ§|ÿœnN«²Ä*Ÿ¼išˆ”1ËË‘äl\æÿ#RKA3‡çF_çæ#)|ynPS'õ«ùüÍÀdà *©D0Ü{µ~ÿ¦ÄÏ¡K qtU¶9WÎ_¶© endstream endobj 206 0 obj [ 205 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R ] endobj 203 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 206 0 R /Contents 212 0 R >> endobj 213 0 obj 633 endobj 215 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 172.004 162.0 180.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 217 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 160.004 198.0 168.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 218 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 148.004 234.0 156.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 219 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 136.004 180.0 144.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 220 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 124.004 156.0 132.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 221 0 obj << /Length 222 0 R /Filter /FlateDecode >> stream xœÅWÛnÛF}×W ܇:AµÝ;—F@©AƱРˆó@K+‡µDÊ"Û(úïå]$EÛ}peZîrfΙëêvÄ€âߨ}y>‡ùzt[ì1ð8]l) L®` ÅZÁʽÕXðr…_ùK¸ø_FшÂÙèë7<\E»m«Ë„/Fç û¸ý&Áøÿ‚ÀaÈ¢’Å…ã¿G²àì(I÷O«öëÝÌ È÷p'·íŽV…§‹ïH¾ÌùäßyКí÷cÁðåŒS¸½~~§€Q˜-ë<÷îÃ}÷á0[Ã×cÁ^}ƒÙûÑtÖ‰þ »¬Eg»"ƒÐ1ª†RÊö8e‘õ N9¥ÁÚæ¤z| pŸP­Üû&8Ì&o'ÓñìÏOSÈE+&8aí ­»¢—œ{m9$g6…ô»…ôac!^B‹ ®‚Ÿ®þ²ó””ؽì’êST§sug6²ÛpïvÑ< 㨔=ì.íÅŒï{¬p×ÅC”÷¥ ßc”QI$—ŽQA"û´xÙ}±¤6vlÛ~Ò¼Gs‰Q´€0݃¤ ÝAøœé+¿¾Ñ`r F¤@w©Rv²½Þ­m”&D ø#Xílr´óžÂ:b¢¡¢ôÊÁ$eT÷ˆMÚ™òØSiëÒ(K§ú¼Þ›¯âÄ.ÆåiEÁô$ñ)f¬2…¥¾h9H'pcîâí’‡õU¼‚…â4Œ®1­o¢ø.ª!]ó›±äq§sʈ¯¥’Š"Ì6™oÃM3Ã{+›Kloº!øÙ¦»m”ìUÜ@ŠqMŒ‡Õåa_ê*{²× » v«´Êä×}ç]€ Rí¦åD„l‰4ÛÛP°„fÄÃnlcE/ ¦Ë%z>JTa$Ñ8jÉqdŸ’¡I†À(Y”`fÍ.àêaÈ¢D–ʨ†àS-"Iáa¬œ9Óû¹ÍJ1ÀѦ»À­éJ¤«°qÔ:¾„+ŒŒ•G 'áµSV=Q½¶Û-v³ê1\ÖkWÔÕCÞëçM`ßkèLn\øDPì'y—ãí€å Å.Î{ä›X·xgIm“gnT´ùškÓ ®8ª§ªÝÖÂñž`7ÿ¥¯[ÀæÆP¦(.ˆÂ¶Í•(¯ÖÂd•ÄÕ³¾á¡a% ^f²_YÙ¯ÓÚ("ön«EWë½²:Š>Wã2Œj’õjþ‘6<˜ÔŽSã™Úaò˜+p&> endobj 222 0 obj 1141 endobj 224 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 508.628 234.0 517.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 226 0 obj << /Type /Action /S /GoTo /D [94 0 R /XYZ 72.0 720.0 null] >> endobj 227 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 391.156 198.0 399.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 226 0 R /H /I >> endobj 228 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 379.156 258.0 387.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 229 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 367.156 180.0 375.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 230 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 355.156 162.0 363.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 231 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 343.156 156.0 351.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 232 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 331.156 234.0 339.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 233 0 obj << /Length 234 0 R /Filter /FlateDecode >> stream xœÅWÙnÛF}çW Ò;(G³“,Úr, \·®E’ZÙl¹È"UÅ(úï½CR$ÅE‰Â•r¶{î¹ÛÌèÑ¢ˆÀ×6/Çch[ÕEC\UCR!*0“(FU[¢È¬j5ؾ¯r4Ð{+±zc}ø“" °³H®ž[·-ýf†<»~‚î­‹…5¹’ˆ´X5.â.&DB‰ƒ\Ì™g> -bôáìêíÍ¥}9]L/¦óÙù'´xgÍÖpÊþkn ý"Æ ~.}0!9œi%A=ÞŒ y9#¥n3UQ«Þ%‘²YÚS¾Gí ¤mÅaV<«òñ„p8Œ`÷ ¸þ3»¬E£»6Æë#\“ÔÒ˜¢TiËdzU˜vàçþŸiô"ÐI>IôNga<1ÏKsÛ0Œ`®|-q~z…¾ûñõõüöÚþùwxþP<ërA WÌ<úZþóªÆY­Çj’ëxù¹¦ãœ„çôë/óÅ›ßf†XÓ<`Ç=vÉ.‡ØIõ%v»Ý¯ãl…Ý%Š’0"«Ü>Ù›·×ý…n×Ó]í/_á{]—þGΠ¤ëeT.š\A¥À&âÂ=È:HN°ãrB„S¥Ý< 4š­Vz™g{ù^íuÒÁDAÆ VIÞ¤‰Æ_¡Ò•XR×óê•‚ÓB›ÐÅS]¾Mõ9M±(Kh¸|HïHX¦IR€ÖáÈZ[C2N‘ÁaÃ$6ÂuK¸Ùç¥^çašøPàa¾õMû¨˜bXrüÃ+Œ÷a¡sd Š):ËÂ{V÷ý¤iëÍ&Ý4ÝtÕ´ó§µnzË({ŒìÎò°µÊò Dø+ª†=@òj·˜k¦Q–— §.ö„8¥÷ÔìÄõà¹lp9ù&\{µIc;[ëå¨ÁNÖfÕþ1 *Å© _B„,:1Ëý|›:'Gì›6MA%v˜ò\Ï‘û!×G÷H!† =!žã”" (¹ñJ™¿„9 ÜÙ¦$FRâGê§]º ¿¹ßÆpC@yZsé9z.­¹®q1vp¯|G1•ï×TOÚ“˜™@0F¤‹ŨjÎŒ0¨†½uHµþœë$ƒC·2àÖúÄ T endstream endobj 225 0 obj [ 224 0 R 227 0 R 228 0 R 229 0 R 230 0 R 231 0 R 232 0 R ] endobj 223 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 225 0 R /Contents 233 0 R >> endobj 234 0 obj 987 endobj 236 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 573.892 234.0 582.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 238 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 561.892 162.0 570.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 239 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 549.892 180.0 558.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 240 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 537.892 234.0 546.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 241 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 525.892 198.0 534.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 242 0 obj << /Length 243 0 R /Filter /FlateDecode >> stream xœÅTMoÛ0 ½ëWð¸ˆJɲ%3 °Ã€ v(zp»38-ìaÝ¿õ‘ØNëé!uˆ Ì÷øø?1H¿™;´•°Ú²§˜ %$YL¥Åe [ˆq ÷Ö ûˆŽð¿ákÂ7v{G—k@*øËðÎ/ÙbÀïnðìüìkήnRyÕ(µ\¤'`x"­{$ä[¸ý²ÌçùÏåÅäßÙu>’‘ù 2¾ß·7WÒ_sïðè"U8¾¸È÷YO˜„e·»ÚD»â aÐÎIØËÀ¡Šñ:œ•|ztBnF ä¤ûgÙ ÷A µN®Zc1ÒäÕQS4¯ªrÕ•k¸ÿ´½2 e ±³ŒðL¬û±kJ¾¯˜æË4O©Æj뮟WåcWïš‚¤ÔÝŸÂÅí[ÔVpƒ’ mzµnbЏe,\–%Ì7íî`b?CâIÆ%7H?D{Ü ¾ø"¬vMã§7[]q_´eûê‚8te>ˆ>‰˜á©ˆëº}TËSA/#䬮fåsÝvíå$ºQ§¢WuÓOw€ûΞK2ßZ$ó±ßš®|sϤJ¹Ô Ñux¼hžsÁþ4 endstream endobj 237 0 obj [ 236 0 R 238 0 R 239 0 R 240 0 R 241 0 R ] endobj 235 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 237 0 R /Contents 242 0 R >> endobj 243 0 obj 463 endobj 245 0 obj << /Length 246 0 R /Filter /FlateDecode >> stream xœÅTMs›0½ó+ö˜ÌĪ‹ÜHê¶ÓÉtêš™29ȶbkb 9mþ}„‘0&G˜Ñê‰Ý}owaï¸@ñžÔK{°Êœ}‹¹zà-Äp§ÄcAk3ØÕoY†w´pÑ/¡±…ßNîPøê<>áá(:üqèi¸ÆyáÌ­üõ ½x~ ç.u>}aàRHŸM‰|JÚµ}kWMD›Z^GuP#ƒÚ*úsqÑäã#úˆ¨7 Óéh÷/\²AëܤŽ]pžÝž¦¦³a«IKúQ(QiUgŠ0À ŒµéVVp D¸z>ä+%‹¼2þÞÙ2+^D·U[c¯¢äJ曩Þ+%²aäŠtPº=T7Æ¡ÈL¼5W|É+1ÎæUŠýA–=bº¶næžèæëLæ²R5o-˜ÑQ©ÂØKalþÆåŽ/w$­Hmôfu(K‘+üLÒoÄle;J;»ÌÄÍHÔÛì½Úï,v|õ"òµÚÚt#Ÿ‰À?)M´©Ïè$¹ôŒpL]ó»}-*µÁ´ÈíHéÈF©x g3Œã(`á0øª\‰õr”’OÃÜÉGˆØÙd“㎗Á?ã Ø=ÞÉ >, ‹3 Ü¡óýÃbþ0ž/ª}ñkgø&•È+^býØæÎ?èÑÍ endstream endobj 244 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 245 0 R >> endobj 246 0 obj 582 endobj 248 0 obj << /Length 249 0 R /Filter /FlateDecode >> stream xœÅUQo›0~çWÜc+5ÌlpßÒ5Û4UÛ² MSÕ'¸ j€œnù÷3˜`B»ÉçÏÜÝ÷ݰw<@êšÔKÈ0¬2gßb„|ÚB„‚¸˜@­M`[ßeød©EߤŒ ürrÁgçñI&€”ÇkœÎÜÊ_Ÿ wÏ`íÜÅ·O<ñ³)¦.õÆXBäú˜Õ? qW÷³EüóûïÉý4žÞM³ë'ˆ¿:³¸'È÷ð4o84 š6cõݦ׽ þ‰5nÐ&¡¯1…èÜõѶm\»j"ÚÔzô:ªÈVÑŒwM>>¡¯7êÍB@G»ÿÎ%t±Î݉QÔUW#„×ÓÔt6l5iIß )*­êB‚|æ"JU¤¨õˆ7i×0QƒWχ|%Ó";;Í_‹Ñm寨ÅN”\¦ùºCªc%E6Œ\¹oÕq(2/á’/y%FÃÙ¼J±?¤e˜®€­›xgºy’¥yZÉš·LP¨daì¥06åé–/·”Z‘ÚéÍêP–"—ø1¿¸f;•¶cjgO3q3õ6;Vû­Åޝ^Dž ­M7ìÂHPÿ¬4MЦ>£“ä¡ ~ÀUêšßí®¨äZ¥UÜN”NL`” &j6CÆ"JÂað¤,vÉr”fä g÷-ý9O%ÔXÇÉi Ç«CoPÍãJ:ð¡X}Ô³Œ¨7tþø°˜?Œçcµ¯z؉zE ‹¿R䕚]×z¯Í¸IÒ> endstream endobj 247 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 248 0 R >> endobj 249 0 obj 588 endobj 252 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 149.625 210.0 158.025 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 255 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 137.625 216.0 146.025 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 257 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 125.625 204.0 134.025 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 258 0 obj << /Length 259 0 R /Filter /FlateDecode >> stream xœÅW[oÛ6~÷¯ ú°5ÅÌ‘)Q6À]ÓaCP °±=4}P$:*KŽD'ñ¿ß¡®”M+ÉK–Eòœï\?R÷3ŠüÎÍ#Š·³ûvŽ¢€!Ïo§„(ÇL -jÇef—5`ÝÍ&lп³|FП³oßa1AgäX]-¼œ][øf…¼9¾mGÙÿb±¡ÎJ®“3ZœŒW¬ÄõóÃl è5s0Ó`›¥¬tûl i†?Íó¬dpƒ¸ãØzøvàÝÍ>­f¿~ˆ´Zux0ƒ% ÍC«-úöžË‹ïhõ÷ìru’ý7ÙI vï ˜Y•„:ò©ÎlÐúÔ¸ô5ÚªÆ)G ¸D,ÄÄf¿l®þZ®æŸ«Å§Åòr‰Ù^‚z–ž–Þ©ì cÁ±Ÿ@Wi¥Qéè6ªT…¶‘Ž7i~‡ôF¡j¿Ûe©JP\乊uZä¨Ú©EyÒË }Ø)Üy8<䓦ß`~Ùçµ®Næ|0ý *Ã0 m0—‡\GO`è£D`æ PæÓÖÅúç(*’;vf‹y‹ã8úNå-`É‘14pa ¡œ›Pžu…ù.iôÓu˜À„<;¤:—æ&Ug½Àéào¿£RUûL?Ÿ.S› HãkéEy·ßª\WuÉüeû.®.ëMú„î‡!'l2`'­DÒ‹ãÚM×iÙÕç6#˜r(Y/œ¡Û†cѺ€5°L ^5eZ¯­ªüÅšL±ÂÖkd¡‹2±—W›´²1Õ:‚ôÙSº°_66þƒÉ‘õ^¬­—‰šŸÐ ¸’±Ë5à|³“ñf”b!€6½ hTŒkÎéS¡2-ŒÀæžÇúvÆÏ×/óBÌ ð/Zzü¬ª¸Lwv½89܇¡m(kë®ÎÁº%:h ½/sh‚Þ¾qÕLKÓ¼&ݾDªC¥Õ¶+Z`áÛÉΗÓÀœ¤¾Ëž—Õ/¹ %/ !”È„Rv9¹|ж»lh{i{ÌǾ}Ë:¢¿9"côóÍûwYGÙ¦¨ô;ô.Wð?né7èãÈMôq{ï ’î³›‹£º5¨ž3\A %ïúHOÓ¨Ïá ®?’KÿüÖušzÌ!ŒRsbuBþ‰!3hóú®x*ýÇÕòúê<¢4Â%AÐêI«¼‚êÅVÄ®gÿi endstream endobj 253 0 obj [ 252 0 R 255 0 R 257 0 R ] endobj 250 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 253 0 R /Contents 258 0 R >> endobj 259 0 obj 1230 endobj 251 0 obj << /Type /Action /S /GoTo /D [260 0 R /XYZ 72.0 720.0 null] >> endobj 261 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.087 216.0 106.487 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 263 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.087 204.0 94.487 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 264 0 obj << /Type /Action /S /GoTo /D [250 0 R /XYZ 72.0 720.0 null] >> endobj 265 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.087 204.0 82.487 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 266 0 obj << /Length 267 0 R /Filter /FlateDecode >> stream xœÅW[oÛ6~÷¯8èÃ’µJRwæ¦î°¡ÛÐØ[Q$} -*&K‰(×õ¿ß¡.-ÑnŠYD¼}çÎäãˆÁß±úø!ƒÕfôØŒQðØ^3äz@‹¹°¦íBªVi Ö¶ðS/ÂÆ>޲_F·Ÿq2‚€ÝˆôÅUàù胦_Ígׯ[`Sö¿X l¨²Rå…áŸoUÉ9špr<£%î0ÞV íz GjÝj*m"Ý|kCêfíOý=ééÜ æ86>Ÿr÷£7‹Ñëw.P‹¸«s߯+`¡úa°ØÀí¥c_}†Åo£ÙbýgÙ ‹J÷Á4³Bè‘OUfýƧڥ?øFÔNbàÀB‹x®ZÔ€ë›Ùt1¿.¦o¦óÔà„:žE\Ôlw¾cÌïÜsX‚—8D¼äK.Æúcj‘ Ú«Ñï¶ÙªLò¬ÅœŽ‹Z. ÂЧM\æû¬ä_[`hPÚ–O|”…•RAjSÇdžv~Ú´ P|OuƒŠ<ËDåÒX>ˆÕIó˜mÃÿˆýÌ'CPë͸Ü?ˆ“úlS<àÇŸ@nW+!å·@³q0Xå|ZÜo7"+%ð,‚¿yºò´ñh€*=êaq;vp6\ƒ:§Fô:<(|'+®×“Ù /°ˆík‚Œ141ÀNá 'q¸p£ )‰Z·±R¯´ÁÄ–ÖåZ b—‘>½X'R×)b¾MK}¨ÌõÎZ×ÿEeIëç±Öy‰ñ€-Ðç€ô|®4Ž¢öòlÈ¡VHõÜõêÎì!j ËÍæwWe¬Ÿ&€5²M¾Zm‹âÀ0G»Ÿ3€[ô6J*^P!Àõ{Œéxz}=›Ïdz››?o>$¹ƒ}{:~h1jÊüæš–DfqŒÁ>Mö¨Í%¶eûÙ€µTßl’¦°-¯B^3YŒjH 15¢âûqmjUâx´%‘•¨8—ãý=)·Õ%â¼½®k®‡ç‚×ܦ¦Yu”¢R.E+P«ÜèºK¡uÊu‘ïôÅI|4«¯=ºeÔCM´5¹Z7ËK­ÇÓ4ßé³bg¯ã›…Áð6'ݾîư°\Ïï…îàQ%MEMm?ù”T†x) Ô­Ômžs!`šÊüðìÞa¨Û£x‹¥ÕC°zˆ N e½)#!Ë"ß÷ž ½¦ÍœïýPäËþ{Ä Øö¾WpšÈî~&5Áê÷_–€WÔ endstream endobj 262 0 obj [ 261 0 R 263 0 R 265 0 R ] endobj 260 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 262 0 R /Contents 266 0 R >> endobj 267 0 obj 1303 endobj 254 0 obj << /Type /Action /S /GoTo /D [268 0 R /XYZ 72.0 720.0 null] >> endobj 269 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.102 210.0 106.502 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 271 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.102 204.0 94.502 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 272 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.102 204.0 82.502 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 273 0 obj << /Length 274 0 R /Filter /FlateDecode >> stream xœÅW[o£8~ϯ8êÃn;j\cc.‘v¥L›Íj´Ýi¢­Ú>0 Z)Móï÷æ iç¥ÓVÅØ>ç|çö?4 ø;ΦÍÀ]žÕœ&n¨)a€¦&` j, Ìwµ¬á£Ü„ƒ|E# ŸG÷¸èE݈vÕÂóÑ·–ý|…¾»ý6®±Ÿ‚ ÇPd¥È Ã?“É9X:=\i%®žof ƒ¼œÃ™Òv¾ªH«g ¤–þ”Ï£~ÐÆ :Gåáû§ð4ú¸]} QXøM›gˆÅìü‡Áb ÷纸x„Å£Ù¢—ýwY/‹¹íÚ„ŽYµ(¥ÚOEfMåSéÒŸÎZ–N Ä@·€Ù„"ßo•7³ùâîöŸñÍt1ý8Ï ”®e4Á 3Ñ´Î̾ôcfWÀ8%žL³$Þ§à€çdÎÒIk¼æ^]#Ô¦(o”òŸ¶‘›qTÉa¡Y¶mj*4ó}”9/• =`ÌÆ–¦ˆÖ0K …u|´ñT×{"PéGíš ½ínE²phœn¤{Óû²ðË¿rÂ3¾GÊ“q¶ßÈ£Ö¸pì·ß!ݺ®LÓ×c¯1N ŠuiX¼Ÿ&OÛµŒ2Ì{äÁßN¸•éqè˜ M·ˆÈ+ÇÆÉXõª\”žB#¹|à®Ó.¥a¦Fç¶Í?Âa=Ù)\à¢0 j=­©\cëU¡”Éek2 ’´^ÖËa'^{y± Ò¶Mé;Û0kOeqûeÕ¶ÿ_ž¥Ö{ì·^>xrÜëôÙ⟠‹ãƒ¨}8rF±)–•nªÜuên0Ø}©),ã8”N~è<øâÃñþbVN3\Pµ8jùï”à%ä!­S½sÒª‰ümî+6”y½©„rA)7”ö™ºI°iñ ç ›à™‡°¸¢Â¢,|E¥C” Atˆ<ݧ™\W#=Xž¢ŽQÑ4ŒŠÀ£´oþm-¤c4O(yKÄ,5X¶eQ½š½8ëMØPÏÐ)À™A4¤>ËBr½“~}8? c× WqšÁY$wøßC†«09p&Üû”Èô9|¸èôNn—[»H¹‹}û9øL½‡o`—ÕÞ,IâdßWA(!KöAôÈ:NÑM…Õh¯2t†]%qœ ¨·»Aئ¹ÊC_þº/>ßÍæß¾NúJtüì*)P6JT@Áwµ7/‰7ÞrÒÀMä:F‚¬7Ìîînï&Ðl8+Ü8/–)Dqò%H<ÒY7+䉨u·IR3Ãïfà7/(ú9À®¿¢óãéõõl>è4éÝlÁëm¥›‚0Ê)ðŠãç'aæûx¼gi4‡äE4ƒ¶(lÚ"Ç a©"‹ ã'ñº !#¬ø |&/“7ô¿ÀÏOfè¯Úß•]bâæA¶-ÎÿÓˆ^ÐtjV i„§ #œËJ[5Qx ÆKY²Uïê=ßÌ×[ZßÅ»ò¶ZÍ+HóBRC' ã]WC½±8×;HTd/O è—ˆ0ŒN+ú°oЫÁÎHß’%[nRüP7Ô%a.%LÃ4®ogÍåšFòûÞŠÛQÃ)X„\ôÜD:™ì|Çwn}¹fülýAÍ›$^¾A1Ý?¨8ÄÐÖzÓ–âü÷÷D endstream endobj 270 0 obj [ 269 0 R 271 0 R 272 0 R ] endobj 268 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 270 0 R /Contents 273 0 R >> endobj 274 0 obj 1271 endobj 256 0 obj << /Type /Action /S /GoTo /D [275 0 R /XYZ 72.0 720.0 null] >> endobj 276 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 204.212 210.0 212.612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 278 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 192.212 216.0 200.612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 279 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 180.212 204.0 188.612 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 280 0 obj << /Length 281 0 R /Filter /FlateDecode >> stream xœÅWKoÛF¾ëW |hí Úî“- 7NÑ"HëZhq4¹²‰R¤LR¶õï;Ë犤¤¤7 ÂÝÙýæ=³£ÇŠçæãúÂõ챡1p9§!)˜$\Ášµ‚Äܲ¼]á§¾„‹ø{–Î(ü2ûü# xžÑ!» |3»¶ä›úêòm ãÿ‹F‡**U\8þsIœ½%éþ‰¸ŽÞS+¢¦!¥–mŽ’ÆÓÍ·V¤^ÖöÔ߃vÐÞ :íÇÆÂ×Ná~v¹œýðA£°\õyî ¤ûæ‡å>ŸK÷â ,›]-GÑe—¢hdwÆ êURÊölª"ë66Õ&} Öº6jÂÒîê(sß«üùûåÕüýb¹¸\Ü\AíLøDxæºðÇØ[ÎÝ!@@©‹²€U–ƒ~‰‹R§¡†lDAÜE§»;¡»d„ú¹95·Û4,ã,m1‡ÝäøD1ÔÊe›nvi¼´@B˜/ˆ'8òÂÄ© ›<»Óó}=-?ñ1ZþÈ} €‰ a–¦º²h^ltxP;Î'ÀðÝ?zwD"wäÔZ3/w}PžSÆýøÛ0ÔEqÚÿŒsÌv‰Àœ¯à‹ü~»Ö)&CFðWluqXyŒ“QÂõ})¼£îe=›D/ ÇƒÁÇ«8 ìtšVÃñŒ&}8­Ä»€ JîJJ9mMª3ƒ ÎWMgíußw'UŠÔë¾§·”*EêeЭ¬L¯ q:Ént¯öK¿mê!ê(w»ny8¥„‡!šðÀײtÔ$úk¢å ârÇ÷|·é‚W/Áz“ôoê!®K(J¢ž’ͳ;x‹àûÛó³$ ƒä!+Ê38Kõ3þa{m?·ðnÏ>x·Á»÷¹.“Û‹Aá©‚¤b¿_NÜ“rpN;B¸œHGPÆÝæ9Ž# W«¶ãÃUm¤ùq¥ƒno&¸OYªOË“\†uB­ãC]I€X\n«ÆT´ÄÁFzÈoú‰ÉÚ¹ç™î§[~=iìît¿-òìÙ:ŽWö™uÑ~jJ—öíLý.ÍÊ~“ëPÇO6ˆÖqŠU™e–Ïý¤ëp‹’ÓrïÝÛ³Ùa›‹ØTw×ÐFH5 ¾¹¢ªY"*=Ø þ[—“žO|a¦ÕL~7ZÃ")²n|ï§gT[QE<Ï3#t5>ªŠ‚GÄÞ/µ/‡ÓÝàgáŒ*~#ç;gžíN³ÆaùY'èäŽoa1>ñ£A9q\†½K±¶ŒÊãMHùøÐ(ỾôÃSO1Æc0à[tÂ%CÍ©Ã&Ð?¼¹þxX¢gÀè%Å&Eë|¢ Ì^byìzö/; ÷„ endstream endobj 277 0 obj [ 276 0 R 278 0 R 279 0 R ] endobj 275 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 277 0 R /Contents 280 0 R >> endobj 281 0 obj 1201 endobj 283 0 obj << /Length 284 0 R /Filter /FlateDecode >> stream xœÅXKÛ6¾ûW=$Y Vù”ÄZ`ƒlÛiŠ`æç ÛôZŽ$g×ÿ¾CQ/K”l_R'€(Rß<¾‡ûmF†sýð$Eëxö­š#È£ˆ¹Õ”pá(FÕX HÕÐzó vèÓ,™aôûìóXÜ €§î‹+Á³ýzÿpý] ¡ÿ‹Ú†2*e\(ü÷œ28' ‚ãÓ•Nàšùv¶TÈÌÌÝz)ª˜®žÆ34þ˜ç¨¸uÛy¬<üqÊ1zœ½YÌ~þM ‚ÑbÛæ¹Ç`Æñ©Ô?Š1úüŠË›/hñçì~1ˆþ¦lE­»qL‡¨úcrâSY¯òɸô!ˆ•qÊÂ÷•v…þÞ7€OïÌßÞ-îÞÜ=Ü#m„1°>æ‚ ¡KJ½>€OÐý³Z …´J7G”nÑ:Ý(ô;˜ûda°Š,’ *R˜Ë÷jnCµA› VA®PºúW­ §öÒ³xɉƒ%Å®QüW°ÎÒ0Φ+A|)=R±ùpLŠà¹J‹&‚¡ p.¯r²üõxñ¹åKíö¼v«O¤Km²kSÀž-ĵ³YÍÕQ(¶Ù5¡…–S}À:MI˜&s¯Qu ÛÐèE¦òbB)ã6.*¥ó {ÌÇ#D¬¾(Óo\#×ukÓ ‰\°úö˯¼;DÅùì#Œ8®¯³Ö«Òö.{<Ä*)rÀ~ø'ˆ*Ÿ0@pÇõ<-…-XAwíV|Ú…ë óvO;eٕδ]žp˜¯+““)c7p€U²I³Ú5jå5sy;ì÷‘¶4QB¦®|É‹,LÏX.]‡`¨°®ÏÆóÎnöú7p—¡ø* C¯Ò½61ˆ:SAòvHo_Æ÷2¬{.l1Ìå¸Ù£3B¦àNÇ„Å.ìšëâÚy?@î8Ô×Üõ{‰cœq‡p8G\l³ìû÷ãž SÐŽöm:^%u0)ö¯$”HlA½ÔÌÑÖ[K!—€q¥)"CqðUÍ7jtjÊ@7õ°CôŽfœYd¾ªãk3ª £æ™˜'8Yd®Îú­LÄîs§šÏ4æe{HÊ8h €EŠ{¦˜ú²+÷cå2i¢“c<ש#=]C)µ]ŒãúS@i0uúùÂ1[Ä·ùrQh˜ð¦dLW#Ê¡…%ÏœºÃ3ÉZ…†;ô>Ì÷¦óÒð3*]â Õ·>ÒN3»Î>æ­*T‡ ”áÕ±ô²Ê¦‡Žìûí ߘ î €˜p·ºÑ=(5ÞM¹Ü‘  Pç†Ð³}.v§àåÕu¼µ¦®Ã<}å¥ÂÞ„ùYõ>Hð«~j(á‚]+<âŸ`†iuüß•—ÍÊ$ͪÊÉÅùršÐëhÀ¯¡y¾šæ„ hv!á:‚á6ï×Åq­êðCXÊ ûdb»_Æ`KȺ™½˜ñ!ô*Ƈð+‚¯e|(Áéüéúãì?æÂß endstream endobj 282 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 283 0 R >> endobj 284 0 obj 1588 endobj 286 0 obj << /Type /Action /S /GoTo /D [282 0 R /XYZ 72.0 720.0 null] >> endobj 287 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.104 198.0 94.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 286 0 R /H /I >> endobj 289 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 73.504 195.53 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 290 0 obj << /Length 291 0 R /Filter /FlateDecode >> stream xœÅWÛnÛF}×W R °ˆÙ+w×hÈ¶Ò \'Õæ!Ê-­i‹Tm£è¿w–¤(‰\Qé‹+æjÉ3gn;3|P øº‹2 fËÁC½GA1àa½%C "`–P¯%$î©Û¬ðR=„‹¯ðiü4øüoÎ àq@ÚâJðÍàã¿»C^œWNÙÿ¢Ó¡ŒJ†*(ƒ³wC ²g'pÍþv·$äÕîTÜîVR{º¾VŠTËÊžêzв5ƒøýX[øräîç“Á›w(Éb›çŠãN ™q“%|>‘ôô L~Œ'è¿°Ë:QtÜ1¨:FUBèžMedUmSeÒu´´•Q Ì$”îy]>ý2ùyx9~7úýj2¼MF磛1œ:F'•¨FÕ40!ò)!º¢¦Œ©6Àôšñ“­ ÛüŽšÕm6n~d‹f9ËæÛÇãâkóãõÜ.¢uR çQÝF¹}½#lΛ_EæáËïí,^ÄvÞ2]'(ªb tíë A°q¸ò8\ò€‚6‡è·h¶Ê6€ÃEGK$2ŠÖd7Ïi=m€ÆÃD©¨@a,¬óÊOË-ß÷·—´ º´…]-ãÔÎáöН¶`°eE‰Ó»r?‰0uìÓ=ÞÏã,…8íK$Œ©¤X¤ ¡Ö^ïpEú°ÁñŒbB´2êÒæ³U|_ â½•=4­„ø`W‹lµì1Uóa¨ ¹.þH¨>,T5ù 3å$ íçDzà›Ft˜^é>ʡ۾%FcwFñB×­jü-ï“íQö`Î]è„+%uÑî’wÛ /KÈ. ëÏw?\\Ý|¼¾¿<¿8sÿ¶­9µoæX`àý‡ñ5ü-°¹È‹Ñå?o=¢1÷EOO[À¯M˜žÌ’ü!9[Äé¼Ñ^-í2[=Ÿ½šžº¯G¸f-ဲ¼¶tÓÓv?r¢LÛq®omAçO$©&ˆÇ¥[‹|­]{8ž)B¨·ÑûjÕ¨c¬ãÅ oÞw^…bcÔh¡ëÑà:Kí7$'¦e`ÜH¡ø¦ç”leìc”LÒ8#ÿ+£ÄiØ!µ2›ã0³eEŠp‚‹uäÖ½æJ<°F¢t¥k­/¢$ÉÁMa5,ì”'pîJ >¼;!‡ E°p³¦P0,Öé¬Tº¿Ð[«3!õHé¯Zõ@a=Cß9ÚÕ*[¡"‹¾aÊe NÒ#îèÌÀ]ŠÆCœCš8´"§Iˆ-Aá ÒFÕcÁµ0Jò¬yÍÚ¾å`J„Œn.ÆWò5§SSq øÞ^ölm½¼9¹\îÉíø¢+÷P¡.…»ï¿ÿïèv endstream endobj 288 0 obj [ 287 0 R 289 0 R ] endobj 285 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 288 0 R /Contents 290 0 R >> endobj 291 0 obj 1190 endobj 293 0 obj << /Type /Action /S /GoTo /D [66 0 R /XYZ 72.0 720.0 null] >> endobj 294 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 590.345 173.33 599.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 293 0 R /H /I >> endobj 296 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.209 590.345 542.209 599.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 293 0 R /H /I >> endobj 297 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 578.345 226.66 587.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 298 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.862 578.345 541.862 587.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 299 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 566.345 301.65 575.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 110 0 R /H /I >> endobj 300 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.373 566.345 541.373 575.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 110 0 R /H /I >> endobj 301 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 554.345 232.21 563.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 302 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.825 554.345 541.825 563.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 303 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 542.345 260.54 551.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 304 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.641 542.345 541.641 551.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 305 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 530.345 279.97 539.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 163 0 R /H /I >> endobj 306 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.515 530.345 541.515 539.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 163 0 R /H /I >> endobj 307 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 518.345 167.22 527.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 308 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.25 518.345 542.25 527.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 309 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 506.345 242.77 515.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 310 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.757 506.345 541.757 515.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 311 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 494.345 206.1 503.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 226 0 R /H /I >> endobj 312 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.995 494.345 541.995 503.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 226 0 R /H /I >> endobj 313 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 482.345 265.0 491.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 314 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.613 482.345 541.613 491.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 315 0 obj << /Type /Action /S /GoTo /D [214 0 R /XYZ 72.0 720.0 null] >> endobj 316 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 470.345 201.66 479.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 315 0 R /H /I >> endobj 317 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.025 470.345 542.025 479.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 315 0 R /H /I >> endobj 318 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 458.345 183.33 467.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 319 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.143 458.345 542.143 467.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 320 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 446.345 226.1 455.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 321 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.865 446.345 541.865 455.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 322 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 434.345 199.99 443.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 323 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.036 434.345 542.036 443.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 324 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 422.345 257.19 431.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 325 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.663 422.345 541.663 431.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 326 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 410.345 180.0 419.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 186 0 R /H /I >> endobj 327 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.166 410.345 542.166 419.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 186 0 R /H /I >> endobj 328 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 398.345 157.78 407.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 329 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.311 398.345 542.311 407.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 330 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 386.345 215.55 395.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 331 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.933 386.345 541.933 395.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 332 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 374.345 222.77 383.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 333 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.888 374.345 541.888 383.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 334 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 362.345 208.89 371.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 335 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.978 362.345 541.978 371.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 336 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 350.345 203.33 359.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 337 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.013 350.345 542.013 359.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 338 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 338.345 202.76 347.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 286 0 R /H /I >> endobj 339 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.017 338.345 542.017 347.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 286 0 R /H /I >> endobj 340 0 obj << /Type /Action /S /GoTo /D [285 0 R /XYZ 72.0 720.0 null] >> endobj 341 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 326.345 251.64 335.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 340 0 R /H /I >> endobj 342 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.7 326.345 541.7 335.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 340 0 R /H /I >> endobj 343 0 obj << /Length 344 0 R /Filter /FlateDecode >> stream xœÅÝ]Ç• á{þоôÃÞ̈_—´Díp@K²ØÆ|a.d™² ØÔŒ(`1ÿ~óT“¢Ø•ôò¹ñÚD7ßì®ê§ÝUyùßö›íø÷ãüÇXåæ»¿>úï·ÛoF¹©ýí‡Z¿Ùã¶´›¿Þ¼ýs»ùKV¿øCy÷§ã÷Ññ‡?ßüË£×¶›ÿýè?þóøË?ÞlÇÿçÑöðÓ]~ñèw¿øúù7ÛßýëÿòÔ½üyù.*—rügÜ^p>ø‹Û‡ó ¸Ÿ?þþ£—/Xï?v|äþkç_ýåíwúí?ïÈýïŸÏý??ú<¶÷Oc;ÿ>¾}†¿/¾ÝüéÑoîý¯/Ú;ÝÜ}ÿþç|Ôã#·³¬üW¹¹ûëÍüjøÏ›»~ôôîJÿïü-»R̯ýó“©7%nçå±ðœæ¸]ÇGûº)ûm™cÛ¶ÞïŸÜg?¼~ýò»Ÿ^ýðúæÛ×¼yöúÕO¯¾ýË«7ßæ‡îŸ÷É·)æñŸÛ}Îã³îóþ3ÝýùÕ››¸y·ëæWoÞ~Îwÿý/ß|÷ã«?¼|_üôç—?ÿùÝ×é¿ÎÞêí¨í ˆzý?{þâwÏ?ú÷y}ÛJ¹>ôç/ýêõO/üþÛïÞ?˜ïøñûöÛñêõŸÞ?—oúöß¾yyý9Þ?»¾Ÿ¿úþû—?¾|ýÓû§þ?ÿõòÍ?þü_¿ûñåñÝ~ý§ûgòËïqß<ì$:¾•?ýøÃÿä#z÷HÞ\ì¾{KyüÅ¥{õæùþÇþú¾¿}÷];~ÜßóøØ?øæ?aÛñ›«ïÇOM¼ýQ¹ûöyys<³ãgæ§ãù¼ù[?ûñ&fËŸ´ýþðÏŸÜ=ùÍ“O<Í}ÛokÍ0ëÉQù]Ú÷üƯ®<¾{õø¹ùëãêÀÛ«|P~|MÊ«åÝòEy)–7Ë'åu·ÜT«©†©†©†©†©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©–TËFªe#Õ²‘jÙIµì¤ZvR-…TK!ÕRLµšj5ÕjªÕTÃTÃTÃT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©ÖTëFªu#Õº“jÝIµî¤Z ©ÖBªµj-¦ZMµšj5Õ0Õ0Õ0ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª±‘jØl)l¶6[ ›-…Í–ÂfKa³¥°ÙRØl)l¶6[ ›-…Í–ÂfKa³¥°ÙRØl)Ž—ƒ¾Å¶ÕµÓÌ6Žó„ãTzÛc®“÷v=ßs´«_öÕ—_>ýìîñ³/?ý×g/î^üúj˜·½‡ÔÞO>A>¾ã½ê~=Rnóv[ûq\”“ãΆ`”‡åƒò±Y^-ï–/Êg±¼YnªËT—©.RÍ!多C0ÊI5‡`”“jÁ$/¤šC0ÊMµšj5ÕjªÕTÃTÃTÃT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©æŒrRÍ!˜ä;©æŒrRÍ!多C0ÊMµšj5ÕjªaªaªaªÍT›©6Sm¦ÚMµ›j7ÕaªÃT‡©NS¦:Mušê2Õeª‹TsF9©æLòTsF9©æLòBª9£ÜT«©VS­¦¦¦¦¦ÚLõx9ˆº­µ ™âx]˜¹°rµý丽ŸÌÀŽÓœ3°Ïóøë¯¾zþø·Oþõñß<}úøíPìÙW_^ÃÊñþ¢çàºN>U>ÐãÕa\=Ðr¼Ï˜ul[ëåä¸ëóÈfù¤üxŸAyX>(?ÞgP^-ï–/Ê»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘jÝHµn¤Z7R­;©ÖTëNªu'ÕZHµR­ÅT«©VS­¦¦¦¦¦ÚLµ™j3ÕnªÝT»©S¦:Lu˜ê4ÕiªÓT—©.S]¤©ÆFª±‘jl¤;©ÆNª±“jRBªQLµšj5ÕjªÕTÃTÃTÃT›©gûìÛ=äl.O;ë8ÞɵyvÜ>NN;{½:í|úÅ“ß?¿{üîb¾«•¹ÀcÏ#Æ~rüå¤x¿­×+/Ž´—ºmûÙa¿{ïT/©G¡ºQ=¥ž;ÕAõzmT“å"Ë%–e˲‰eÙIJìbYv±,»X–"–¥ˆe)byK}z]ɲ’e%Ë Ë Ë ËF–,s_y÷zñ ù¢¼Ë›å“ò±[–ÊçfyµÜT§©.S]¦ºH5§P”“jN¡$ßI5§P”“jN¡$/¤šS(ÊMµšj5ÕjªaªaªaªaªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT‡©NS¦:Mu™ê2ÕEª9…¢œTs E9©æŠrRÍ)”ä…Ts E¹©VS­¦ZMµšj˜j˜j˜j3Õ\ü°ïkæ†iŸ>湬}8ÎZöRÎÎAöy2„íÿ5„z|÷o__O¢ŽßU­æ¢‡²N>I>ÄãwåÉ5@9:ïÛý–c×Ç]$Âò!y^þAyµ¼[¾(ÏѹäÍòIy!Õ¼üƒrS­¦ZMµšj5Õ0Õ0Õ0ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¦ºLu™ê2ÕEªyù多—H¾“j^þA9©æå”“j^þA¹©VS­¦ZM5L5L5Lµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘j^þA9©æå’駱—PNªyù‡ä…TóòÊMµšj5ÕjªaªaªaªaªÍT—ƒãmĶZd¾#Ç—ÙË~r\ÙNF óáF)¿~öå³»gOž?û÷§Ÿ8¹¾ø#÷&Êß÷RN>S>Î|7}õÇñ~í8¯]«ç¾ÜWÇ]Ÿ‡åƒòãýåÕònù¢üx¿Fy³|R¦¦¦ÚLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT§©.S]¦ºH50PNª¹€AòTs多 $/¤š (7ÕjªÕT«©†©†©†©†©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©æÊI50PNª¹€rRÍ ’RÍ ”›j5ÕjªÕT«©†©†©†©6SͳƒÖלí,ÿèiqž¾·½m{ôvr\ÙONß×Ã=ÞîÕð ½¼™|w¢~uÌý¦ªådSÕœFûØqŸxÞo‹ò°|PžS@É«åÝòEyN%o–›j5ÕjªÕTÃTÃTÃTÃT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹T/+Ì$'ÕË 3ÉIõ²ÂLrR½¬0ƒ¼êe…™ä¦ZMµšj5ÕjªaªaªaªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹T/+Ì$'ÕË 3ÈwR½¬0“œT/+Ì$'ÕË 3ÉMµšj5ÕjªaªaªaªÍT›©6Sm¦ÚMµ›j7ÕaªÃT‡©NS¦:Mušê2Õeª6[ ›-…Í–ÂfKa³¥°ÙRØl)l¶6[ ›-…Í–ÂfKa³¥°ÙRØl)l¶6[ ›-…Í–.wÙ*fÁ—lRÊõ`:—x¦±¨ìÅÉhär²(ãä\–½Ûu}YÝñ|µme;ûÂ×óAùñœòjy·|Q~ü§¼Y>%/ÇopÊI5×"J¾“jÙIµì¤ZvR-…TK!ÕRLµšj5ÕjªaªaªaªaªÍT›©¶TköY>%ï»åaù |l–WË»å‹ò\¨-y³ÜT—©.S]¤Z7R­©ÖTëFªu'Õº“jÝIµR­…Tk1ÕjªÕT«©VS S S Sm¦ÚLµ™j7ÕnªÝT»©S¦:Lušê4ÕiªËT—©.S]¤©ÆFª±‘jì¤;©ÆNªQH5 ©F!Õ(¦ZMµšj5Õ0Õ0Õ0ÕfªÍTó‚Ã1ÖÚÆYþÑÉK®XïV:^WN×Ï}Xý|á—O~ûôáˆ!O·ûøúÈË^Pëd%e.*kkn—§suØÕã8k”ºRÝ©^RgŒR7ª§ÔÇé¢ÔA5Y²d9Èrå$ËI–“,Y.²\b™ëǤË\=&µXæÚ1©Å2WŽA]Ä2×IM–•,+YV²¬ddddÙȲ‘eKËãõÿøŸó§ä}³¼ZÞ-_”by³|R>wËÃrS]¦ºLu™ê"Õ\,F9©æb1ÉwRÍÅb”“j.£œTs±å¦ZMµšj5Õ0Õ0Õ0ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª¹XŒrRÍÅb’駱‹Å('Õ\,&y!Õ\,F¹©VS­¦ZM5L5L5L5Lµ™jnÈžû|­r6¿ûè.§ƒkEÞŒþì$¤œÜ0w¨úÓÁÇ_|óÕo¿øúégWƒ…zrìen¹Ü°0o W·ãõ'Ç]-–äyk8Ê›å“òãÍ(åaù üx3JyµœTs¯5É«©VS­¦¦¦¦ÚLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT§©.S]¦ºH5÷Z£œTs¯5ÉwRͽÖ('ÕÜkMòBª¹×å¦ZMµšj5Õ0Õ0Õ0Õ0ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"ÕÜkrRͽÖ('ÕÜkrRͽÖ$/¤š{­QnªÕT«©VS­¦¦¦¦ÚLõrvÐÖZ£Ëà²Uú^²­“ãÊ:™MÄÃÙ>ØýáÌ ï@Þ¸ö~rèå2»íì>v{.‰Ç#;þ×sràÕl"—DK¾(Ï%Ñ’7Ë'å¹$Zò°|PžK¢%7ÕnªÝT‡©S¦:Mušê4ÕeªËT—©.Rͱ#多cGÉwRͱ#多cGÊI5ÇŽ”›j5ÕjªÕTÃTÃTÃT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©æØ‘rRͱ£ä;©æØ‘rRͱ£ä…TsìH¹©VS­¦ZM5L5L5L5Lµ™j3ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT§©.S]¦ºH5ÇŽ”“jŽ)'Õ;RNª9v”¼jŽ)7Õjª6[ ›-…Í–ÂfKa³¥°ÙRØl)ÇŽm?NÐkì4ÝËM´¶Çëä¸zr‹‡<³ˆk¶ÚÞŽŸ½8¿ËÞk}Žç°í³žwÿ¨Æm¹ž9§ßkËDÄÙWƒ‰ãô[òãô›òjy·|ù!Wξµ×ãÒBu£zJ}œzKT©ÛFu¥ºSM–,;Yv²d9Èrå$ËI–“,'Y.²\d¹Ä2wµ“Z,/÷×ýôzËÜÑNj±Ìýì .b™»ÙIM–•,+YV² ² ² ² ²ldÙȲÍûú¹õOÉûnyX>(›åÕònù¢|˛妺Lu™ê"ÕÜÂŽrRÍ-ì('ÕÜÂŽrRÍ-ì$/¤š[ØQnªÕT«©VS­¦¦¦¦ÚLµ™j3ÕnªÝT»©vS¦:Lu˜ê4ÕiªÓT—©.S]¦ºH5·°£œTs ;ÉwRTc'Õ(¤…T£jS­¦ZMµšj˜j˜j˜j3Õ±Ž}Û#h–—½J·f­Ž“ëÙÍ ÆþÑë㯿úêùÓϯ&O¿Ø—îêè˱õlmgÚÈÕªWÇ]O•6Ë«åÝòEyî³#y³|RžûìH–›ê2ÕeªËT©æCÊI5×J¾“j®1¤œTs!多k )7ÕjªÕT«©†©†©†©6Sm¦š/qµ¬¹Ú'ÕKêÜeêFõ”:·Ø:¨Rçþ:PWªÉr’å"ËE–K,sQ¡Ôb™K ¡ÞÅ2J-–¹œê"–¹˜Pj²¬dYɲ’eeeee#ËF–,;Yv²ìd9Èrå ËA–“,'YN²\d¹Èr‰e®”Z,sÅ Ôb™ë¥Ë\-uË\+(5YV²¬dYɲ’eeee#ËÜ4­–·×1úˆ(/Lž=ÖÚJ=9®ÆÉøjÖÕϾ|›Í‡güùÿ†Í¼`zö“Cß-]<»©Âñü·±VëûÉW“…|à ù <ß2H^-ï–/ÊómƒäÍòIy7ÕnªÝT‡©S¦:Lušê4ÕiªËT—©.R½ÜÇArR½ÜÉArR½ÜËArR½ÜÍòBª—û9HnªÕT«©VS­¦¦¦¦ÚLµ™j3ÕnªÝT»©vS¦:Lu˜ê4ÕiªÓT—©.S]¦ºHõrkÉIõrkÈwR½ÜÚArR½ÜÚArR½ÜÚArS­¦ZMµšj˜j˜j˜j3ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÓT§©NS¦ºLu™ê"ÕË­$'ÕË­ ßIõrkÉIõrkÈ ©^ní ¹©Úl)l¶6[ ›-…Í–ÂfKa³¥°ÙÒýuÌóíb9^®c®}Û·'Ö³;¿®ö zöå³»gOž?û÷§ÿæVйKÃÚ¶­äRÀ«ÏrÙ㱞]Õœ3“R¶íx_urÜéÌDò°|H~™™H^-ï–/Êsf"y³œT/3ÉIõ23¼šj5ÕjªÕTÃTÃTÃT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©^f&’“êefùNª—™‰ä¤z™™HNª—™‰ä¦ZMµšj5Õ0Õ0Õ0ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª—™‰ä¤z™™@¾“êef"9©^f&R½ÌL$7ÕjªÕT«©†©†©†©†©6SÍ[NÔm­ãW±Œ#.·œèÇ;¹¨gÃzr;Ì\ÿaõÍÓlý¶Õ÷ó›yv%b¾)›÷{Åx5½È7e’ÊóM™äÕònùñÃ3¦ÒÚ§äù¦Lòfù¤<ß”I–ÊóM™äÕòn¹©vSí¦ÚMu˜ê0ÕaªÓT§©NS¦ºLu™ê"ÕÜ8ŽrRÍ­ã$ßI57£œTsû8É ©ær”›j5ÕjªÕTÃTÃTÃTÃT›©6SÍEÒùž`ÌýSò¾[–ÊÇfyµ¼[¾(ÏEÒ’7ËMu™ê2ÕEª¹—多{ÉQNª¹—多{ÉI^H5÷’£ÜT«©VS­¦ZM5L5L5Lµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT§©.S]¦ºLu‘jî%G9©æ^r’ï¤;©ÆNªQH5 ©F!Õ(¦ZMµšj5Õ0Õ0Õ0ÕfªÍTÛßTýøTõ²÷\oG»ŸXOî*œ»‡|X½¸{r÷ûÊãðk­9ι<¢ã]U¿zDóHk[klûÉqŸø*T7ª§Ô¹êò°|P¾o–WË»åDº2Ý ¡î%Uû¶EOÉënyX>(Íòjy·|QÞŠåÍrSí¦ÚMµ›ê0ÕaªÃT‡©NS¦:Mu™ê2ÕEª¹šrRÍåД“j.‡¦œTs9´ä…Ts94å¦ZMµšj5ÕjªaªaªaªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹Ts94多ˡ%ßI5—CSNª¹šrRÍåД›j5ÕjªÕTÃTÃTÃT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©ÆFª±‘jl¤;©ÆNª±“j줅T£jØl)l¶6[ ›-…Í–ÂfKa³¥°ÙRØl)‡å½…¦sX~¼úØ×‰“{aç–ÕVŸ}óôÉÝÓîu™+šòÛÇ[º“ƒ/›pöÛq½:úx½Ýö~<§²NŽ»ž—m–WË»å‹òãõ–òfù¤üx½¥<,7ÕiªÓT§©NS]¦ºLu‘j®t¥œTs¥«ä;©æJWÊI5WºJ^H5WºRnªÕT«©VS S S S Sm¦ÚLµ™j7ÕnªÝT‡©S¦:Lušê4ÕiªËT—©.RÍ•®”“j®t¥œTs¥+多+]%/¤š+])7ÕjªÕT«©VS S S Sm¦ÚLµ™j7ÕnªÝT»©S¦:Lušê4ÕiªËT—©.S]¤š+])'Õ\é*ùNª¹Ò•rRÍ•®”“j®t¥ÜT«©VS­¦¦¦j³¥°ÙRØlér—šÞ·íx ”Yîe°Ž—ü½®³ã¢žÌîâá&‘Ÿ?}q÷ÍWÿöÑáÝñÌÇØ¶-Ê89úòØâ6Nn²·eã¸VNŽ»ž— ÊWDÊ«åÝòEùñŠHy³|R~¼"RnªÓT—©.S]¦ºH5ïÉL9©æ=™%ßI5ïÉL9©æ=™)'Õ¼'3å¦ZMµšj5Õ0Õ0Õ0ÕfªÍT[ªÖ5W韔/Ê{±¼Y>)»åaù |n–WËMušê2Õeª‹TóÍ”“j^Ô$ùNªy›fÊI5ÿ?fÉ ©æ­š)7ÕjªÕT«©†©†©†©†©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©æ=œ)'Õ¼‹3多÷q¦œTóNÎ’RÍ{9SnªÕT«©VS­¦¦¦¦ÚL5çe—{‘ÈLêrWç9s˜µNŽ‹“Û¥ä+χÕ×ß|õ›/u;ÌfÞÖyÕurìå‘ÍÛu²Ôm»­cæí O»M]êNõ’úx—ºQ=¥>^Ä¥ª‡Ôƒ,Y²d9Ér’å$ËE–‹,—Xæ¯R‹e^ï*µXæÕ®R‹e^ë u˼ÒUj²¬dYɲ’e%Ë Ë Ë ËF–,Yv²ìdÙɲ“å ËA–ƒ,'YN²œd¹Èr‘å"Ë%–y=«Ôb™W³B½‹e^Ë*µX敬R‹e^Ç*5YV²¬dYÉ2È2È2Ȳ‘e#ËF–,;Yv²ìd9Èrå ËI–“,'YN²\d¹Èr‰e^®*µXæÅªPïb™—ªJ-–y¡*ÔE,ó2U©É²’e%ËJ–4÷ šûÍ}‚æ>AsŸË¼n®m¯}ÈTì²¾-7\쳞g÷êé·{|þìÅÝÏ㺇:æVxõþ¦4õäØû=&·³kSŠYǶµ^N¼š:?’?”WË»å‹òãGƒòfù¤¼ï–›j7ÕaªÃT‡©S¦:Mušê2Õeª‹TsDH9©ærRÍ1!多ƒBÉ ©æ¨rS­¦ZMµšj5Õ0Õ0Õ0ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¦ºLu™ê2ÕEª9D¤œTsŒ(ùNª9H¤œTs”H9©æ0‘rS­¦ZMµšj˜j˜j˜j3ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÓT§©NS¦ºLu™ê"Õœ2RNª9g”|'Õœ4RNª9k”¼jN)7Õjª6[ ›-…Í–ÂfKa³¥°ÙRØlér™­oû¾:M÷â²áB}»PðêÀ˜'ƒÇñpë¼yv÷O_'x|Ù¶ÖŠ¶Ÿúî‘,ÌK z^÷uràÙÜQò¼¤@òjy·|Qž—HÞ,Ÿ”ç%’›j7ÕaªÃT‡©S¦:Mušê2Õeª‹TsîH9©æÜ‘rR͹#多sGÉ ©æÜ‘rS­¦ZMµšj5Õ0Õ0Õ0ÕfªÍTs»Š¾¶ýxŸ’çv’WË»å‹òÜ®Bòfù¤<·«<,7ÕeªËT—©.R͹#多sGÉwR͹#多sGÊI5玔›j5ÕjªÕTÃTÃTÃT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©æÜ‘rR͹£ä;©æÜ‘rR͹£ä…TsîH¹©VS­¦ZM5L5L5L5Lµ™êeî8Öjݦ{ñÁF¯WÆÙ«×ÃmÿîçŽO¿xòûçw?Ÿ»×w×)_}Š|„³]g¹]kÛ¶gG c(Ÿ”åaù<‡1”WË»å‹òTsC9©æ0†rRÍaŒäÕT«©VS­¦¦¦¦ÚLµ™j;Tçñ»l+õSòã—,åÕònù¢|Ë›å“ò¹[–›ê2ÕeªËT©æ0†rRÍaŒä;©æ0†rRÍa 多ÃÊMµšj5ÕjªaªaªaªÍT›©6Sm¦ÚMµ›j7ÕaªÃT‡©NS¦:Mušê2Õeª‹TsC9©æ0FòTsC9©æ0FòBª9Œ¡ÜT«©VS­¦¦¦¦¦ÚL5·È»æ,æS'yåiÞô`?ÎGOŽjoïŠúôîÑïŽÿ_Y œ­ endstream endobj 295 0 obj [ 294 0 R 296 0 R 297 0 R 298 0 R 299 0 R 300 0 R 301 0 R 302 0 R 303 0 R 304 0 R 305 0 R 306 0 R 307 0 R 308 0 R 309 0 R 310 0 R 311 0 R 312 0 R 313 0 R 314 0 R 316 0 R 317 0 R 318 0 R 319 0 R 320 0 R 321 0 R 322 0 R 323 0 R 324 0 R 325 0 R 326 0 R 327 0 R 328 0 R 329 0 R 330 0 R 331 0 R 332 0 R 333 0 R 334 0 R 335 0 R 336 0 R 337 0 R 338 0 R 339 0 R 341 0 R 342 0 R ] endobj 292 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 295 0 R /Contents 343 0 R >> endobj 344 0 obj 7750 endobj 346 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 162.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 348 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 180.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 349 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 222.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 350 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 643.364 246.0 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 340 0 R /H /I >> endobj 351 0 obj << /Length 352 0 R /Filter /FlateDecode >> stream xœÅTMoƒ0 ½çWø¸`NB9Ò}OÓ$T¤ªXI·JVÁ´ýüÂZhASwèÉ–Ÿýl'BÍëÔÂW k²im|\¶&!z.°†VÕuö£a2ÊÌHNnÉüÙ8S@ðIp® ž’¨“¿öàÉó#¼’IL.nP„x¹k—®¤J©@q\ÎTý0ˆ×0?›ÝÇwÎU‡“pz}þ ñ¹Ž{l8eÿÀ&jjhÊofÌÌç»Í {áaßÓY‚­}gmrk3›»veíÔZi ±ªåcå(ÜÑÀ.‹þVœ4ùøBøÜXÜ ·G§â–L±Î½%cJ7S ‘ö85“õ[N–ÒTk³²ØÛázpt}{M4¸j¿IxpVEžëE5Ø'è±cÓUù ¦ðþŽé¼E¦Ó1h)…þ\UoNª—ÉGV9iR%/I©;ð¿Í¹+h ”OÛ=•.-À@¦FjNp€Ì`)Ñ­¡—{`Á)“±°*!Ÿ yäyæž4…£¤Ñ—Óèq<£ïÙKVÔæ0µþªt^®ŠÜí4,"ß n. endstream endobj 347 0 obj [ 346 0 R 348 0 R 349 0 R 350 0 R ] endobj 345 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 347 0 R /Contents 351 0 R >> endobj 352 0 obj 437 endobj 354 0 obj << /Length 355 0 R /Filter /FlateDecode >> stream xœÅSKoÂ0 ¾çWø¸òhÓöXì!4©"Ä¡e ñj'öóç4¶T½²´’-;ö—/Ÿs"~ž1a,àkON.Æ! •  ¸OE{p~;³«áˆ‹‡ÆnBgsr žÉb‰É0,8vÛ®*ž‘´o2ìîø ¾ÉP“Á$Î@¯ë+â‚òˆá’"*El–½‡ÅÃüU¿x£ñ$ù˜jo”èd˜ÌÆKÐod¬[¬$ÿÀ*­Î`i­þ!­o%Ÿµ3a¸Æëh(m #Û¤vN=gíA¬kùXÛ˃Õ4X“E{:î Þ?¡ÄZˆ^õï|e ö• U5cÍ[œ*eCÇÉRz?–yaY &ñí%øȘ2¥°Sä*ÎÛrã­òuö³+½UVfŸY‘_:tßWèw[À¶€ .5ªS ª¸y”Šw‹Ÿ¦³tÚ‹'„©EzŠÒÎËüPlÚP2%½•± endstream endobj 353 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 354 0 R >> endobj 355 0 obj 368 endobj 357 0 obj << /Type /Action /S /GoTo /D [17 0 R /XYZ 72.0 720.0 null] >> endobj 358 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 680.124 149.98 689.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 357 0 R /H /I >> endobj 360 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.798 680.124 542.358 689.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 357 0 R /H /I >> endobj 362 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 668.124 180.538 677.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 361 0 R /H /I >> endobj 363 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.194 668.124 542.194 677.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 361 0 R /H /I >> endobj 365 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 656.124 176.22 665.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 364 0 R /H /I >> endobj 366 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.372 656.124 542.372 665.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 364 0 R /H /I >> endobj 368 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 644.124 174.0 653.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 367 0 R /H /I >> endobj 369 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.388 644.124 542.388 653.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 367 0 R /H /I >> endobj 371 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 632.124 195.66 641.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 370 0 R /H /I >> endobj 372 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.236 632.124 542.236 641.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 370 0 R /H /I >> endobj 374 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 620.124 193.56 629.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 373 0 R /H /I >> endobj 375 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.411 620.124 542.411 629.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 373 0 R /H /I >> endobj 377 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 608.244 190.77 617.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 376 0 R /H /I >> endobj 378 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.431 608.124 542.431 617.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 376 0 R /H /I >> endobj 380 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 596.124 189.11 605.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 379 0 R /H /I >> endobj 381 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.444 596.124 542.444 605.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 379 0 R /H /I >> endobj 382 0 obj << /Type /Action /S /GoTo /D [20 0 R /XYZ 72.0 720.0 null] >> endobj 383 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 584.124 336.97 593.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 382 0 R /H /I >> endobj 384 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.342 584.124 541.342 593.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 382 0 R /H /I >> endobj 385 0 obj << /Type /Action /S /GoTo /D [20 0 R /XYZ 72.0 514.852 null] >> endobj 386 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 572.124 297.967 581.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 385 0 R /H /I >> endobj 387 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.632 572.124 541.632 581.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 385 0 R /H /I >> endobj 388 0 obj << /Type /Action /S /GoTo /D [20 0 R /XYZ 72.0 299.872 null] >> endobj 389 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 560.124 189.0 569.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 388 0 R /H /I >> endobj 390 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.283 560.124 542.283 569.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 388 0 R /H /I >> endobj 391 0 obj << /Type /Action /S /GoTo /D [20 0 R /XYZ 72.0 264.073 null] >> endobj 392 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 548.124 264.983 557.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 391 0 R /H /I >> endobj 393 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.878 548.124 541.878 557.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 391 0 R /H /I >> endobj 394 0 obj << /Type /Action /S /GoTo /D [20 0 R /XYZ 72.0 162.589 null] >> endobj 395 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 536.124 264.983 545.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 394 0 R /H /I >> endobj 396 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.878 536.124 541.878 545.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 394 0 R /H /I >> endobj 397 0 obj << /Type /Action /S /GoTo /D [23 0 R /XYZ 72.0 572.619 null] >> endobj 398 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 524.124 232.332 533.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 397 0 R /H /I >> endobj 399 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.117 524.124 542.117 533.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 397 0 R /H /I >> endobj 400 0 obj << /Type /Action /S /GoTo /D [23 0 R /XYZ 72.0 439.062 null] >> endobj 401 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 512.124 230.686 521.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 400 0 R /H /I >> endobj 402 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.131 512.124 542.131 521.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 400 0 R /H /I >> endobj 403 0 obj << /Type /Action /S /GoTo /D [23 0 R /XYZ 72.0 293.505 null] >> endobj 404 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 500.124 310.468 509.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 403 0 R /H /I >> endobj 405 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.539 500.124 541.539 509.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 403 0 R /H /I >> endobj 406 0 obj << /Type /Action /S /GoTo /D [23 0 R /XYZ 72.0 147.948 null] >> endobj 407 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 488.124 267.189 497.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 406 0 R /H /I >> endobj 408 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.862 488.124 541.862 497.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 406 0 R /H /I >> endobj 409 0 obj << /Type /Action /S /GoTo /D [29 0 R /XYZ 72.0 720.0 null] >> endobj 410 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 476.124 222.761 485.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 409 0 R /H /I >> endobj 411 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.918 476.124 541.918 485.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 409 0 R /H /I >> endobj 412 0 obj << /Type /Action /S /GoTo /D [29 0 R /XYZ 72.0 665.661 null] >> endobj 413 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 464.124 193.44 473.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 412 0 R /H /I >> endobj 414 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.252 464.124 542.252 473.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 412 0 R /H /I >> endobj 415 0 obj << /Type /Action /S /GoTo /D [29 0 R /XYZ 72.0 324.527 null] >> endobj 416 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 452.124 259.749 461.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 415 0 R /H /I >> endobj 417 0 obj << /Type /Annot /Subtype /Link /Rect [ 536.79 452.124 541.79 461.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 415 0 R /H /I >> endobj 419 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 440.124 207.028 449.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 418 0 R /H /I >> endobj 420 0 obj << /Type /Annot /Subtype /Link /Rect [ 537.153 440.124 542.153 449.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 418 0 R /H /I >> endobj 422 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 428.124 208.656 437.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 421 0 R /H /I >> endobj 423 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.11 428.124 542.11 437.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 421 0 R /H /I >> endobj 424 0 obj << /Type /Action /S /GoTo /D [57 0 R /XYZ 72.0 409.841 null] >> endobj 425 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 416.124 209.224 425.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 424 0 R /H /I >> endobj 426 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.106 416.124 542.106 425.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 424 0 R /H /I >> endobj 427 0 obj << /Type /Action /S /GoTo /D [63 0 R /XYZ 72.0 636.0 null] >> endobj 428 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 404.124 212.532 413.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 427 0 R /H /I >> endobj 429 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.082 404.124 542.082 413.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 427 0 R /H /I >> endobj 430 0 obj << /Type /Action /S /GoTo /D [63 0 R /XYZ 72.0 485.117 null] >> endobj 431 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 392.124 189.56 401.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 430 0 R /H /I >> endobj 432 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.243 392.124 542.243 401.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 430 0 R /H /I >> endobj 433 0 obj << /Type /Action /S /GoTo /D [292 0 R /XYZ 72.0 720.0 null] >> endobj 434 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 380.124 247.037 389.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 433 0 R /H /I >> endobj 435 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.728 380.124 541.728 389.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 433 0 R /H /I >> endobj 436 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 368.124 197.33 377.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 293 0 R /H /I >> endobj 437 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.19 368.124 542.19 377.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 293 0 R /H /I >> endobj 438 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 356.124 250.66 365.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 439 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.819 356.124 541.819 365.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 440 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 344.124 325.65 353.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 110 0 R /H /I >> endobj 441 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.298 344.124 541.298 353.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 110 0 R /H /I >> endobj 442 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 332.124 256.21 341.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 443 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.78 332.124 541.78 341.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 444 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 320.124 284.54 329.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 445 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.584 320.124 541.584 329.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 446 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 308.124 303.97 317.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 163 0 R /H /I >> endobj 447 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.447 308.124 541.447 317.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 163 0 R /H /I >> endobj 448 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 296.124 191.22 305.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 449 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.231 296.124 542.231 305.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 450 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 284.124 266.77 293.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 451 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.707 284.124 541.707 293.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 452 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 272.124 230.1 281.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 226 0 R /H /I >> endobj 453 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.962 272.124 541.962 281.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 226 0 R /H /I >> endobj 454 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 260.124 289.0 269.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 455 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.551 260.124 541.551 269.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 456 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 248.124 225.66 257.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 315 0 R /H /I >> endobj 457 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.992 248.124 541.992 257.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 315 0 R /H /I >> endobj 458 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 236.124 207.33 245.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 459 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.12 236.124 542.12 245.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 460 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 224.124 250.1 233.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 461 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.822 224.124 541.822 233.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 462 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 212.124 223.99 221.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 463 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.004 212.124 542.004 221.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 464 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 200.124 281.19 209.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 465 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.607 200.124 541.607 209.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 466 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 188.124 204.0 197.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 186 0 R /H /I >> endobj 467 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.144 188.124 542.144 197.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 186 0 R /H /I >> endobj 468 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 176.124 181.78 185.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 469 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.298 176.124 542.298 185.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 470 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 164.124 239.55 173.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 471 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.895 164.124 541.895 173.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 472 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 152.124 246.77 161.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 473 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.846 152.124 541.846 161.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 474 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 140.124 232.89 149.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 475 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.942 140.124 541.942 149.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 476 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 128.124 227.33 137.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 477 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.981 128.124 541.981 137.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 478 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 116.124 226.76 125.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 286 0 R /H /I >> endobj 479 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.985 116.124 541.985 125.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 286 0 R /H /I >> endobj 480 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 104.124 275.64 113.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 340 0 R /H /I >> endobj 481 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.644 104.124 541.644 113.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 340 0 R /H /I >> endobj 483 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 92.124 243.232 101.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 482 0 R /H /I >> endobj 484 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.752 92.124 541.752 101.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 482 0 R /H /I >> endobj 486 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 80.124 292.87 89.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 487 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.525 80.124 541.525 89.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 488 0 obj << /Length 489 0 R /Filter /FlateDecode >> stream xœÅÝ[“çu é{ý \ÊŽ`uf®õ.)œÆ­áh»´·9A‘2ÝÓÿ~rí¢vBªçÆcw´yx³ªÀ@í\øöÊÿÅþb;ÿ÷£ú?c/þø§_üûÛ¶¿Ç‹èoÿQë/ö|8Ú‹?½xû×íÅ×Uýì/ŽŸþêü?Ñùÿöâ¿üâ›_l/þ¯_ü·ÿqþË/_lçÿûÛÓw»øó_üþgŸ¿þÍöþùþÄ~üÿòÔ×pS¹¹çÿ7œ÷þEËíýó3¸¿üówÿôö ãñŸÿäñs׿úúíé·ÿ÷ñ yüËÇÏãÿýàc{÷ÃØ®ÿ;¾ýþÇ}òíÅÿüů^ÿâ?}Ú^ìÛ‹×ÿúîçùˆ‡Û¶í3Îõ0Uÿs¼xý§ÿí—_}õÕßý¯ÿï_¼|}÷óà?ø?Þg}î¿ü°Î¯ýôõãxïGw3oP?¦×_üË×o^|û¯/~ýí7?¼ùæ‡ï„ÿir¾ˆñ0¶~~Ôc>^ý»ïÞüë|óxÍ»ÿˆãaÕ'ó÷‡»K^üÝ™œ_ÞzñË'—Íý¡·¹ÖùÿÝ_öð4N‰Äk“8$î/ˆ÷í ºQ=¥ÞEqß…±~Ú@}ä~ˆä~å~eeee’e’e’e#ËF–,Yv²ìdÙÉrå ËA–“,'YN²œd¹Èr‘åËcËcËcËcËcËcËcËãËãËã Ë Ë Ë Ë$Ë$Ë$Ë$ËF–,Yv²ìdÙÉrå ËA–ƒ,'YN²œd¹Èr‘åËóv”j±ŒM,cËó®˜j±Œ],ãË8Ä2² ² ² ² ²L²L²L²ldÙȲ‘e'ËN–,;Y²d9È’&>A#Ÿ ™OÐÐ'hê4ö šû$Í}’æ>IsŸ¤¹OÒÜ'iî“4÷Išû$Í}’æ>IsŸ¤¹OÒÜ'iî“4÷Išû$Í}²õ‡ý¼©ŸsK©Õó¬Ï¢ÍþŒú|Á'uR=¤Îê ºS½¤nÕj²ìdÙɲ“å ËA–ƒ,YN²œd9Ér‘å"Ë%–çoâT‹å±‰å±‰å±‹å±‹å±‹åqˆåqˆåqeeeee’e’e’e#ËF–,;Yv²ìdÙÉrå ËA–“,'YN²\d¹Èr‘åËØÄ26±ŒM,cËØÅ2v±ŒC,ãË8Ä2² ² ² ²L²L²L²ldÙȲ‘e#ËN–,;Y²d9Èr’å$ËI–“,Y.²\b™›Xæ&–¹‰eîb™»Xæ.–¹‹eb™‡X&Í}’æ>IsŸ¤¹OÒÜ'iî“4÷Išû$Í}’æ>5Ìíó,²§LOkšã¼c_g{wÝÅ4wÄ“æ?õýß~÷éã—±òbˆÛúOCå»ëîÆu>þùu‡:©R×ùx¨ƒêNõ’ºÎÇCM–A–I–I–I–,Y6²ldÙɲ“e'ËA–ƒ,YN²œd9Ér’å"ËE–K,o{ ËÛ^„ç×»XÞö"@-–·½ϯ±¼íE€š,ƒ,ƒ,ƒ,“,“,“,“,Y6²ldÙɲ“e'ËA–ƒ,Y²œd9Ér’å"ËE–K,o{ ËÛ^¨Åò¶j±¼íEx~}ˆåm/Ôddddd™d™d™dÙȲ‘e#ËN–,;Yv²d9Èrå$ËI–“,Y.²\d¹Äò¶j±Lšû$Í}’æ>IsŸ¤¹OÒÜ'iî“4÷Išû$Í}’æ>IsŸ¤¹OÒÜ'iî“4÷Išûä_}mÿáYëmä;kKp®ûë.F¾çkÚ÷›ß}÷æ»7ÿþãWßõÛﯦ–½V÷~åãWµ_mY¨½Øc¬µæ¼¿î~j¸QTwª—Ôç«©ÕSêóU‹ÔI5Yv²ìdÙɲ“å ËA–ƒ,'YN²œd¹Èr‘å"Ë%–µ@j±¬ýPïbYû¤ËÚ? µXÖþ©É2È2È2È2É2É2ɲ‘e#ËV–s;¿£äsê%u?¨nTO©ÇNuR=¤žÕA5YN²\d¹Èr‰eíZ,kÿÔ»XÖþ©Å²ö@}ˆeíš,ƒ,ƒ,ƒ,“,“,“,“,Y6²ldÙɲ“e'ËA–ƒ,Y²œd9Ér’å"ËE–K,kÿ€ÔbYû¤ËÚ? µXÖþ¨±¬ýR“eeeee’e’e’e#ËF–,k~¹ŸõžC&…5¿<ïÚÖ:2î¯{:¿\ýÅzºWöãÏ?ùônü¸?´óc®Ñ..¸}15Ä¿[ž_L¯wÚϼ¿în(Q/mj:ÚÏòß®ë¥ ÔIõº^Ú@Twª—ÔõÒêF5Yv²ìdÙÉrå ËA–ƒ,'YN²œd¹Èr‘åËz§½ÔbYï´—Z,ëöR‹e½ÓêC,ëöR“eeeee’e’e’e#ËF–õÒ¦¾ÏŸ/žQ×iATwª—ÔõGZP7ª§ÔõGZP'Õd¹Èr‘å"Ë%–õN{©Å²Þiõ.–õN{©Å²Þi/µXÖ;í¥&Ë Ë Ë Ë$Ë$Ë$ËF–,Y6²ìdÙɲ“å ËA–ƒ,'YN²œd9Ér‘å"Ë%–õN{©Å²Þiõ.–õN{©Å²Þiõ!–yˆedddd™d™d™d™dÙȲ‘e#ËÛ{êsÍÞ.î2>í/öíÅë}oÜYk[ßÏÿñÓO_ýtE{zEí}­Õ{^\ûø%î—£Ïã!kåÀy uqáýì³Y>Ïüí”÷ùùk†ò´|P~þ²¡<,ï–/ÊÛay³ÜT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘jP)'Õ¢RNª5F¥œTk*ùAª5J¥ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©Ö•rR­1«ä;©Ö •rR­Q+å¤ZÃVÊM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘jMa)'ÕšÃJ¾“jMb)'ÕšÅJ~j¤š6[J›-¥Í–ÒfKi³¥´ÙRÚl)m¶”6[J›-¥Í–n“Ù=×êasÏÛh6¶:+z5ȼ8€Zçýè>iOÇõlèý6Ý/.xürއãb »=̨g¸¸ð~®–wËåç -Ê›å“òó…åiù ¼™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘jí¥œTkã¨ä;©ÖÎQÊIµ¶ŽJ~jí¥ÜTÃTÃTÃTÓTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹Tk!)å¤Z+I)'ÕZJJ9©ÖZRÉR­Å¤”›j˜j˜j˜j˜jšjšjšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕaªÓT§©NS]¦ºLu™ê"ÕZYJ9©ÖÒRÉwR­µ¥”“jÚl)m¶”6[J›-¥Í–ÒfKi³¥´ÙRÚl)m¶”6[J›-¥Í–ncØó¦uæ¼”~xîyÃæÛõ§÷^a£–¶µ¢·Çèóÿüço¿ûáÍ—õiê]Ô/~ùëoÿô§o¿y÷÷Ÿ}õýŸßýÝ«?ýùë7zóÍ_üðÕ·ß\ܹ¬±Õq\|²wåîºù°ç¾Ö<ÖÅu÷w »åiù |n–‡åÝòEù:,o–“jí$£œTk+™ä;©Ö^2ÊIµ6“I~jí&£ÜTÃTÃTÃTÓTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹Tkiå¤ZkË('ÕZ\F9©Öê2ÉR­åe”›j˜j˜j˜j˜jšjšjšj3ÕfªÍTëÛÁùº:xòü×ýy~_ˆó{ßÚÅeÇÅ L¶¿v3Ï{ ¿üü÷Ÿ½û›¿~¿RO‹î}­VwPwûÝG¹»n=œ/ä×êm^\w÷B¸–HÞ,Ÿ”×þÉÓòAy­0<,ï–›j7ÕnªÝT‡©S¦:Mušê4ÕiªËT—©.R½­é–œTo‹º!ßIõ¶ª[rR½-ë†ü ÕÛºnÉM5L5L5L5M5M5M5Mµ™j3ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT§©.S]¦ºHõ¶Ç[rR½mò–œTo»¼%'ÕÛ6oÈR½íó–ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦z~;ˆ½ÕŸÍÑ­eÝ÷óÕÍœ-.®{zO<ŽÛ³æÞ^}óý_|ýõÕヒ WçÞ[Ñÿ2¸»ðéúöìCÉ»å‹òzx§äÍòIy=¿Sò´|PÞLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT§©.S]¦ºHµÞ[A9©Ö{+$ßIµÞ[A9©Ö{+$?HµÆ±”›j˜j˜j˜jšjšjšjšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘j½·‚rR­÷VPNªõÞ ÊIµÞ[!ùAªõÞ ÊM5L5L5L5L5M5M5Mµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT§©.S]¦ºLu‘j½·‚rR­÷VH¾“j½·‚rRM›-¥Í–ÒfKi³¥´ÙRÚl)m¶”6[J›-¥Í–ÒfKi³¥´ÙÒí ‹¹=®*—¹çí‹ç瘫]\wu2©¯'ÑËo¾ÿñ»7õ)V¾¸=qñ§¿þêûŸþêëo¿øòÍ—³5ÏWûØ/>îO×Þ]ÕÎ_"Û–{»¸ê~$²$?jÍ£äÍòIy­y”<-”ךGÉÃrR­ƒi’‡©†©†©¦©¦©¦©6Sm¦ÚLµ™j7ÕnªÝT‡©S¦:Mušê4ÕiªËT—©.R­ƒi”“jL“|'Õ:˜F9©ÖÁ4ÉR­ƒi”›j˜j˜j˜jšjšjšjšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘jL£œTë`å¤ZÓ('Õ:˜&ùAªu0rS S S S SMSMSMSm¦ÚLµ™j};8ç›ó˜ÏŸ.Ô±´9ÆZ[8»»êj RÇÛÞ‹~õãW_ùÓÇÿõOñoo¾þó›ïþ2ùê_¾û⻯Þ|ÿWg"wúY3‘»«þúLäoæïÏDž‘7Ë'åïÍDž‘§åƒò÷f"ÏÈÃrR}&ò·ó0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEªïÏDž‘“êû3‘¿ï¤úþLä9©¾?ùÛùAªïÏDž‘›j˜j˜j˜jšjšjšjšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘êû3‘gä¤úþLä9©¾?yFNªïÏDþv~êû3‘g䦦¦¦¦š¦š¦š¦ÚLµ™j3Õ÷f"Ï.¼?¹»êj&²žî¸ùøËÛDd¯uT?}‚‹‡Úïç ®1·:öå¯?ÞþüYÒÚymÎqqíÏ>ýŸ¿øáßžŽDúöÙeú×.¾»0æ:Z\}Ö»ÑKm­–|Q^[«%o–OÊkkµäiù ¼¶VKnªËT©ÖürR­ù›ä;©ÖürR­ùå¤Zó7ÊM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘jÍß('Õš¿I¾“jÍß('Õš¿I~jÍß(7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"Õš¿QNª5£œTkþF9©ÖüMòƒTkþF¹©†©†©†©†©¦©¦©¦©6Sm¦ÚLõüvÐZ{û@q˜2ÕÛ´öÚ<}R\\÷#¸š|p7^ÔsÉöwW±ÚO1ûù){^|´Ÿ]|7³:Î{²ó¿ÉšÞ¸šå“òÚ,yZ>(¯}Á’‡åÝòEù2Õeª‹Tkqå¤Z‹‹$ßIµQNªµ¸HòƒTkq妦¦¦š¦š¦š¦š¦ÚLµ™jí nÇã=#¯}Á’§åƒòÚ,yXÞ-_”×¾`ɛ妺Lu™ê"ÕØHµQNªµ¸HòTkqå¤Z‹‹('ÕZ\$y˜j˜j˜j˜jšjšjšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕaªÓT§©NS]¦ºLu™ê"ÕZ\D9©Öâ"ÉwR­ÅE”“j-.¢œTkq妦¦¦š¦š¦š¦ÚLµ™j3ÕšˆõóWl‹«™Õ‡§L·‰XìÛ¾_»®&bûÓõFo'bõä¿q&-×¶Öˆýâƒüú³ÏÿÙOßJ;oôÚ¶oÛØæÅÅï>}MàÞýÝßüì+«åIïþîOß~ùã×oînnçCö¹mGõÓÜÝXî#æZ3¯~l÷÷¡iù üü‰IyX~þ4:¿OíÑdzòEy?,o–OÊÇnyZ>(Ÿ›åa¹©NS]¦ºLu‘jû œTë܇ä;©Ö¹ÊIµÎ}H~jû ÜTÃTÃTÃTÓTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹TëÜå¤Zç>('Õ:÷A9©Ö¹ÉR­s”›j˜j˜j˜j˜jšjšjšj3ÕfªÍTëÏÀêö¬Ž‰ÀíY½óªŸf;o#/®»ºÉ=ž®¬ùÃßÜÞ×µý÷‡7ßÿðîï¾ÿñ«Þ¼ûÛÿþËoÿ\RûâëÿþwO>rýqþ>çÛÛô»ÏñîcÜ]7úqÞþÇÅew/ˆëyDP'ÕCêzÔAu§zI]"‚ºQM–A–A–A–I–I–I–I–,Y6²ìdÙɲ“å ËA–ƒ,YN²œd9Ér‘å"Ë%–õ§öR‹åíaCP‹åíQCP‹åíACϯ±¼=fj² ² ² ² ²L²L²L²ldÙȲ‘e'ËN–,;Y²d9Èr’å$ËI–‹,Y.²\by{˜Ôby{”Ðóë],o‚Z,o‚Z,o‚š,ƒ,ƒ,ƒ,“,“,“,Y6²ldyÛ¶Ö:ú”;ûÛR˜¾Ÿ¶ý⺧£‰œÖü^t<Ü>|ñË_û§?}ûÍç¿ÿì§ðúǾýî«/¾~:O¨?"îçmoëâþtõÝUùpÛnyqÕÓÿ$õ$ÉëD›äay·|Q^'Ú$o–OÊëD›ä¦:Mu™ê2Õeª‹Tka å¤Z c$ßIµÆPNªµ0†rR­…1”›j˜j˜j˜jšjšjšj3Õfªu¢­¾ŸÎxV½¤®÷JBݨžR×%¡Nª‡Ôõ.I¨ƒj²œd¹Èr‘åË:)$µXÖ9!¨w±¬SBR‹e‚úË:!$5YYYY&Y&Y&Y&Y6²ldÙȲ“e'ËN–ƒ,Y²d9Ér’å$ËE–‹,—XÖA ©Å²ŽI-–uHj±¬#@PbY€¤&Ë Ë Ë Ë Ë$Ë$Ë$ËF–,YÖd­Ímsþ¬ªæjk5Wµ'y½É¦=]ó꛾ûöËÿX‡yžNjÉøù;ÆvÞ‘]\ùø ðãáb†v¾ÆÙzß¶}®‹ ï&狜­ŸEý9ùù*‡ò´|P~¾Ð¡<,ï–/ÊÏ;”7ËMµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©©©©©;©;©;©žß×,'Õã0Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍTÛx|M°ÚÕËûäfyXÞ-_”Ãòfù¤|妺Lu™ê2ÕEª±‘jl¤©ÆNª±“j줩ÆAªqj¦¦¦¦š¦š¦š¦ÚLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT§©.S]¦ºH57RÍTs#ÕÜI5wRÍTs'ÕÃù{Ýù þáÛ/ß|ýÕ7ÿóÝ?ùß_=.óyü»ÇxµY¨ý|?ÎÝgù›…Ηé#Ï‹uõ%>ýôïoölÛ–5`¾»îj|Cù¼Æ7”‡åÝòEùùÓ‹òfù¤ü ÕßPnªaªaªaªaªiªiªiªÍT›©¶RÍ5×võÛÏÕø†ò°¼[¾(‡åÍòIùÜ-OËMu™ê2Õeª‹Tk|C9©ÖøFòTk|C9©Öø†rR­ñ 妦¦¦š¦š¦š¦ÚLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT§©.S]¦ºHµÆ7”“jo$ßIµÆ7”“jo$?HµÆ7”›j˜j˜j˜jšjšjšjšj3ÕfªÍTûþëü{Þ@Éô¢ŽÇµmÛlyqÝÕôfÜmlþú‹ï¿Ü,=æ‹_þáÍ×_ÔQ¹ïŸÎ2ꆎ:Š7çŇùÙG¸»p>ô­oÛQ'ÿî.¼›™ÔÛ’%OËåõÎdÉÃònù¢ü|Ay³ÜT‡©S¦:Mušê4ÕiªËT—©.R½­¨“œToKê ßIõ¶¦NrR½-ªƒü ÕÛª:ÉM5L5L5L5M5M5M5Mµ™j3ÕÚZws´öœ¼þˆHò´|P^›ë$Ë»å‹òÚ^'y³ÜT—©.S]¤zÛa'9©Þ¶ØINª·=v’“êm“ä©ÞvÙInªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹To[î$'ÕÛž;ÈwR½mº“œTo»î$'ÕÛ¶;ÉM5L5L5L5M5M5Mµ™j3Õfªõä¹Ñ¶ý8®î=><Ý»=y®Å¶·=/.œ#Èùt=ÞoÿåÿyóÇ?G«1篿{óÅÕÛuëµB;oÚìægànê·=ûq^د>ÿý0,ï–/Êka‡äÍòIyíì<-”S¦:Lu˜ê4ÕiªÓT—©.S]¤Z‡ )'Õ:I9©Ö!HÊIµAJ~j‚¤ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©Ö!HÊIµAJ¾“j‚¤œTë$å¤Z‡ )7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEªu’rR­C’ï¤Z‡ )'Õ:)ùAªu’rS S S SµÙRÚl)m¶”6[J›-ÕL±µó—`³ñ[Ö{¥¶u^íâÂ}»Þïþ^õéWß|ùöm¥õYòÅÛ±áý9ÅZKk­íêÃüìú‹!áo8Þ_x5$¤¼[¾(¯Ç}KÞ,Ÿ”×ã¾%OËåÃT‡©S¦:Mušê4ÕeªËT©ÖrR­!!å¤ZCBÊIµ†„’¤ZCBÊM5L5L5L5L5M5M5Mµ™j3ÕZÔ0æãù=#ï›åay·|Q>Ë›å“ò¹[ž–›ê2ÕeªËT©ÖrR­!¡ä;©ÖrR­!!å¤ZCBÊM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘j )'ÕJ¾“j )'ÕJ~j )7Õ0Õ0Õ0Õ4Õ4Õ4Õ4Õfª·!áyƒ¾¯Fó·Ç)áÛ‹÷îûÅ”pº°î“7_¿ùá/c¬Gõ~`LxŠ´Ø×}^|œŸ]wa>l#·­íqqáý oP^;i%Ë»å‹òÚI+y³|R^;i%7ÕaªÓT§©NS¦ºLu™ê"ÕzÃ1å¤Zo8–|'ÕzÃ1å¤Zo8–ü ÕzÃ1妦¦¦š¦š¦š¦š¦ÚLµ™j3ÕnªÝT»©S¦:Lu˜ê4ÕiªÓT—©.S]¤Zo8¦œTë Ç”“j½á˜rR­7K~j½á˜rS S S S SMSMSMSm¦ÚLµ™j7ÕnªÝT»©S¦:Lušê4ÕiªËT—©.S]¤Zo8¦œTë Ç’ï¤Zo8¦œTë Ç”“j½á˜rS S S SMSµÙRÚl)m¶”6[ºÍýòí.B¨ÕÜo›Çyå¸ú<{\ÌýŽ»§C|ûÍ¿þñû‹÷ Ÿ?óÛY®ÑúÅu?=ãbÎWϘ{=zx¿¸ðnQÏ|P^ϨÿF}æ³ò°¼[¾(¯gHÞ,Ÿ”×3$OËåÝT»©vSí¦:Lu˜ê0ÕiªÓT§©.S]¦ºLu‘걑걑걑걓걓걓êqêqêqêq˜j˜j˜j˜jšjšjšj3ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÓT§©NS¦ºLu™ê"ÕúSxÊI56RTëN‚rRTã Õ*(7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"ÕÜH57RÍTs#ÕÜI5wRÍTó Õ)»åiù |n–‡å¦:Mu™ê2ÕEª5È¡œTk#ùNª5È¡œTk#ùAªõòŒrS S S SMSMSMSMSm¦ÚLµ™j7ÕnªÝT‡©S¦:Lušê4ÕiªËT—©.R­Aå¤ZƒÊIµ9”“j r$?Hµ9”›j˜j˜j˜j˜jšjšjšj3Õóî zl[oK& Y›ꉺ}ÆÅu{>éëà[>]ž÷Éǯ?þÕÇŸ¿|:8_xÄù%m{}컫Oã­«±Ìùd÷R[líâ»Äù„ò´|P~¾¡<,ï–/ÊÏ— ”7ËMµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©ž¿»ZNªµÁrR­ ~”“jmð“ü ÕÚàG¹©†©†©†©†©¦©¦©¦©6Sm¦ÚJ5×c='ï›åay·|Q>Ë›å“ò¹[ž–›ê2ÕeªËT©Ö?ÊIµ6øI¾“jmð£œTkƒå¤Zü(7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEªµÁrR­ ~’ï¤Zü('ÕÚà'ùAªµÁrS S S SMSMSMSMSm¦Zïä]çÍÄ~\M?<;¼mð[Û¶™îíb ÙŸîùûû_ÿö7¿yùë×½úô£—ÿôêóןÿýÝ f>ô~~šèýâÔ×·öûÁæm‹Îí]ÆWŸöjCù¤ü¶Eò´|H~ܶè@–wËå;©;©;©©©‡©†©†©†©†©¦©¦©¦©6Sm¦ÚLµ›j7ÕnªÝT‡©S¦:Mušê4ÕeªËT—©.RTc#ÕØH5vRTc'Õ8H5RƒTã0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª¹‘jn¤š©æNª¹“j;©æAªyj¦¦¦¦š¦š¦š¦š¦ÚLõöÆ“¹Voóù£Ž:X6ßb.®ÚûÅf<Ý»ö÷Ÿüê£ßýö·Ÿ}ôÿÓGŸþáåËÞf^ýö7w#™z;MÏu^¾.>T}™uDèî ­÷ÕŒµ¶}?ââºû{¥Ey=:Hòfù¤¼$yZ>(¯GI–›ê4ÕeªËT©ÞS"9©Öûj$ßIõ¶jQrR­÷ÕH~êímÏ’›j˜j˜j˜jšjšjšjšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘j½¯†rR­÷ÕPNªõ¾ÊIµÞW#ùAªõ¾ÊM5L5L5L5L5M5M5Mµ™j­O̹fŸW7(¼«¨ÛŸóuܶ?G/®ÛÇÅíÏ|ºFåï?yùéÇÿøÙë~zƒÍÝŸBÏ|¨í-[ûÅõ·wýÜmµk¤þèzëW=ý/P»F¤ª;Õ êÚ5"u£zJ½ïT'ÕbY»F¤ËÚ5"5YYYY&Y&Y&Y6²ldÙȲ‘e'ËN–,Y²d9Ér’å$ËI–‹,Y.±¬!ˆÔbY#¨w±¬ˆÔbY㨱¬á‡Ôdddd™d™d™d™dÙȲ‘e#ËN–,;Y²d9Èrå$ËI–“,Y.²\bY3©Å²&R‹eÍ7¤Ëšn@}ˆeÍ6¤&Ë Ë Ë Ë Ë$Ë$Ë$ËF–µ)dmÛžgñì™ÁmOÈXkÍ1/®ÚçÅ)¿ÍE OËå·¹äay·|QÞLµ™j3ÕnªÝT»©S¦:Lu˜ê4ÕiªÓT—©.S]¤Z» )'ÕÚeH9©ÖáÊIõñÌÍóóƒTÏÜ@nªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹TÏÜ@NªgnžŸï¤úxærR}ž¹ÜTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©>ž¹œTÏÜ”“j-ð‘|'ÕZàC9©ÖÉR­>”›j˜j˜j˜jšjšjšjšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘j-ð¡œTkå¤Z |('ÕZà#ùAªµÀ‡rS S S S SMSMSMSm¦z»;ȳXr#z[ÛÎ;ñœW7°Çº¸EîO·ü¼·ùõÉ{=2²~ÑûÅ¥·{÷uµÄ§4¶óÂ6¯®{úÃßë@£äay·|Q^%o–OÊë@£äi¹©.S]¦ºLu‘j=9˜rR­gK¾“j==˜rR­áå¤ZÃ/ÊM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘êm{µä¤zÛ^ ùNª·íÕ’“êm{5ä©Þ¶WKnªaªaªaªiªiªiªiªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT‡©NS¦:Mu™ê2ÕEª·íÕ’“êm{µä¤zÛ^-9©Þ¶WC~êm{µä¦¦¦¦¦š¦š¦š¦ÚLµˆ¬3?®ÆSœ1Ý·¬cÛ²†fw×ÅÕòêùtiË'¯>ÿÀþêóÞ/¢öW×{°î®»m‰Ù._µ…m®õ8É»»ìn*Q[Ø$OËåµ…Mò°¼[¾(¯-l’7ËMu˜ê0ÕaªÓT§©NS¦ºLu™ê"ÕZ˜D9©ÖÂ$ÉwR­…I”“j-L’ü ÕZ˜D¹©†©†©†©¦©¦©¦©¦©6Sm¦Zþ×ùÝ8Ïâymø—<-”׆ÉÃònù¢¼6üKÞ,7ÕeªËT©ÖÂ$ÊIµ&QNªµ0‰rR­…I’¤Z “(7Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¦ºLu™ê2ÕEªµ0‰rR­…I’ï¤Z “('ÕZ˜D9©ÖÂ$ÊM5L5L5L5M5M5Mµ™j½…ø Öh¦oµ¡yßÏËÚ~5ì‹« Íë隤w#Á~÷Ûß~öò“»ùËÏ– Ý]}WîWKjYÃ~^¸·uqÝý¤$-”ײÉÃònù’¼ŽfQÞ,Ÿ”ï¤ZG³('Õ:šE9©ÖÑ,ÊM5L5L5L5M5M5Mµ™j3ÕúvßÖìÏÊ嵬Aòfù¤¼–5Hž–ÊkYƒäa¹©NS]¦ºLu‘jÍ¢œTëh–ä;©ÖÑ,ÊIµŽfI~jÍ¢ÜTÃTÃTÃTÓTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹Tëhå¤ZG³('Õ:šE9©ÖÑ,ÉR­£Y”›j˜j˜j˜j˜jšjšjšj3Õ:šuÞLìÛHvÔÙ¬yœ7öÛ×EÞbÚötÃϧ¯~óî)YOgçãüèÛÖr]\ú8 ÚŽ‹w&¶‡üéÔØý…w³‰óœäç78ÊÓòAùù Žò°¼[¾(?¿ÁQnªÓT—©.S]¤Z›®)'ÕÚtM9©Ö¦kÊIµ6]K~jmº¦ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©Ö¦kÊIµ6]K¾“jmº¦œTkÓ5å¤Z›®)7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEªµéšrR­M×’ï¤Z›®)'ÕÚt-ùAªµéšrS S S SMSMSMSMSm¦Z–¾Û~þ\£¡T[Ú¶XkÌ‹ëââ¹mmºìëÕo^½~õñg¯þëËþÚF¯ºcßkpvd^|”۳嶋gË=ÞºçùUÆÅe×wîϯ§Ô·ûöç×IõúvÓþü:¨îT/©“,“,“,Y6²¼Ý«Ÿßçvõ3ýú^ò°¼[¾(¿Ý«CÞ,Ÿ”ßîÕ!OËMu™ê2Õeª‹TïÕ!'ÕÇ{õçç;©>Þ«CNª÷ê“êã½:䦦¦¦š¦š¦š¦ÚLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT§©.S]¦ºHõñ^rR}¼W~¾“êã½:ä¤úx¯þüü ÕÇ{uÈM5L5L5L5M5M5M5Mµ™j=c}‹m[ÛÕÍÄïƒëdKßúZÙ¯®‹‹§Rµãén¢?¼üÐÒ¡«úqn0®³Ô» Ʊmýˆ‹ Ÿþ˜k9‘äõ.ÉÓòAy½ Bò°¼[¾(¯wAHnªÝT‡©S¦:Mušê4ÕiªËT—©.R­åD”“j-'’|'ÕZND9©Ör"ÉR­åD”›j˜j˜j˜jšjšjšjšj3Õfªõ.ˆñö´ë3òz„äiù ¼Þ!yXÞ-_”×» $o–›ê2Õeª‹Tk9å¤Zˉ('ÕZND9©Ör"ÉR­åD”›j˜j˜j˜j˜jšjšjšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕaªÓT§©NS]¦ºLu™ê"ÕZND9©Ör"ÉwR­åD”“j-'¢œTk9妦¦¦š¦š¦š¦ÚLµ™jû«ªžîݶenû‘íâ¸xº_˧;>ýñëüüépá|E6ÆZkÖ£»kn_ÒùëhÝkŽÔñ¡Ù..¼bÔ_òEyÍñ%o–OÊkŽ/yZ>(¯9¾ä¦š¦š¦ÚLµ™j3ÕnªÝT»©S¦:Lu˜ê4ÕiªÓT—©.S]¤z{?§ä¤z{?§ä¤z;*9©ÞŽ…B~êí`¨ä¦¦¦¦¦š¦š¦š¦ÚLµ™j=æš­?§®#¢PÕê%u…ºQ=¥®³¡P'Õd¹Èr‘å"Ë%–·C¡P‹åíHèóë],oB¡ËÛqP¨Åòvj² ² ² ²L²L²L²ldÙȲ‘e#ËN–,;Y²d9Èr’å$ËI–“,Y.²\by;ó µXÞN|>¿ÞÅòvÞj±¼ö|~}ˆåí¬'Ôdddd™d™d™d™dÙÈòüݾçY÷y5ýð³æ®ÇšÛ–ûÕ=D^µ[ž–ÊÇfyXÞ-_”ÏÃòf¹©.S]¦ºHµ¦_”“jM¿('Õš~QNª5ý’ü Õš~QnªaªaªaªaªiªiªiªÍT›©¶RÝ·½$û·ëúC¨ƒêNõ’zT7ª§Ôs§:©&ËE–‹,Y.±¬q—ÔbYÃ.¨w±¬Q—ÔbYƒ.©Å²Æ\R“eeee’e’e’e#ËF–,Yv²ìdÙÉrå ËA–“,'YN²œd¹Èr‘åËšfI-–5Ë‚zËšdI-–5Ç‚úËšbIM–A–A–A–I–I–I–I–,kvUG˜¶ƒFD·áÕÜÖíê"çýðªoO,ý—W¯ÿóÏV÷(ãŒW¶ýâÒ·_ØÅâÚ|8Zlg=/®»š]Qž–ÊÇfyXÞ-_”ÏÃòf¹©.S]¦ºHµfW”“jÍ®('Õš]QNª5»’ü Õš]QnªaªaªaªaªiªiªiªÍT›©¶R=Îïo—ß®†W”‡åÝòEù8,o–OÊçnyZnªËT—©.S]¤Z£,ÊIµ†Y’ï¤Zã,ÊIµZ”“j´(7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª5뢜TkÚ%ùNª5Tkâ%ùAª5ó¢ÜTÃTÃTÃTÓTÓTÓTÓT›©Öôk7èK†LÓ¯\³E»¸./ØØ÷§{£§_/?ýø?{ý¡)X z¼}‡áý‡¨/p^½õñ¶ºŸÿFæÅuWSÉk1´äÍòIy톖<-”×zhÉÃrS SMSMSMSm¦ÚLµöD÷Øöc<§®5ÑPÕê%u­ˆ†ºQ=¥®ýÐP'Õd¹Èr‘å"Ë%–·ÅÐP‹åm-ôóë],oK¡¡ËÛJh¨Åò¶j² ² ² ²L²L²L²ldÙȲ‘e#ËN–,;Y²d9Èr’å$ËI–“,Y.²\byÛû µXÞ¶>?¿ÞÅò¶ój±¼m|~~}ˆåmß3Ôdddd™d™d™d™dÙȲޜûöü Ü1×-}?ÿ íç}ÍÅuíé³Àr¾èÇÓB¯^=Ü>Áx/~ùúßÞ¼û›ÏÿÏŸþåÛ¯¿úãÏþÉï?ûù¿þæ‡/þß'Ÿb¯ nìke‹Oöîê»ëò¡oóLÛÕuOÿƒíçoî’Ÿ¿»S–wËåçïð”7˧äÇù›<å¤zl¤zþ‚±œTTTƒTƒTÃTÃTÃTÃTÓTÓTÓTÓT›©6Sm¥º¶mŽõœ¼ï–§åƒò±Y–wËåó°¼YnªËT—©.RTc#ÕØH56RTc'ÕØIõ|ñg9©ÆaªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹Ts#ÕÜH57RÍTs'ÕÜI5R̓Tó ÕþÕg/?úü÷Ÿ}ô‡—òò}þÏ¿yýñ?ÝÝcn³¯µÚ~õQêk¬µË÷Ç> endobj 489 0 obj 16092 endobj 491 0 obj << /Length 492 0 R /Filter /FlateDecode >> stream xœÅTYo›@~ß_1ÉÛa¹Ç­Z¡TŽ‘Ú(ÊÚ£Fâ¨õ¿ïÀ÷Ñõ¡ƒ9¾o†=2¾Z{8ž€0gÇÞ¦ƒ#À°{“eƒ0¹° ‡^¶ £§¦‚$:ÔC$à+ÂöúFÎ~3\¦ë‚wl;©ßzðæõ~±‡€}úlŽ$gŠ„Ë-ÛBDË—Âk?‚^ïüïë•ï¿h_w«£Ý¿Aðmjr¯D‡Šá"v·õµçÍêqó¬í^ž‚ÕO¼ flºøll»: ÝŽú9¼[”™Ã2qî™,Ñh?[éorCÙÈ¢j·®¬ŸzªF”¨ð¨ó*<ÃÀ)ŠùVÝ´øõ…r ²pw¶ 6^þ)»˜b[{C­ÓT]Zi}†©›¬ÓcRžÊ&®ªH0]0<޶M™Ü>"8ÄPŸò}™¥!ÐëAJÑÈ?Ö¥µÜgqûDq"ß³†¹írÛú"÷Ú§„W»q\Ž:ºy ÷ !·á.J“$®êQOª2•u™çeÑv=XÒb›ƒlFe軸iˆ[ÓkoÓ»l#+C™e'­§B«™VÅ2Š+MñtkÝâ¦KƒAaü^zFF§±=è²^ÜlD±c,IÈeX•PÉæW@˜ ¼a“–Ÿ,ø–ýj±gÙ endstream endobj 490 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 491 0 R >> endobj 492 0 obj 511 endobj 494 0 obj << /Length 495 0 R /Filter /FlateDecode >> stream xœÅTKoÛ0 ¾ëWðؤÑò+9f7`(:$ÐEF,/b‘=¬û÷£-·²ãúšù%ê£hò£H™H7ï†x-a_²ó€yKð£ #!”0È!œhÕXo v xdCøÆž_H™’Á†—¿ëS¶ùï4xuÿ¿ØgÅ>} ÁCP…K‘ŒE,CDôW°¾\w—UÂóÍ.IÕ]ÂÓí=ß%›/üöÔwgëKt¦“7¼0Nv<ýù 6Ob¿èQCH/˜YÂ-ðУª¹ÉE¡Mã€ÂÔ¥›ÝÕeYWäÆAÇÊÉí!kÝì-”õ¬±©#Cú ïųXŒnÚÚhÞœOÜè,׆7«6{åM›µz‘_€ÑòOGᎸåº8V:w@6Rf' %|v”ÙÞÔ`²ö  ù 2(~WûöXWbTX[ö¶Cc endstream endobj 493 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 494 0 R >> endobj 495 0 obj 440 endobj 497 0 obj << /Type /Annot /Subtype /Link /Rect [ 344.596 496.501 491.836 505.501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 500 0 obj << /Type /Annot /Subtype /Link /Rect [ 512.757 496.501 539.997 505.501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 501 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 485.101 252.0 493.501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 502 0 obj << /URI (http://www.lispworks.com/documentation/lw51/CLHS/Body/f_load.htm) /S /URI >> endobj 503 0 obj << /Type /Annot /Subtype /Link /Rect [ 222.766 438.89 239.986 447.89 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 502 0 R /H /I >> endobj 504 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.819 438.89 536.669 447.89 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 502 0 R /H /I >> endobj 505 0 obj << /URI (http://www.lispworks.com/documentation/lw51/CLHS/Body/f_cmp_fi.htm) /S /URI >> endobj 506 0 obj << /Type /Annot /Subtype /Link /Rect [ 137.15 426.89 186.03 435.89 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 505 0 R /H /I >> endobj 507 0 obj << /Type /Annot /Subtype /Link /Rect [ 192.07 426.89 494.03 435.89 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 505 0 R /H /I >> endobj 508 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.089 264.0 82.489 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 509 0 obj << /Length 510 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯ °—¶€i^E©Å¤«»uh3´vwAŠDÇZdÉ‘d¸þ÷;$%K–uíC—oçö ó0¡ˆÀïÔ|TÀP´™<Ôk)†¸W/IQ™DT%Jͩ΀5#ø¸C0X£?'Ù„ _&W7°#û 鳳ċÉûŽ|³C¾»ü®œ²ÿE£ƒõŠõ ƒ?…­sN6¤ §;Ç×ÛU+»5Xq²ÍVZ#]"nèìqßGí ­dÇÚÂï'œ »ÉËådöZ"JÐrÕÆ¹â°‚}˜†–tõÄãOoÐò·É|yæýï Ù™ì£1 :xÕ'„Л¬gUm“3é2ÜhgÔÂG,ÀÄ“æ¼ï^¿y;ŸÎ//^ÂgñþíôÃüâÕüÃtñ÷åòâ/ôM•zâx91Ñ(£;çy͘êð1‚VÎ< oSÝΫugR>ì¢3¿-Âè^WíB¡ÃX‚CV…ŸÛù*/aJò¬§6 &((ëÞ~ q¾B†t•¤7P«¨%Ç$ `¤çèÞ…Q‘7»Ô§X‚¬@ÑZÞÂÑ’(ð‚3UÓ ûÓ3Æ'SmQŸ–éÔA8-;B['ÊAY?þ„¾l  ÕEq·Ûè¬*Q˜Åè0Ýér,p©`®(!¬NÞËæŠAâ@üù|@¥S¢è`JbŸC®ùR Ð;~Œñkô1>¶G‚ÁïËo2b¦lÈGqRNÏs˜qÞ;÷•fSŸ 01ÊreÊÇ~DëvZ‡Î$oÇ÷Zo»Ç ~µS(,†"©èœuqå&m]sóuX¶“[­³væ<w¤t˜>‚¤ê9Z±MTk€Ó»®ƒy#â´²•Û”ØB—Uîê)IJ´Úe‘ý³++ÔdLR!Xϳ6§ð€2ž‡‰Í„pÊüžE.Y¦'ö¹+ð8Û‡‡î–.:¤ÝsYÞŽ£¼ ¶F±ì®]°Žw“]8Zu\¹ÝUöYY.íB¡ÓDwdžPêY»²kRÒ9@WØ)D¦¨M ˜“Uús… Ëu»YnutœÔ×£÷ÄP ik®AO¨iÆ} Oa¨Ðl >@qtÕ§Sû4°gèÖUµ}>›í÷{œ&åvŸ÷%ŽòÍ,Î#{¡Ø°›¥{Ig?¿ýu1{™Ç‡Ùê“ѯ«M>O`Ïi—ÒnÐHïP]ì=CÍ“€ƒKÉÔº3:Ðzkn_ã­>ÐØÓ×ùjHb#î ;F Y1• }+vÑfûi• ¡Çؘšgè1(,öî0`?jU z¸> endobj 510 0 obj 1457 endobj 485 0 obj << /Type /Action /S /GoTo /D [511 0 R /XYZ 72.0 720.0 null] >> endobj 513 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 497.106 306.0 505.506 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 515 0 obj << /Type /Annot /Subtype /Link /Rect [ 450.0 263.564 522.0 271.964 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 516 0 obj << /Type /Annot /Subtype /Link /Rect [ 138.0 251.564 216.0 259.964 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 517 0 obj << /Type /Action /S /GoTo /D [496 0 R /XYZ 72.0 720.0 null] >> endobj 518 0 obj << /Type /Annot /Subtype /Link /Rect [ 154.94 229.954 328.94 238.354 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 519 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.086 270.0 82.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 520 0 obj << /Length 521 0 R /Filter /FlateDecode >> stream xœÅ]oÛ6ðÝ¿‚)iEJÔä«WlH³56Ö ]h›Ž…È’#QMüïw)“‘e/yÉlº;ò¾Ç“&Âð ô#ÍZn'–¡” 8±$– ˆ†„¡-²0C…Þ备àa6°A_&壓¯ß`q…008¦CV9Æ8zæS—ÙÔúd\º[iœ‰åˆd!N˜ÞÏ Ãôæêýõ4˜}¾n§W¦·Áìï›ùÕ_ÈH9ðFYÆ ð1ˆÎ‘”I Ÿc@‹j!Šbd)…DÍC+j‰µXÞK…j)V²F;Tâ)ì=JG<¢Qˆ3 ’#ù“XÖUÏp:rI²ˆgYÙÈÍ:U=c6¢)Â,¤”€¬˜Z/ºÏÀqNGv/ƒæ¡ŒkAãésA#£j~ü ý·GQ‡4e'‘a»ªïÚ­,UƒD¹BŠ¢•͹ڈX K!’Ä›ª”á 4s°8Ö9Hm>ÈfYç;•WåÙjÔ5B(Æ,Š ã¼­Ë½CAœ„º¨J«tÔ«Cl±pZ—JååÝ QG»•Pþr»ÜøœB9,_¿PfÞø|h!1Pýê*ot…¬.ÏU !Ñ ^µlTUVйq2øjëXzÌ‹¢?‘¹BâNäå €PÈ#‡ÃS[{Ó'±Ýçë¤qHRÝRþªz‹1N ða[o³|%Ñt½–KuVeLXHbhD„Z—g·Î]^*Y—¢°=™2P• Ç*U-&!§ ÆÜ ûT­òu.À•\‹¶0­Li~£Ï,K§ÜNÐÊ9fFØQ—Pµ=S2tG3e4亯¦±ûÏ×p2NF KBA@ è?æÕÅÈIÈ¡–kí„C+ßK¹ó7B»vhµvðãFBjo¯9 qÄàáé…ŽÙÞR–ëâ(óMî±/Eé³:xWW‹`Fˆ"ÅÉ …Ü •/5'áaÚt[? âü°o­ÚÊMõèýwùdŠÎt+¿rðÉä“ ®½J/cdÄóeÃÁÇ)Ë8OÓf§^xÞ¬[ÕÖžçB)¹Ý©fÜpÛCü >âÕ.œŒë®Øõ£¶ª\Vj§#l: µÙ7`•ÃõžûÆá¹ò`îUœ!ø5f(}l+¼Í±Û™µ’×¾²–'”–#!‰ñ $Æ’KÍJ/­rHY9Ø–—·5/,¸ÎMj Ö_i–¥q0œ—¥lS°†ô˜«ÃŠJxkUíàeµÝ–à¹*Ñøj½…"ovž úê€Éeì¬R2ˆ´é¼˜®3[0lïÆ5 íŠmÉ=Á ІR‹ {ÒïõeÊïò°³Ër/Ù©éØA¢lbzÔ$ðù¯:u]Õ#~³a·6‰J™®ÕeÕêÛË$J“rm<ï°º-K;ÿhÔF^ƒÖ²°Ç]÷оjä;N¹ª÷'Ôœdb¸îý±¦t“̈ÿɰKŒÑ#­.¢t„ .Až‘Ê·pÓÁ9ÑA¹þq=¼æµnÎa°N`x?4HtÒ=¸k2ª/Y­úˆUˆàüÛÀظƒsBd†|$Šî:Qù÷—ŒQ,JBg°@íuÕMPPF‹ý¹)ŠQ ó>¼¡$œ¾jpc XžQóNhçÄ¥ì^`ðšåªíóÙŽeÐ#¸–N³W)OXͰ¹õi¼*šêð/€{ EI¬§%ªßÄ»·ð£DcÄa~öÿPðkx$±Ýÿ úû/cÚŠ§ endstream endobj 514 0 obj [ 513 0 R 515 0 R 516 0 R 518 0 R 519 0 R ] endobj 511 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 514 0 R /Contents 520 0 R >> endobj 521 0 obj 1456 endobj 524 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 312.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 527 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 318.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 528 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 306.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 529 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 674.1 294.0 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 530 0 obj << /Length 531 0 R /Filter /FlateDecode >> stream xœÅUK›0¾ûWÌq÷µ |ÌnÓJU)¤mµÚƒÌ‰‡¬ÚüûHÈcÕô%‘<<ß|3c³% (þ¬fñ%‡uF¶ÏÁñ:“ð€¹6A' H›·ÞK¸˜—PØÀ3É …ïäåPÜð›Ðãpíæ%Yà7zs| oä!$_¾ `Âx_"Çž øxØ—ÍÃ!Ìàån:Ÿ<̦Ör1³ž¦“¯Ó'kùkN~Þ¿BøƒLÃ/‡ñOàµhsh‰´Ýæø÷í¶å#‡péØs0ƒ}omcC‹Án\i׿n5‰Ñð1ëEtOƒ²ÏÇMÁ/†ï ÅF3!ÄÅî߸d']·Ð Ì8ôä1=z2ði±Viº³t®V©¶ªmj•ZEº´ª]^«?g©#ãÿ‹%ÕuPܽªÔU]”g ¬ªVµ¾d.Ék€â‰üC醘8^xò¼{ØQhŸÛ~3w>sLìyQëÊÄ83¨˜®ômêy)fG¸ÑPí²U‘&kÀ+ LTÐ=‚Õ"«÷´¶ûØÞ™ØŒÉ£à3Œx1?°)CVï´Ó½p‚álßEIë²ô¸,²Ay,²¬È›¼{K’b½Qõ ôiœtˆ7R¸RŠæ Ÿäñq§Î})v\¤&åG¼’=%¬n’c¡{]í]j2µ.‹A+U½Ñ¥IbÔ‡! ÒåžÄ*ä  ~Ï×uRäöÁˆ-È_öcÉž endstream endobj 525 0 obj [ 524 0 R 527 0 R 528 0 R 529 0 R ] endobj 522 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 525 0 R /Contents 530 0 R >> endobj 531 0 obj 560 endobj 499 0 obj << /Type /Action /S /GoTo /D [532 0 R /XYZ 72.0 720.0 null] >> endobj 533 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 495.156 306.0 503.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 535 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 209.476 264.0 217.876 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 536 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 197.476 312.0 205.876 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 537 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 185.476 318.0 193.876 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 538 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 173.476 306.0 181.876 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 539 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 161.476 294.0 169.876 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 540 0 obj << /Length 541 0 R /Filter /FlateDecode >> stream xœÅW[ÚF~÷¯8‰T¦s³güÐJ$¡Q«d¥ ¨¥y`صêKÖ6Jöß÷ŒgÀ »ôa HžÛ9ß|çj"¿÷P)‡U=„5ŠƒHÂRœ“„ÇP@Ç»SƒßðááàþˆÊˆÂûèóÜ\Eo=V× Ï£Û¾Û¡/Ž?¼`ü¹»Cç•Î/ŠtÎ9؈%=Ü8n¿Þ¯v€Â¯áŠÇv[y°txú‹ø¡çãŸgyО·c`øràî¢7‹èÇ_b`›>ΕÀ¢yê>|~'¯¿Àâ·h¶8ñþ ›ìÄ‹{O¯Ž^Õ”RvÀ©ó¬ œ<¥SXOjÄRO Mbw^{w¿Î§o>Ì&óÛ“O³é»Ù§Éü¯›ÅôOðjöœrÂ$ ŠôTËßœ«ãóìÂyxŸWK“ç°Î³Ì-4[S[XÖfõm¡¶fmkhËÖ|';Fj„‘d„¦U'^õG³ª«ÀyË%)‰™NSÅ‚åæÔN0Ab4&ZpT†ÁäitŸ#âZŽœ 4'ÍC>ñÜ&Ͱ·š“†Ÿ~†§)1áŠIL©ÔÁÌÓún[زmÀ”køÝä[Û\Šk •¦R 7UiÉ3 uBRç%Xˆ+Û¬êìk›UåÅxdŒp%)å4 .¶uÙÀk˜ô¼ª6›~ÒÞÛ~‚ÛOB¼ìçÞ¸ƒ¹mÛ¬¼;£êätkÚáövu?”4m?ËÎ]ïXgÖ .û°EÏ`ìWméBdýÃ¥ä\Ù«¶M[Õ#‘5éXœ5¾‹´Smð-Ëó}Rf-˜;“•ψ3‚Í‡ÒØ+š}7Å×ür¸q•ÊPYªÔUá&¨$2”ñ 7ÏÖf›]µ×DÉ ‡0·˜ÎoYÙÚº4y(9àC ­v¶X“£LuÚbz¨ícµÎ6™õ×vc¶¹/e­Sñb*% ‰Æ,¤þ´#e×°|¼DLRA¤FQ4ËU¦”‚‘T`Vq²óÜÊvy‹Æ˜gíÖ¸ñE«Ê8!œ©T+š\®%IMõ¾Í­…iÞTûÆÜ÷EÂÚF.]sìãI†PÐDôxŸTçêîQçwض®„È«•ke“«¡¸ü¯PO´“,‘\‹õ¬Â2‚$õµH› ©<ÃzO¼ Å:&’&©æ’ï°½\š’Ór)CûÁÌm‹e•g+p-&Ô,ß»J€©¸Kî}Œ'cÊ1µ•¿ý€ÏÞGi_ 9þ}8•u}‚a½N_&°(ÔÍ`eSWÅ`ú¶*Šª 2¬eå`²ëaaz¶ãp Q­]ƒHÒ‘;=†#…º¨pxß!?4wV¢åû3Ü6ƒqÑ¿ÿ8CŠ#¬Ú`•®±T› l¶åÊ:2ˆ·Ûè_´„ð endstream endobj 534 0 obj [ 533 0 R 535 0 R 536 0 R 537 0 R 538 0 R 539 0 R ] endobj 532 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 534 0 R /Contents 540 0 R >> endobj 541 0 obj 1048 endobj 523 0 obj << /Type /Action /S /GoTo /D [542 0 R /XYZ 72.0 720.0 null] >> endobj 543 0 obj << /Type /Annot /Subtype /Link /Rect [ 434.767 514.401 539.999 523.401 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 545 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 503.001 210.0 511.401 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 546 0 obj << /Type /Annot /Subtype /Link /Rect [ 450.0 205.712 522.0 214.112 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 547 0 obj << /Type /Annot /Subtype /Link /Rect [ 138.0 193.712 216.0 202.112 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 548 0 obj << /Type /Annot /Subtype /Link /Rect [ 154.94 173.281 328.94 181.681 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 549 0 obj << /Length 550 0 R /Filter /FlateDecode >> stream xœÅ]oÛ6ðÝ¿‚À^Z â(J¥‡ HSoÈà&kí­+Ú>02 •%GMýïw)‘‘e'{éÒ¹#ïƒ÷}ÊýÌGþyêO(Jw³{sæ#NQ™#!?Ä”¡20C¹¢rÚCðK°EfÅŒ ßgŸ¾Àå`x˜‘±¸Žy9{çèW7ä‡ëw_øôyzC•..þsÜçÑ Éã'pù=íú N´nu•O›ßú!Ôöèß'í Ö 2íGcáSNÐÝìõjöóo ù­66Ïy'8¦‰ú¡hµCŸ^0þò Zý1›¯Ž¢ÿƒ]vE¥{0žQ !þ#›ºÈrc“6éZì¤6jÂaŒh‚IÄ}¬7—‹ÅGo~}ñz1÷–ïÞûùÅ›ù{oùñzuñÒÒ4LpÁSHäKûL)30`š˜ì˜-ÊTäùÉBÜæÕ÷­¨$º­DúU6¨’b-+TŠF|ǽa|°ÐÇ$! 8҂ߊ´*{†ÓŒÌü8I¸o¸ìTõŒÉ„&Ÿ@ÍF ê~FvÇáe®­õ´µ^}Ÿ{ÚD¯vôZßñhJÝ/¿¢§-óû>¶Àð]TwíNMD±F‹¼•õ¹\ñY€ã|DÌdWYHü Õ1ÁÜ!A¨ßÈ:­²}“•ÅÙì$i"c£qÕVE^"Ð×^”……›­´ä­ELÖ ¸ö­Å²f[¶=H·¢¸ËŠ»ÂÇüu#÷ºM·.§p$Dó(‚ô§É„µc¾‰„X``‡]ìXB%리lfy£('ûlÄ4¤Ÿ×Yv2B~0Ų<‡Jõ@5duVo‘ò^ÚV$›©]ÔI~FîÐâÀ‡t˜Éùw±ÛççS•‚W…d‰©ÿ«¢‘ÅZ®Á¥<†îû¢)ðV`[;$Y1€b€6YnÉ7e5Ài¹¶Û¬K‚Ajmo-™ioÃCL›®ûD3B‡<5mš‹¾ËË[‘[Qü=ÕÇhÂqC  !»} ¡Ÿðç';Õç—ã†"¡Yœ9AKý´ctyófŽþZ^]ÿŽ–ß¾¾Y\]"Uãf()’ ‘Að|õ!;cý¸ŒF2m<›öçÓ9İm„”øÄ”Ô2ƒÔšo62mΦ}H8&LÍSÞ½rm2È>•k¹m®§¨*MéNÐð‘°(Baûì–$H|-샨 H·ž)¿@11hh>ObÞÞåâtòÑI„ÁLB(è?æUý/¦8†Ì®²®„z´´ðW)÷.!”EË…¶¼P9´º©kÄ6uo…£OäÊg{p+ea1]klOVÛÌaOEá²Zx_•·ã–¬¼…#Oär'š,Uœ4ÆzÓÆÂÆX; aíÜ•;¹-ìÁ:«»—Ûù½‘UÑ­`V~iá“Á§ l\l‚ £œOUü„³$Ž9Ÿ`¶ê…cͦmÚʱ\4Üí›zúáf¡t6áxT[w²ûªç¹ÅÖ¥…‹²ÙBuxž ‡>­5¼ÊâŠækmñ¬q`çÜÉ8}àæ˜>ésLc;áoÅ~¯ÔHÞ¸/•<¡´˜pI\¢_òJ±ù0œ!£õ¢´°I/‡´©4CÕ`ýÊdXj C½¤²Ö3Ú©¡h±¼Î]7 œ–»=hñ«µ«Ö¹€½eï¼Am°+OÔ*#dä˜Y·˜2•g&a:ØŒ‘Õ ÍiÉý žK%÷G7Õ«”ßä@ÙE¹—lÕtì Ñ&0=ªø˜Äø«òdU•ՄݾêÖ1ñ93ßn:Pœ©\MË®JŠw;ÖF[ÞaU[ý~Íìv͆—á¿ÚôСlä[VySN¨9½DóxÂó”nèOØOÃýÄ—ÛÔÒ†¼H 0 ⌚l“êD9åýüϞРˊÆIÅæOK)ÑIó`Ö$¡²Jõ«*ˆ'>@'Ì ,:'©Í¦žÈ»qÒdßž³ì3N1 BA¬ùFí–H£ÛùŇ%àÐöý„ÆÿéÓ4‚ÁÓI쇬ÿ¼He÷a Ëó2kÚ®˜Ïn]Q¨Öµ0á„éîþ”ônö/Ìö÷“ endstream endobj 544 0 obj [ 543 0 R 545 0 R 546 0 R 547 0 R 548 0 R ] endobj 542 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 544 0 R /Contents 549 0 R >> endobj 550 0 obj 1606 endobj 552 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 264.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 554 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 270.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 555 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 318.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 556 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 643.364 306.0 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 557 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 631.364 294.0 639.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 558 0 obj << /Length 559 0 R /Filter /FlateDecode >> stream xœÅUK›@ ¾ó+|ì˜Î ¯á˜MÓJJ• R»Zía’ Xµù÷5 m¹¤yhûó÷ÙƒÁ€âÛ¬Ïç°MCãcàq°ÜÆå¸ÀmÂH¡±HðªKƒ·ú"4öðÝÈ _Œ—W î€bÂ/ƒË’×Æê¿ŽÐ»ãSøi<†ÆÇÏ0 at–ˆ "lÛ÷}‹ ÷ë‡0…—Á·ù,žÍÅrö,Ìõ*0^!üzζ\B]J)³<àtþ´˜}Z<™ëçe8û¡aO ‹ñÿ ÆêÔƒf_¯ÇGN{Ò 86íG.v¨óŸ½øµ‰¥}èÑØu(i†Þœºmj>ú¼ÉƒžiÐKý¥º+øí}ò,ôÑ[GÜœþ%»šbÝ‘ÁÖqª¢Þç§Ód½†“¦´V fI™wÄÎum%ž~ÊœêúC‘èÕ­¦2¹I”Y³Pr§ ³> endobj 559 0 obj 597 endobj 526 0 obj << /Type /Action /S /GoTo /D [560 0 R /XYZ 72.0 720.0 null] >> endobj 561 0 obj << /Type /Annot /Subtype /Link /Rect [ 434.885 505.501 539.999 514.501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 563 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 494.101 210.0 502.501 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 564 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 122.1 264.0 130.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 565 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 110.1 270.0 118.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 566 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.1 312.0 106.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 567 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.1 306.0 94.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 568 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.1 294.0 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 569 0 obj << /Length 570 0 R /Filter /FlateDecode >> stream xœÅWKoÛ8¾ûW °—æ .I‰"uèNâ-²p´öv7hzeÚV–IFšß¡D[Š,;ö%k0_óøf¾2O¿Žù‘‡h=x²k $×·KÂæ.` v, 1§Z¾áO}+øg(||ûŽ›s (ð< ]u•ðdð¹eßìÐw·ßöÀeüñÀøPe¥Ê Ç?Iªä¼Ú}½ÓJÜn½Y­ ºõ®Ô¶ÍVb#mkGêa§þ=ˆƒ60h-Â÷3Na9¸œ~ÿS£0]4<—.®Åóá0]÷"¸øÓ¿£é^öß9d{Y4¶w`Ðu̪¢”²W˜ªÌJ‹©†t®u ª'žê s^Õãû«áxüà\ßL†—ã‘3ù xè»ç‹}gQ˜$/0‹p–h(ž6a®a–‡Ñº„\‡sCñ’–áO²…&{ yŒÐ€¢f¿Ö|Fy¶8B? ‚© ̆pR™Ú =–õ õLع´(ªO¸òzN&5\ÇÂuЧĩ1:EËp=Åûì}üÞ†Æ\øRâF j¹a¾Ü¬uZ¦sø&]£ a’Q*¸Õp—¥šœ`ZI¢\A©/Y-x­‹(”q–%(ãÄå˜OZ‹ÓMžpŽÏˆ²Å¢™”+ÝLºÍÄòf7¯ƒÛÌŸãr•mÊf!Z…é2N—”wå‹2,ÛÛ›hÕ– [š;u±”ÂÐRöÀíÊõPÐõÁB:`'Û×ë¢Ìò†ZNÇeîu„vüs*dSÄÜ>ixŽ“kÕAÓHë¸X‰^´Ésd›­^¨4Ÿ@Ób ¸Àç¶S~†ëÉq®r)‰§|¬a)w“–:ë¹ )ã.Q˜™¬5™éÖdS¼:§­IØ/â¤-¶ÈòÖ,Êæú’çU\sdëʪ}Ô¶½–s¶¶Žì(¸]@'óC€l‡iï[Ò÷ðAØíÊÁ¸¹L²Y˜tò××]´ƒOÌœrÛà7òøvï{¼èöP£Ótöœõ䳄¸º¿ÁÝýþžÜÜ}‚ÉÃíåýøæ Lã°—9Ö£ÛàÉ.Hv$ÝÚì”]TPß.$ÏôŸµÒ:‰‘ £ÅBGåÑbò\Ÿ(!%…-ñÛl/b]T„˜ëE¸IêÛÙü)U×?Þ´¦oQḛ̈ò:{9êK@ 5/)äY—Þëæþ ¤»>éê B6OâršñÑ@Ï57 ¾è™Æ‘x"^áÙØk äÈvÎæÍg )e}Õƒo¯´((ì¸í·«N=:/ZTïSzŽú7ž'=ú?Gÿ¶œ ƒ{ç˜y£ÜZ©ÿÿ=ÕŠ¹NAb¾¿8³’Ö endstream endobj 562 0 obj [ 561 0 R 563 0 R 564 0 R 565 0 R 566 0 R 567 0 R 568 0 R ] endobj 560 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 562 0 R /Contents 569 0 R >> endobj 570 0 obj 1074 endobj 512 0 obj << /Type /Action /S /GoTo /D [571 0 R /XYZ 72.0 720.0 null] >> endobj 572 0 obj << /Type /Annot /Subtype /Link /Rect [ 253.798 494.931 400.103 503.931 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 574 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 483.531 270.0 491.931 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 575 0 obj << /Type /Annot /Subtype /Link /Rect [ 137.064 418.345 331.688 427.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 576 0 obj << /Type /Annot /Subtype /Link /Rect [ 351.376 418.345 540.0 427.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 577 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 406.945 138.0 415.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 578 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 174.676 264.0 183.076 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 579 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 162.676 270.0 171.076 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 580 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 150.676 312.0 159.076 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 581 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 138.676 318.0 147.076 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 582 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 126.676 294.0 135.076 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 583 0 obj << /Length 584 0 R /Filter /FlateDecode >> stream xœÅWKoã6¾ûWð˜*–oR‡ðbÝEw‹ØFØîA±éPYJ$ywýï;)Y–%î!Mˆ¤4oæ›áäqFßÈ=tÌÐf?{ gi†¸ GR!*0“hÂZ¢Ì}Õ[°vÿ,îѳ|FÐϳŸàåø:#CuðjvÛ³ïÞW·ß÷€Sö¿xà|h²Òä…ÁŸÆMrÎ^HAÎßôןNƒÜŸÁ‰·í^e!ÒáéñKÇ?ŸÄAN0ÈxÂ×3NÐçÙÛõìûŸ$¢­w'žk'ذØý0´Þ£7оù„Ö¿Ìë‹ì¿rÈ.²èlw`ÀuȪ!„Ð3LMfuÀä!}HöÖƒ‰0ˆÅ˜(é¾7^`¹X­[.¢Õí¯Ñr1·XF«¿>¬çF«õ|½@o@¬tãÕvÊq¬À)ÆÙ¥Ú¿ÓC1%Ð3´´U]”¶wR=’³ƒ»2ÙücëÞIi“­-û2ǼN¾õꢷI몷{(í—´8T!^‚‚Ÿ oB€«:©-nC¬GB,9&1dÊK¼O6eÑ ìm)Hò-ú=ɶš"-ÕsÊÁ²æE~J„éØ`år!XHÆ;[mÊô¡N‹|²Là à* Xyr—YGC1ßÔ÷¶[Cít뎇~Û±ÐoÓ]·D˜Bþu •#æb#| F@˜¡(ÃGØÆÿËt?ÎÌ”¾Î¡ûä”;kón³I²Ìn»íÞ—t¥ ä?;ö™äSTg\ ئՕˆ€ #zÀ)ºqT Ë’[~M+Û[U»÷Éo–>÷ͲK}³óÎàvûöØ)³»äÕß+»lA êçÜå`(p+­Pðoû‚’`Zb¦¡Š %±ø–ì²é `aDl$—¡;Yß\Vš¦ Ž<#’C±‘„+•1¾Þ/d…£Ö1ºšÒLÆ ªÌ°1H'Ç<ÆÁ1c®áJÐdZÉ“è˜a¨Æy]ò‚S:P1…]©ð…Ã5oô^¸­CæÓ­E‹ÝÎnêIÎp%0Ñ”PšöÒ~±%4}Gø4¯m™'YKâþµz¦ÄH -¸f¶÷Å6Ý¥Ök ¥„\œjµn´Ó†Àv œ7X Uݧðn°4 T¶÷Ø\ØÊZÙ$ Iw”±„àšlëqc› ”­Òú¸õd¤EL1UÚ ¶úªûQºæ+tIOe=Ϫ¢ŒOsi3ÚH,˜pÃi3˜^PÆÌÏfìé"LÞ΄Ðךxæ&±}àJ/ë9#¦4ý¯¦®‡eøµ¶v)x¦gþ QŒ`Ê¡1é´zúFQÊÐÝʨS5UÇý]‘¥ä®ÕËû *´­yÜóîvö/+•â* endstream endobj 573 0 obj [ 572 0 R 574 0 R 575 0 R 576 0 R 577 0 R 578 0 R 579 0 R 580 0 R 581 0 R 582 0 R ] endobj 571 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 573 0 R /Contents 583 0 R >> endobj 584 0 obj 1124 endobj 586 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 270.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 588 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 312.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 589 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 318.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 590 0 obj << /Length 591 0 R /Filter /FlateDecode >> stream xœÅUIOÂP¾¿_1GMìó-]€Åh P£†p¨P•¤‹¥5Ê¿wÚW -ˆì’™Ìô›ýMSÂá­ÄrÌ#’V2–iV"áSa@o@ˆ_Õ±á¨y‡G·d:Cå¾k›+Á2ªù/4ììþ¼‘®G®ûpÞë®D’SS0¼ll*…S\¼¦ý»«¹ÃNÉd4Ð.gàÝ× &e&"¹´@°vìvnܱ6yz't½F%$ÿP‰QC9‹–CÒP:kjj´•ï¤øêT*J”ïBV¯¨ D±*EæÁvi°z͉:«óãÃdI”P»1¦~´ûg.Ù^›-Ôm5ŽÛôœvzlï„,–™ÿZ–†Ú*ðÁJËÖqîÌ=pqª‹0™ûa¸Ö‚ø4Ox<þèé7ImíbÇñ0ØÅh™7µl‰ ÇPö‡IdÊÆÙÁm nn; ñ/ÓÏò60³ s°ÅÅþâBìã{\[G=r\Z¢Pâa{q’ÃÇ*È‚8‡e ½$Š’ ÒZFä“YbS endstream endobj 587 0 obj [ 586 0 R 588 0 R 589 0 R ] endobj 585 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 587 0 R /Contents 590 0 R >> endobj 591 0 obj 442 endobj 593 0 obj << /Length 594 0 R /Filter /FlateDecode >> stream xœÅV[oâF~÷¯8¢R“H‰;ÛcWM%²I¶[Q¢šJ¼0€%cˆmv³ýõ=3cs1›¾¤$’Ç3çœï;×ñ‹Càß•zˆˆÁxá¼T{T[~Ôs™ ¨Ö>¤JjgÁê>Œ.æð—“9>:ƒN€ ÂW‡4Íiåžó¸ƒ¯NÈ»ãï2à”ý/ †ÿÂÕÉÙ;ð=²²“¸ÍþvWr³‡;[¥U¤«§!b–Æó<êÙºAìq¬<|?p3ç¦ïütï%Пnë\pÜqC©ƒþç1‚þïÎ]ÿ ûﲃ,*ì3H³BèžO:³¢òɸÔÒ8e‰‹\øJ>4 ½Ç…X¹0æï×Ù¸D­Zçx¨Ð+Ÿ"MA«Põ¾eeüZ+F0J¸Þ°öFÿþ‡žE²xIáGt©lSnµ[Ó@ Ô³™óYq”: ¬׿²ºÚ†úûA£œ¸<„p*Œ•v>[/dV˜Î <ÇéZÇÉ« úÌ>%D ÷ƒ¥³¨´¡%,§–:Ùà [œ0¾IÃÃûX*íºBs©ôÐWõRïÖ–û†èEØv'ž±}+‹qž¬v+ÖÚ¥Œºj¢ òâ“,×yVÀ\…ΑMµÒýk–íêm&3™Ç%öVµ¡®Z—sY/w"ZoÏ'Ü #ôÔ | Ë“™e‘8¥ëÖèý“Üâ|sZæqV¤».&Y¹Ü Ìa0ΰ&h¦š1*Œ—ÙmfÚîפœC ФŠU<–0‘i²HtQÈx<ÿo%ÁœûŒ#R]Bw¯ñb•Êãݬ§¶çíQA«1¬L–¤Ã‹C/9 âØú­îŸNË"Œ-n³}6].­Æ=f1~ÿð`³4‰Û­ÏqÞ²aCAM­ÖÊŸÙìGMîÍÙ¬® Ò$lHPbcàÑf¨J,èo’­"7<ÇÄÆÏ8ª‘¬X~“¾Âž«L]bD/µß—JÝ/ìEñÛáÃce²nƒŽÒÖ«eqŽ[i ™Jü* Ñ l?ë…ëF#8›Ç_T“ ®µ $#¦#SyxÁ×7¼ft¦:[ø§hõðmÁð¹×ÐVÁèÝuî>ôA…ã¦ý÷OÀMûoø­ýü©û†çxâ~º…kÜ}ÂÅðÚÝ[%ï>·;€X–èù^`# ߟ>Ž_JhF¢_½d"án:ÅHŸ¼ 3ò]ÏWWQPiv—™|ÃÀ pPG¿"ˆWh4ŽŸ¿B <ü„æ< ±Mõ÷£ó/XÆK endstream endobj 592 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 593 0 R >> endobj 594 0 obj 1065 endobj 596 0 obj << /Length 597 0 R /Filter /FlateDecode >> stream xœÅXÛnã6}÷W(ÐÝ Ë;¥´]ÀÙM)I»×Ý}m9q+[Ž%#I¿¾C]lY¤.~I¢)ž™3ÃÑŠüš‹öš.ÅEš!®Š)©˜I´DÅX¢ÈùŠÆ?.ÆVô_Y2+І{ç ˜Qõ!ôÀ§,²ºð)wé:X†¹S „‡˜‰’æy/Œn?^üñËÝÅhtusrìA9ÇL›§µû…1]ˆ6z¯’t³¦ V¸Qø¼Þ„I²ˆWh¾‰—(Ù®×Ñ"œ¡—§x3CÁæ~» Wi‚K¿´Ã/A1ñ 0©œér»š¦°h‰i–PùXRÏ÷5-$½¬Òà¹ú2J$ö„6‹™„²OM O8žL£ÓŠÏß‚›u }'Ci˜S³ˆ'QºY¬îÝ`‚É"”“(l&Ñ.L‰Ç€ ZI#I¶]!áÔ%p‚`“mÚì ×ÇiQú²næÄÉñÓ;³Òî|¦ZŠ' áªØ ÃrÁž›¡ß‚h&ÍF›ü––¦¬0)]ÉdjB`†(‡áv2Š£žhWJ¹©ê`zYNâD2; |Z Y‹Iˆ²5ÑbfîÌá¦Ý$FV”S¼è´ÉÆ Ö ÛAÈV&𲬔V6ºI-\ƒ+´[°¿ Ba%À#ɵ¹n{,ˆ ”¬Ãi•ò€GyXIí{~‘7ÕL?\¾þäÅ“¿ÃiŠâyÁsP]q÷na¾Æ”)H%R(ø!L¦›ÅºÚ<\”3ŠQ°‹çÀ»0ÝnV :­íþ-ˆ^M£+Ç•â_NMË®m¯œËšaù%}wã]ƒÜñì¶w9óô°˜>ì¾-ƒ—ÝxVH—“ŪºÎ~yEñSrf‹CÚ¥äj÷ ›óHº ý’ÛÆeõ«™‹r‰€ 3!èö앲 ûƒC x§YRõS‚ôT¹ìñ4 Œpúèii¯sž ‚âM[LÅœ›çq¸£ÖóVpW:H‚µé¢‚i—«ÒÃ{UÛô¦63ˆQšº+˜Ý1° íšx.Èw-2øÜèQu„vàº$Wj_CžµÖ_Ÿ´a]jK7€h©ûªmAºÕ¶ ]"]qÄB÷^Ѷ\JhhÚ ä¢½…¨#ºu¨#Ž’¡îxæmX—ð' BqÙW Ò-q˜"©¥ô ëûNPtœ´|a!z¼åJè'„)_kY´‹ç`¹ŽÂæSµñŘK؈D”‰Uÿùâ,?â¼™Ç1:Û1ÞL‚Í—‡:¾ª­Ûo~|ÿÉü 5ústf®W.®Ç§Ãñøîêü×ñº¼¹ÁçûwörŠ‘NŒú×e”âìx£Î‡¹ uŪ? e?3Þþjƒ;M endstream endobj 595 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 596 0 R >> endobj 597 0 obj 1260 endobj 599 0 obj << /Length 600 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_qè€%j¤$R ¶iêlÚ¸±u]ݲM'ÚlÉ•äµÙ¯ßQï–(¹Ý‡Ì ,ŠâÝ=wÏñŽò§‚Cu.ƒåvð)Ÿ£ ˜<Ÿ²9PË`6l!Û°Q«jVŒð’-ÂÁ¼?>|ć+ (ðy@šêRáéà¶f_=!On¿ŽÀ¤ìA 0¤¬¤¼0üFJÎÁÛ"‡OjÄ•óÕljÐÌæp&³­mòHç× H6ÌüÉ®~Ê ¢cîáÓ'p?x1üpm%0[Wy.Lœ1檃Ù>œr÷ì#Ì~Œf-öŸ8d-•íÒ„ެ:„zàSʬÈ}Ê\ºñ¶2sJËæ„Ûj½“ Lo_ÇoG“ËÙ«ñ d¢¥Å妲k9Ñ9c¢)`ö ÀUÄI´_&1x i_v‘Œc? `…[ð Þïv_® ÜÉÈK—®À‹î÷[$±Qx'4ÞYÔ .Aƒ<3x½– ê.dºÉ]æŽë šrú$Þ—BÐÕ£Ä6ÐMô΢¹é§ÇÒ¬Œ?m†™%º*†œétPH å:0Eø:]`”wÛ©V1šï‘´¤¹ÒþFÜÌÖáF¦ãnÌŽÖÆO€€ö›&$Åf$µ0 9q°ÔZy”¥¶î“užr}~3,%Øí·­µÖb@§XË•£LfW ^®LªµÑષºq|ÀPZû²(iQøÍÛìeÜ ZÑïRƒrŽÊM¡ß­*I ׈]Bü¸]„XÉ Lüྨ`…>££ ›Vj‡Øm¾µÚ"ˆ!‰”é&†"éŽ`0-ÃXml†-þôZ"ˆA&®«Š k¬ÑɃ„x'—þZ•îz\ÿø@ÙÜ &w]³ØÍÚœ‚i-½„pñ§\¦x’Ç„Îd¤Â4E>¹ Ej§W­¨3$ÌÆ„Tý…Z:8Æñ”fø,AˆËò¦øRÆËÈß%}v1N&q êB©È÷ÂD&û(ˆá †¦cXpŠÉPŽåM­É–sË¢#]ådÚ‚Ë;ÅiyS¶e½‰’íj¦6®Šb1Ó¨¦K Œ(î<‹i¼>º}-4Ð#_WÍ?‰Û¹i2Ò®’þ k›áô9â2ƒ0†8¨ÐkêÙz”÷É¥õW믢Nq.Ábf;\£íxA¢O¾DàWQÙyqœæJv›eR6ÎËhq[k˜Õâ@+¹ö£8)ïþVÅ¿²|E LO¤ÄÎN§ßH‰…Ê{duAH¼¿êž„åp!5¹f²&@ýÕAOÛžŠI$·ž¨Æ!¿÷Äa ƒ«ƒ8wm¥>Ç™ †P•Œ1ª‘_5ãÖé¼»šß|ˆ+HÞZG_¼ín#»O*<.7G)|ÛÉß>gpËjíÐZXe¡üÌ¥Îo±‘xŽ C8÷ì·‹}‚÷ /šŸitc&ôë®#Üo¿Éâ?ó3­M$¡ËæyVÂÛ2–õŸb0?Ó)³›dÔ|~‘Ô ñc,Ô"u¡Õ$ëš6:N7#ça´’Ñpñ¨çæˆÍ”­I·Ir¿ûQ½ZßÞ&ïa:z=ºšÁõxl¼¸œ<ŸÞ½™Ÿf7 דñõ Þý2šŒ®‹Ô=O^Ž&ðU(™týE€M!‚౞v쎲‚<ö¿ ãgðìê5"Ä«úÖ¹e3§¡5u+NßOÏÕõúîæJýt0ýþ¦³ÉÛñt~z’®9y~¢¾õˆ-ÒÐ]-ë«6WýãÛŸ“¿åOý•„Ñz»¿§~£ME“ƒ’ÅYö& äWT,Ž{ë+ãüܙ÷xì3ÈqÓ™xB6mLsºü (÷ûV endstream endobj 598 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 599 0 R >> endobj 600 0 obj 1409 endobj 602 0 obj << /Type /Action /S /GoTo /D [592 0 R /XYZ 72.0 720.0 null] >> endobj 603 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 203.252 138.0 211.652 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 605 0 obj << /Type /Action /S /GoTo /D [595 0 R /XYZ 72.0 720.0 null] >> endobj 606 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 191.252 204.0 199.652 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 607 0 obj << /Type /Action /S /GoTo /D [598 0 R /XYZ 72.0 720.0 null] >> endobj 608 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 179.252 198.0 187.652 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 609 0 obj << /Length 610 0 R /Filter /FlateDecode >> stream xœÅWÝoÛ6÷_Á·6ÀÂñK¤8`²ÎºíÛCÓŦa²¤X2ÿ÷;Š”dY´÷!³ H<òî~÷M?N("ð½´¥Z¬'žF‘bˆKOŠ$¢³­‘PfOí½°ö î¼< &ù„ ß'_¾Âæ`ø6!‡âæÙäóž~»C^]ÿ>NÙÿ‚Àbh¢ÒÄ…ÁOá&8ƒHáÎ^à:zOmrGŠÓm·2ïiÿt@Ü«³Ç=ÚAz3HØÞÂ×SNÐýä×ùäÇ÷¢ÍW}ž+3m? Í×èË[E/¾¢ù“é|ýWvÙ(ŠVwg @‡¨Æ„:°©‰¬ò69“>&k㌠ø@ĈiLddÏÇŽaöùúòÓ_Ó›«ù§ä8»ó”E€{Är˘:<Ƀ'Ñ©·›¼BõƒAÕn}WdhUlÜr[–Yj– ¢4›¤.6¸Å®ØÅD.ô÷Û|Q§EÞòw“Ô8¢±ÖŠz7Ívy<µŒ: ŒŽá<“ÊÓ| Eàdõ˜]¶:ÊVÄXt‹p@¡’†Ò°FÒHÏÏ¿ ©¶Yý¼Ï(‡¤åœ¡¼¿¯6÷ÛµÉë %ùýd[Sn}1¬£dÇ<Œ{”¢”ÈÛU›> endobj 610 0 obj 1121 endobj 482 0 obj << /Type /Action /S /GoTo /D [611 0 R /XYZ 72.0 720.0 null] >> endobj 612 0 obj << /Type /Annot /Subtype /Link /Rect [ 138.0 597.441 312.0 605.841 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 614 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 529.545 268.87 538.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 615 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.586 529.545 541.586 538.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 616 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 517.545 271.65 526.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 617 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.57 517.545 541.57 526.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 618 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 505.545 318.86 514.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 619 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.261 505.545 541.261 514.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 620 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 493.545 321.64 502.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 621 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.244 493.545 541.244 502.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 622 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 481.545 308.32 490.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 623 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.331 481.545 541.331 490.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 624 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 469.545 293.31 478.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 625 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.428 469.545 541.428 478.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 626 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 457.545 138.89 466.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 627 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.433 457.545 542.433 466.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 628 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 445.545 202.78 454.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 629 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.018 445.545 542.018 454.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 630 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 433.545 198.88 442.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 631 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.043 433.545 542.043 442.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 632 0 obj << /Type /Action /S /GoTo /D [601 0 R /XYZ 72.0 720.0 null] >> endobj 633 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 421.545 195.0 430.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 634 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.068 421.545 542.068 430.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 635 0 obj << /Length 636 0 R /Filter /FlateDecode >> stream xœÅÝMs7‡ñ»>Å“ƒݺ÷æ$ÊV¶\qb©j“Jå ÛtÌ]YrDz“|ûE“’I‰ã-?—lœ*‘£?†3óãZÌo'yJãßiüè^¦—oO~»[–§^&iw‹j›².JÞNw·ët©ƒåþÖø± o¦ž\Ÿ¤éï'?ÿ2~ùjJ£Áï'éñê¶ÏO~8xüøMúËÿp $—ÿËÄ6lU¶.eüß[œ¿¨šþæîÃòýÒíÊnÙX²{ìøÕÕÝ‘¾û¹ÛÝÍÝþì~~t?Ò~7Òüq¼ÛÿîÁÓôëÉ—'_|S§œ¦‹×ûçy—±daÅã¿2]¼~þ¬Êç¿Lÿ89»8Òÿ‹Ù‘b<ö‡‘©è¶Ûþ`Ÿr’…娡æSÉ‹b=¥ÔÚnï.Þ,§ó?ß¾¸¹Z½œÎx:î\o.ÿØíòß´ÇGHmü¿Èfc}Ùvëøêéhxßâø˜Ú"åñˆe<ßšNŸO§½.túìÝíÍV¯–ëý’ËýÍõý,‰Í<_]Ýü¾ºþu¿d3öì×7×ëÍíû—›ÕÍõ~éÍëýíØ÷w–¼»]®×#|¸=·¯VëÍÁÝWË«ÕÛÕfùj¿èÅŸ»#rxäZz´ûëßÞ_Þn73`F£ÛË—ÿ^nÖ‹ý¢‹7¿ßïõîþj½¿½y{½Û€Ýý›×¯Vüçþö«åëË÷W›q¸¢õòÃaºo°~y»z±<ȼ߬®V›Õá¢×7·û;ËëËWw»%—×Ûöjµ>=><½ŒÃãã™Ïà8]Ü?S{¼>SÇkÂû¢Ö:„úýëcõîoÓ¿Þ¯7Óï—×›iµ™n®ïWàŸêc¹¤…‡±iÞ­áõêjyº=ËÓõoW§»M?]?x½jÊxû>^×t¹ÙÍÍ»i?{òõÙóÓ󟾻xòã#âìmamû°ef-Û׎ÇkçQ»’Æë¦éØm3íGqañÆâŽâ¹°xeqCññêCqeñŽâÂT…© S¦ªLU™ª2ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;S5¦jLÕ˜ª3UgªÎT©JBª’ª$¤*©JFª’‘ª¤*©JAªR˜ª0UaªÂT•©*SU¦Z™jeª•©V¦Ú˜jcª©v¦Ú™jgªÆT©S5¦êLÕ™ª#UMHURÕ„T5#UÍHU3RÕŒTµ U-HU S¦*LU˜ª2UeªÊT•©V¦:>Šg÷’téu|.T«îVu¦]ÕãêPT¦¾þöüë¾hêîâ3kÙn£-êLÙ¡,\F»^ÛL»ãÂ@eqCññÅÅ•Å;ŠGaŠÄ…Å‹;Š S¦*LU™ª2Ueª•©V¦Z™jeª©6¦Ú˜jgª©v¦jLÕ˜ª1UcªÎT©:R•„T%!UIHU2R•ŒT%#UÉHU R•‚T¥0UaªÂT…©*SU¦ªLU™jeª•©V¦Ú˜jcª©v¦Ú™jgª©S5¦jLÕ™ª3UGª£‹ÄâHURÕ„T5#UÍHU3RÕ‚Tµ U-LU˜ª0UaªÂT•©*SU¦Z™jÔî ¾­#Äx¦.e¦]m3u„ñä˜zúì«'OŸþtú‰ÃŠÆ0†ƒ¨òÌÚb[㯚Çõ„ø@õ4‰Ìµ;î¯,n(¨$®,ÞQ<>PI\X¼±8S5¦jLÕ˜ª3UgªŽT%!UIHUR•„T%#UÉHU2R•‚T¥ U)LU˜ª0UaªÂT•©*SU¦Z™jeª•©6¦Ú˜jcª©v¦Ú™jgªÆT©Su¦êLÕ™ª#UMHURÕ„T5#UÍHU3RÕ‚Tµ U-HU S¦*LU˜ª2UeªÊT+Sa;ãVR›ë}´Ïý«Ò’[™iWûLÿj|Ÿ˜ï_}êßk££ÔÄïþ`{´ºíÆ–8`¦ÇÔc\»hži7×cBqCñÑcBqeñŽâ£Ç„âÂâÅÅ©S5¦êLÕ™ª#Õè1¡8RŠ#Õè1¡8R‰¤=&gªÂT…© S¦ªLU™ª2ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;S5¦jLÕ˜ª3UgªÎT©F Å‘jô˜H<#Õè1¡8RŠ#Õè1¡8S¦*LU˜ª2UeªÊT+SS))y™ëÓ|´²í1©¸YÒ™vÕgzLÒ¥žŸ_<{>ÓS:=¿xrqöøkãh/åþ`G+Ûnj[´ãþÒøpׄ;¶w¦ÝÑ·ÓñáŽâ•Å ÅLJ;Š+‹wî(.,ÞXœ©v¦Ú™jgªÆT©Su¦êLÕ™ª#Õ8éÅ‘jœôHâ©ÆI(ŽTã¤GGªqÒ#Š3UaªÂT…©*SU¦ªLµ2ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT©S5¦jLÕ™ª3UGªqÒ#Š#Õ8é‘Ä3R“Q©ÆI$^jœôˆâLU˜ª0UaªÊT•©*SU¦Z™êöø‘ˆ“A+º†"iô@[i×òL×PŸùÍ·OÏ>y¤bÉ‹x¼Ý Ì£UmGUæ¹ —F·µM©¤¹M8únZ:ŠKbqañÆâŽâ£Œâ•Å ÅGÅ™j ÕñAÓ¬|J¼%o,î(Þ ‹W7·ÌâÊâLÕ™ª3UgªŽT£ŒâH5úÀ$ž‘jôQ©FÅ‘jôQœ© S¦*LU™ª2Ueª•©V¦Z™jeª©6¦Ú˜jgª©v¦jLÕ˜ª1UcªÎT©:R>0Š#Õè“xFªÑFq¤}`/H5úÀ(ÎT…© S¦ªLU™ª2Ueª•©Æ {yĽ ®eô5f%ö$3íšÌôÛãÓú>L7þ!6ºÛ‰µ·#Fò±59ÆxmNO‹–úèÅ^µ{¼Ó]Pº¡´“´”®(m$í¥¥;Iç„0c^|Gœ9!ÏœhÎH4gD/G¨¹0U Õæ®M>).,ÞXÜQ\ ‹W7¯™Å•Å;Š7¦Ú˜jcª©v¦Ú™jgªÆT©Su¦êLÕ™ª#Õ˜íÅ‘jÌöGâ©Æl(ŽTc¶?Gª1ÛŠ3UaªÂT…©*SU¦ªLµ2ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT©S5¦jLÕ™ª3UGª1ÛŠ#Õ˜íÄ3RÙþP©Æl$^jÌö‡âLU˜ª0UaªÊT•©*SU¦Z™jeª•©6¦Ú˜jcª©v¦Ú™jgªÆT©Su¦êLÕ‘ª&¤ª ©jBªšªf¤ª©jFªZª¤ª…©²Ú’²Ú’²Ú’²Ú’²Ú’²Ú’²Ú’²ÚRüñ ç6Zfâ/×ëÈ…”Åç¶ú8oÛ±=S1jîìÇŸûì»™rcïîn}®ívÓb¢²£M˧zùîÂ Ç +‰Å5±¸°xcqGñZX¼²¸¡xË,ÎTSíLµ3ÕÎT;S5¦jLÕ˜ª3UgªŽTwÓ‚8RË•¢8RÝMñâH5.WJâ©îN¶q¦*LU˜ª0UaªÊT•©*S­Lµ2ÕÊTSmLµ1ÕÆT;SíLµ3UcªÆT©:Su¦êLÕ‘jŒZFq¤£–I<#ÕµŒâH5F-£8RQË(ÎT…© S¦ªLU™ª2ÕÊT+S­Lµ2ÕÆTSmLµ3ÕÎT;S5¦jLÕ˜ª1UgªÎT©Æ¨eGª1j™Ä3RQË(ŽTcÔ2‰¤£–Qœ© Seµ%eµ%eµ%eµ%eµ%eµ%eµ¥(<Ö4âã«6ªîEá1eK©JŸiØææÁµÇs?EáñÙ÷gÏŸ\ÌÔÇ׋ºc/u¦énËææ›Š‚åx“ðí4UGíŽËŽ‚Ò ¥¤c6)®(m$SI´¢t'é†,²lȲ!ËŽ,;²ìÈÒ¥!KC–Ž,Y:²tbã IšXÆ(HÎÄ2Æ@’4±Œ$M,cü#I#KA–‚,Y*²Td©È²"ËŠ,cž¨TR²Ô>)î(óD‘xeqCñ8»‹Ä•Å;ŠÇ> endobj 636 0 obj 3673 endobj 638 0 obj << /Length 639 0 R /Filter /FlateDecode >> stream xœÅXßoÛ6~÷_qèÃÖ±F‘Ô¯à´é­-–Ö]QÄ~`l:Ö&KŽ$¯ÉþúEÊ–%Jn_:·€HŠwßÝwÇ;*#þ«GQXlFfÍ…€óÍ’çƒËêÁÌØƒDíj h=‡ބƒ5|¥#¿Žnçør ¾ŒH[]%üatÓÀWoÈwÇoZÀ\ú¿X l¨¢RÅ…âÿÀ©‚sôÂãäøM#pûõÃjÈô®hlõ*1L›§6Dµ?úÙë9¸Aì<¿8ûÑåtôÓk\ÓÕ!φ+NH#õ£0ÝÀíó€ŸÍaúÛèjÚ‰þw¦¬E…½wMǨ†„÷ȧ*²ñI»ôNl¤vÊÂFñ=µ?Ô/ß_M¦WãéäòÍhÉý~—r'âK9ïJÎ( ÚlH^æR”,E)îD!‰tjƒ‹ÁÜuHDP‰¯•¼Þ¥‹2ÎÒZ¦Ÿ?r<7Œ¢À5Ü|xJKñX F0—xŽÇ#B˜Aƒê×ò2ä݋ʵqåO›u:Šk3Ј–®O»ûÓF\;–»á7"D„¥,y¼mrÛ¢ž£þ–Oh4²ðUg@/ãP˜-|‹,-Ê\ÄiYô‡Ýµ˜7Ä)éîG´Ub Ùh‡ŸÓ¹ì2æø!&³WËMòûÝF¢c Ò%ü)’,ŒFr¼ ¥"ª.#‘éZ‚ƒlåÚœ_h ÑqzÅÓæ.K ËáÃÍÛ\òâ [D'>!^Ø“!v ;b“CqÉîþ’‹¾¬ãÅ–r%v ÒUfðÂLÆõÖÃÆQâ:.e·÷¬XÍëN ‰‹ò¥NÈTÅc¼7ípÉÉ>,¢BVqÓ+…ŠPÿAç6mï®ßôâ«ÒЕ8á)Ç;”⇼ÿÙ]íˆNà2Ë)RT–šÃ?êd@\ øêEN Î¥®Eï´ßeßtNkP' ~F§…^}EfUmÜo êÞŠnb7€çÂ<õùÔã…H¹4“æÀ<‡¨+EØp†‹R9 {nÀõ‰Ôãx2£;Ù2¾N]3ÓuEOTîVUcº®ÆK¬Œñ*–y-§'gs¨Ê^B™Åø“õˆãUe@¾é{놀e$lãÕë ÆÔw”‡Ùal)a‡—Á ˜<ŠXd…<|èဆƒ qÃpqVEh?û²Î y˜ÊDê–vÌå±lãVÅk"¦Hƒ¢uc¿(1îveûB¦è¦Ä’×Å9”O[õP=5Ce94j/;L[lviVŽÓ]R5¹moDþ4Vw Î¥À=‹,ÙmRÀ¤Û7ÉáJˆ·‡s}sþ†šW—®¤*vu;†\ªþ«NNDZõd}R&­> endobj 639 0 obj 1464 endobj 641 0 obj << /Type /Action /S /GoTo /D [637 0 R /XYZ 72.0 720.0 null] >> endobj 642 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 192.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 644 0 obj << /Length 645 0 R /Filter /FlateDecode >> stream xœÅÉnÛFô®¯x§6ªéìChqŠiÚÔB{°} ¥‘¥V"’jì¿ï)ÒäˆRzH-³¾}~š0 ø›ºÁÄæÛɧzá t½¥40I¸‚-Ôsw«3áÍ  '+øs’N(ü4¹¹ÃÃPø<¡}tðõäc‡¾;¡_~—ÁøÿÂ㡲JeŽÿ†TÆyv $}~Ò1Üa¿Ý­ ¿‡;ž¶;ÚÔš®GψŸzyüxTÚŠAÃz¬%üzÄ)—ë,m`ŽëEÇD±(Ž «õrý”–Écˆ1ª “ˆŒëÚ= úë ÉÀÍŠ6­äé«D†®CÃrÑc„)H;VðÎLÆ7Û§Bœ…­—ÓEf‹iš•Sû¸.Ê£T« ùÉ é¸ñ†ãt´ÑùáG8íLHE:Ž…dî2ØomZ¤ ø#Ùìmqœeç*&2B?æR m1ˆ0¦id¶²àÀ [B¹ª=dŠ2_§ßAñ´½Ï6åpýñ=ØÇ]n‹]Œs1Q 9«°>ÃÀ.Û°Ìîÿ²ó>¯Öó,ì2ÙoP]e/ëÅ´¹úrœ9N%aÌ`ôòSÞärY«‰À/6IQoËýþ©ŒInáÕú!ÍpD-¾²yŽÃí §ïšñÛ rÚg¸à=Ÿyc‹y¾ÞuO0³*Ó3»Kx\à9uE¹b¥³ªœ ]Ï“ÍÆ.:#IBr &FMãݪÇ`;ô—y¶=U¦4†gÄ(Oº$—t ¾ÃƒwÊv}pÏŽZ³Î"à²Ów˳ãܶ—ÚÉõ 9d¥‡¢ÄÀ‹ÊÇ;k—sÚÕˆBÑóµ” .DÎ#މS ì”fDfÖEgÑÄQ»ƒÚI¬²57.zŽì×ÉËBŒbè0‘ÛrŸ§Å9l mˆÖÆu~&€ôû÷Çù‰Ôh‡úç•ÍmR<³wת„ÔÕxÀ¡01?Ç_ )|bX/GŠk¬?t^$_wc3†ÐM|f=#“ æZ\E©Œêðê1Ùî6mÅ µaBj´¿tµ¾nÝn}4z΋én–Yvw{1TŸPQÛ„Yàž¡­kzüXLúZkêKtć¤×bùŸ¥“´¯$® lT«þ¹¯îÍ1ÛI‰Ãy)ìw}½^X¸Z.±7(ÆÊ Ä À9‹#é¦j{µ¢ï8%ï\‘;žú¸$´z5HÀuº½A 0J1{ ÁÏðZôW»G‡MÏX \ß? ®¸"*vºn¨ «Ïä><šÈÄMÐÌmÕ|$øX\—ûÄÍGM LDb…ØMÔˆà:C' ùU•öý´Í4‡Ãåa:Ö‹PT8¦  {¢‘Ç!CúâêçIËwÝAÖ¾“n–a]g}PCÛaöŽj)kQ>ílKêÓæ`[œL‡ˆ–ì V&S;3¹3i¬ðÍ5ÄxêA2 .åߖà\Õ 2bifMp q_e„p–ÇWB…˜ZUO£ª±wO¦³+Žf11˜ë¢ØÔïškkárSd‡ï<íg´ŽЏ ó­ÿÎ2¨G""ž}2šc‰/m·‡©>¹ß¿s¦× endstream endobj 643 0 obj [ 642 0 R ] endobj 640 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 643 0 R /Contents 644 0 R >> endobj 645 0 obj 1361 endobj 647 0 obj << /Length 648 0 R /Filter /FlateDecode >> stream xœÅXÝoÛ6÷_qÈÃÐÆI” l@Š¥C‡ @c{hŠ‚±hY-¹’¼4ÿýŽ"i)­$/m@Çã}üîŽ'[P ø=ב2XíßìÁ€Çv*І‹`–Ž`«w æ(|˜MHlàïE¹ ðûâÓg\Ì€ ÃÝ‚Œë˜¯òõ ùáò‡pÊþ ´*. "èÀy°…äáʸã|?Û äfgŒl½´µž¶O£ˆ!=æyÒÒ›Aü~´þ8áòÅÛåâçwPËuç‚ãL°T,wðé…H^~†å‹Ëåýì² ŠZöÑTQM!ôM²ÂÚdLú wÊåñA˜KGzb®Þ_/Ï—o¯.¯Á0·SÊÁ´TƦŒ7Œ‰1›c€?U{¨Ë$l‹¦…j ™lå­làc«šÀi.<š‡4 )ÁãbsÜ»C¹j‹ªt<§§AD“4Ô:éú¾låwǘz„QAíca•ï>#{“pºQ›vnÌ{'"žsúG݃S…’±.4‰§LÕ]©ê“ê3êa™Á¬É~‡Ìi)ÂgÍ/¿B­šÃ¶}Ê£ &»q ÷Evªl1BÊ þ’Ûƒó¡OmRŒy¥CLD±Ç3“øG}=<дuQæ¯á¤±4ä˜ÀSÖï¯N ‹©—ªÞÈí6˜7-áãÇ èh}Ÿ@»Q%t„ñÎ@»Çë*§< Ø$% ͹—ßån¿ío`_›„…8 Ø$"ŠlW8l€àMgœ­k•ݼœ¢Îc6:;ˆ›gíý^}é93¸-ò¢lq¤P«ê^é…UµÛËò)™eµ^“_¾VE‰n÷ Lâ§h¬êeO¯¾ûüKÖßC('òº:ì ¹¯«•¡juW­2m˜¡d‹iq{À…©Ìެ[Q͵Úʦ1åFáÁÇQ¦¾²Ú«Z¶UíF¹óIccDœ4¹«öޱ7h+Ëü såFu®LŸa·æy­ré7Œ‡'D¡3ò\Y».Ýh%{twÃîåÊŠn62«î|bÂ1äGÿUå¿X]ˆej¯Ê¬G+þ™ÛˆuKšÔí¥è“#¤“öÜ€Öµ²EÓ‹•‹o0á ÇÓ L|(<^("J±Í°W§y›*2—ë5bÞÌu`G°œÚó¡*ÕjSG¸£²®§í„u¥V 6, Mœ‘Ó®æ o4 ¸ øö'®2®T—ç_ß‹ö 5=kz†×§60½û÷áãâ?Gÿ endstream endobj 646 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 647 0 R >> endobj 648 0 obj 1332 endobj 650 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.114 192.0 106.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 652 0 obj << /Type /Action /S /GoTo /D [640 0 R /XYZ 72.0 720.0 null] >> endobj 653 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.114 180.0 94.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 654 0 obj << /Type /Action /S /GoTo /D [646 0 R /XYZ 72.0 720.0 null] >> endobj 655 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.114 186.0 82.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 656 0 obj << /Length 657 0 R /Filter /FlateDecode >> stream xœÅXYoã6~÷¯àS±Y¬Yâµ@ 8h¶H,º°Ñ.̓lÓ±[YÊZ2ÿû%ê°EË›—4  áñqNÎ ó}Dß±û(ÃÐb;úîç(R qé§„D4ÂL -ò´@‰ÛÕ!XMÁ§ÚÄý=JGý>º€Å%"x‘ÓãJðtô¥Ãß­7çß•€Sö¿Hàd(½Rú…ÁŸÂ¥sŽDDŽW:ŽkæÛÙ’!¯æ`¦âí–oiÿ­©ÈJŸê{VÒªAÂvô¾s‚G׳ÑÏŸ¢ÍVmœ+3X3ã~šmÑý;M®ÐìÑͬçý76YÏ‹Žw£ ˆ^Õ„z¤SéYåuªTúom¥TÀ‘FÌ`"…Û¯+Àlr}w3¾ùz;MÇ¢ Û (ÓXsÇXó>öcêÀ‡hfó"G«l‡ŠµEöe“6]X”­PŒ–qÏãÜ"ø$×j¨€ÅÄ8XVÚ§‹b“¥5æ¼Å¤Á‚jcõ›Ò"~©&ÀŒ‰Yܧ^òçDuv–ªŒKEóñÓ©±dððZäDªB<ÒŽÏ{òSäñÓ¿ö0Àˆñ£ì9µ»³œ˜ a†˜(ÔQp–§A~ùíl¾OŠË1@¹ÀDÁµÑDTèÉîq¿µ)Äfœ.Ñ_q²·ùyÁ]Lƒ•Œ ¹é{¡wó@ÞdwÀÁ\ø»ûP ŠA”»Múøå‡íXCG@¸ñ7á7›/v›§n: V E)F7µ£JÎWÈ`ŠÞ¹íIšžl3¶Ÿ€ÈõTœÖ”‹ÔZF´,À¹vY†’•@Yªh@ÌÁ‹V™ã,¶f¾I@ ©q$ |q)G] ;Nå¾ Š:?h‚¯¶_VS¯EÃN§‚sWÏÁ^yCžÍ– Ü0EªÔ`F€l>mXÏ é­ÑŒk+V£-ÜVâb·³4iO)óÝè,´ qÛçv×n‹w¶¡íK¼Ý 73·«ž©úâFa¥4¡‚†4vUÄÁ!§Å U¥ô“Fâ…»yà6Í Ø Ð1D¯¬Nñ¤³H;rWòC;ô6ö£ÆÈõª·²Î;[‡rÑRÐðA_Ù—uØ`L‚; –žõƒ®kýTéÛ‹²rh/Œ PÚ´xµ¬,†À-ÿMǤ®lv ¾¶iG§£¥_€ÂP€Äu̵1ÅåzÄ##¢ìëì `Ÿ’¶ uØÜ5îÕéúiqÒ9£ûU–=|» Hk¢,t‚³þ¾’Ìñ¾n?¤RÄ#l$h!ýÃqºYZt³ZA×ÕX0"–šZ÷EYjÀˆ "¼R tPæ‹ú¤d÷f~b((ÇŒÀ‘J{`¿n\f/"ý1,(Îj'.lÙQÄðbÝûØÑƒª )¡Ûe„qÃ_¥»0Kèíá yk[‹&Iž5õö­ Œ$¥ØèòÿUåc¹_iÌÞý‹ ;.#,øw,ã¯=v¹Ëž.ê2ÃëM þ«CóΩî÷?¡Yj endstream endobj 651 0 obj [ 650 0 R 653 0 R 655 0 R ] endobj 649 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 651 0 R /Contents 656 0 R >> endobj 657 0 obj 1278 endobj 659 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 475.156 180.0 483.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 661 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 463.156 186.0 471.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 662 0 obj << /Type /Action /S /GoTo /D [649 0 R /XYZ 72.0 720.0 null] >> endobj 663 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 451.156 204.0 459.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 664 0 obj << /Length 665 0 R /Filter /FlateDecode >> stream xœÅVKoÜ6¾ëWÌ1 *†Q ° 6§€k=9È»\[ˆVZK2ìý÷Šz­õ¨sqe¢HÎ7óÍ ?îƒÇ€âŸo_Jsؽ‡vŽâ ÂvJ†ÀÂ%¡KÈì®Ñ€w#|¹M8¸‡¼Ü£ð§÷ý.î¢Á“G_Â5Æ7ÞõÈ¿]¡oîŸÂ÷)ö>|‘À(ć!E%Ji­#AD×öááû»Ïo7ñÖ7Ÿ®¶¿ý€ø«·/ÈÆÿ2×M MôM‰9þ+ÒÔùbAôreÔýü0Û8ngœo»”µEkß.7t|Ü{‘hÐ1‹Ë¦xSçËý Î袔\¬þ§lREë»'£'ÍÝô´´TÂÐqùã#ÄŽÍx§D„Ÿ¹mÐE[¢" Z:Ûto`{8˜]]uæÓCaž Ñ%‹´3Ü@ÜfÒ v¥Ij³‡4ï#@€LPØ“+±d´}‚hIeC`*Z1'ÿÍœQF$hÅ: kŒûö¼ÆœqI"ʱËÙû½9$YíwQ¿…{iARD‘CÙ>ïÌ©N‹<ÁnIëÇÄŽWk`s &!-Æ3 k ïLYeÿ…Ué†Uz‡.2äÙ/úáJ½Pi™¥-güæÉq¥Ta°l9a^Ôý8â®Ë4¿û}ø>o‹¬ÿ‘½¹¾Òð|*MUa*I?·˜¥bHD}>™ÁÕCÖ×þô2M_«ß#±!å˜êJ“5Å…][‡Å¤s*°}d g|¬¦Û+bÙ’ éþ æ9­êê'†c2´¦xbD«27ÆÀ&«Š^^u³¢$¢ƒÀJܼ¼Ñɽ/‹“ßèȬb[Ð üUÐ ù9ÐjUF¿ŠÚú.yþiܬdQK¢x¨#­Zùø«¨Íê9(ï”Y‘VÊ™Ä÷¶9}!ÖÏl)Œ3 ;”—ºLÒ|Eé™àj-61‘äû×DÄ$'Òb(:Ç ÃÉ«d·®|œkC?Íù©(Gq%åÝãÑ ßaª.¦aOªop…wSsyl®»qÛÎ-4_‡8SÙpÒø‡…Üç)Üç+”À厲J®ðÒ˜\Å<×&Ÿ;Mqicõµ"дåbí5#!k¤L!^UzŠ5 è*ÞÚŠï5xWO(¹·i–ÖgxJë{øv¶×D§êþ5'øÚûíŒþ endstream endobj 660 0 obj [ 659 0 R 661 0 R 663 0 R ] endobj 658 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 660 0 R /Contents 664 0 R >> endobj 665 0 obj 932 endobj 667 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 186.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 669 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 204.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 670 0 obj << /Length 671 0 R /Filter /FlateDecode >> stream xœÅTMOÃ0 ½çWø‡'iÒôÈø’ÐŒUâ€8 V`bka-þ=nÓuíºNâ2ºJ±ìø=ÛÏÝ€ôóŠ#%<-ØGåHP¦riÂçRÃ*[ü¸Õ0äÊ¢Ã]"ãîXÂ.Øý§€”ðÅp®L³Qƒ¿ˆàÞù^Ø bGçBô¼‘o¸µ!=*Ë•,LšY´€ûƒÓÛë/: Ï ºdgQ«%ä?´2*k(k/–ô¼T¹Ð>¶# ¨ýkoI¨œ<Ž»Í+ɪÓâL×;{ûÀuØì¢½{%ï߆@‘‡ÛÖA¯ú{YGŶ„¾uëX·n¶‡ŸÏ²ÜË'ó8ÛÚ%a ùWÐÏ‹¿ ;óÞ¸5™6Ð"¢ØÀò-¬¢@¨ØUš¯jÛöùZÒŒ£1„dC—½Æ°J ëÆpÔ„¯PwSgÏÞ43/IsW/±0v¼Å?_ér “åËç"NrÈÓº¦Î¥¶\BFù]¬é2}wõ£Ä.˜e0©ÙM'Y‘…RŠnòÉp<ö›"—ˆ…o¶Çßyœd³4á%±_ÄFeB endstream endobj 668 0 obj [ 667 0 R 669 0 R ] endobj 666 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 668 0 R /Contents 670 0 R >> endobj 671 0 obj 449 endobj 673 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 192.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 675 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 180.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 676 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 204.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 677 0 obj << /Length 678 0 R /Filter /FlateDecode >> stream xœÅTKoƒ0 ¾çWø¸Èœ@špl¥nÚTMª@Ú¡ê¡k³‡}´ýü™„ècS/ Ù²ãÏþl“ €ô•б„yÎ6µM€–öj“ꈸTC­+ȪS-Eî4þ)ð– áM¦ä\RÀÃC8œ°q+åÁ«çGxgƒ”ÝÝ+é[Ó¢¨Ç‰é c0<”•J=Ks˜ÜŒ“4HûƒÑ0¹BúĆi‡K(ä?p»\ñnÂ’>Íݘ;a×ÓZ½½±º„¡·‘Åç®\Y=³ZúB¼êùxy–64°Í¢»WM~~tHn:k ã³Ó¿rËŽ¦XåÞ“¡ÒiªE‡“›¬®9yJ‰µÐÏŠÕžXƒ‘kI8Üø°Ixô§Ì·vVÚ œ½föd³5’—¢.¶«õï˜*ºÓÁöû³(‹`ÝÂý£…±àJÐE¡EÝÂçUi êZ1 „â%AÅj²´¼•rÌ~£—,* endstream endobj 674 0 obj [ 673 0 R 675 0 R 676 0 R ] endobj 672 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 674 0 R /Contents 677 0 R >> endobj 678 0 obj 372 endobj 680 0 obj << /Length 681 0 R /Filter /FlateDecode >> stream xœÅRMOÃ0 ½ûWø‡'éGrdRA „¨ ¤i'pX‡&øû8´ °ki*ÙzŽc??@"ñ)¼i¬ÂÇ “Ø(Ôu‚ªe)T…&¿Â¿5sÔ·Ç&^bçïa„—°Þpð ‰>~>’{èfõ}„¯Oø+gJB÷qç«›¶h®z×w§t×кŒŽ–êèt¡‡ÐYñ߈ t¨JÊ#³-ñ uĉµ}h—dK66ÝÈ'Ú£> endobj 681 0 obj 292 endobj 683 0 obj << /Length 684 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯ ò0$EÍò"ŠRKº´èeź-ŠØ›¶5Ë’#ÉM½_¿C]m‹’“—Î- #Šç;÷ÃÃÜ("ðohÒghºÜ—kI†¸[. Q3Ö¨¤ Í®=‚U<ŠM@,Ñ×A4 èíàvgˆÃÀÃåÌ7ƒÏ{òÍòÓåïkÀ)û_40:äQÉãÂà¿Äyp>‡~Ù \½Þ¬æy±+…ló),=]> E ²°§xvÚA3ˆÝ¥…?O8A‹ÁÕhðâ@” Ñ¼ÉsÉa{Ì7?†Fkt{ ½\ZÑÿÉ.kEÑÈ®Õ!ª!„Ø”GV–6&}Rk]eñã!æcâ ³ß+^ÿu}9º~ywýŒõvJ=ìQ³×õÛŒcÆä1jJÎÚ èu¢U¦‘B3•©;•jô=иRWZÔu(&>1o¶Ñ4 â¨âéöŒëcA=ß—´ôÌÍ.ÊÔŠÑ·£ÄÁžtAá’å¿##=§½qš[64æ»D n¥%Çjäs¼?Ú jKqêÙ$ü²Ò»1ŒZĨ´Sc6÷ôàs›—âp»Ž†af‚8yš¿8±òdËát©§«a¼ÙO—vÔÉÓìr¨Å®*»¥¸Ì"åÕ¯ètSÎ0w|`eÓºLÛµŽ²©h†¾¨p«Ó…Á>!°+Á±í|j5 ê Ëh©‘aCñeË¢r‘Pš%A´xŽÒÝú.Qœ ›Ï‘þ±Itš‚ïq¿rÒÅR˜0ÎìÞ´+Øb»lºJ|÷žfèaL—h¦çj‚·²=+_†ÕÖg'”ó%–.¸8­±«Õb¸,ýLs·Üou²{´s˜iÀDBθng Yis^"ÃtB÷±'à8q=~¢’ìR[ü—è*ŽC­C»S¹sA å´<1~×é4 úåæglõ|O”¶MŠ.K°ÎUMåi[½LUêYýÚÓ”9ÇœBX¹pÚÒú«IÈÖZv=F ‚*EædÉ@»·sÖR‹b©Þꢩ x*ÒRDõ7Ó%¬®¨â¬lܾM¡}šTNØ¡ªYŽ=”»è¼¨£úµÛgž¡ûÂà8mȾj&´‡±‘lzpýr bQªi³Ó¾³ôTù¶V{†ÝímK7z̽'0÷]jÏ™É%v|Ç÷ º-ÛÓbÂ{6*âÈt‚›5È‘Þ&Äa¦=€{B‚a«Å’e™ƒÙ=LANJS«+ÛHŸÞ}ì-½nÆZîÝ®&Ë*j>m:˜7d³ºTª¦¢8vm>ĉJsãy¢=œÒÎZúw3~<¯_!£FÇ0l̈Rd/¶›™¹T«Óx½†J-ÕÏÜC‰q´7v$åù¥IGéV²¥Êò=l1½ ¥* Òù._,FwM0)$´Ïý¶ðž>aj©“ï‡ ˜J ürÒºþ¡Ö›PwÏâÆ=ÐÖ‡©WÇûxÿ‚nCˇ‹$Þn&m÷:ÐÝù‹«ÎKH±ÛT‡f|ºIš Íé6@ÕÐz­‚ІJ¹uÿ÷ržÄk± ãÖ6ˆDååÃRCo_¡[HµÐI0› :™Œ/,”CˆzÖ>Øæ{a|^ÿlR©zàJ«4yl6HÖÙû8Õó3tv“©0ˆ€Hsâ·4†(e8Ngã ›bžÍøQÇf”ÄYºÚ•Ô!¢Ð?vH ø)X™ É6…šúäª$O rœ„{Z3@ºJô¿Ë(½+É“ ÌÄô…žsúm›€sÍ’xHU’'!9·C~ˆ#H”å¡y ùéh=­è“ÐŽ°Cÿ¬–P$€õ6NîTéÙEEŸÄÒŽ{'A Hß4Lg¹Þ»‚:‰hþbCüªY°€ús[¸bcž‡€ã‹ç–<ž%X€™wŽ¿M·4Ó9*:ïvý|[Ð#nÈ.d Ü}ŸÈò*xÌ4ºžÏ¡»7ÈtsN w»¢º®äí&…jJ5ƒyϽ€`Çœ‘Br Úé›, =üxﯓŸÿÒ¯„¾ endstream endobj 682 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 683 0 R >> endobj 684 0 obj 1588 endobj 686 0 obj << /Type /Action /S /GoTo /D [682 0 R /XYZ 72.0 720.0 null] >> endobj 687 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 186.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 689 0 obj << /Length 690 0 R /Filter /FlateDecode >> stream xœÅX_oÛ6÷§¸§­)fޤH‘*°šºn]Œö¡éƒbÓ±7[r%¹I¾ýŽ¢(9-»{èâ:I¼»ßýáÝQŸ' (þ¦ö¢óíäsóŒâÅÍ#„KØBCKØØU÷^Ü"$Vða’M(ü:ùø _.€"Ãý„öÅÕÌדwúíúÍõ"ˆÿ_X uTê¸püW¤ΓRЧo×>ïžÖ #÷ Ÿ8ÝöÕ¦ñtsu@éìq×£vÐÎ öccá·SNánòËlòã+ ŒÂlÙ幊ð Ñ<±f[øøL‹‹O0ûmr5Dÿ»lE«»5¡cT5¥”=±©Ž¬jlr&½M·ÆðÐÀBci×kÇðò¯?þœ¾}õ[»˜Ñ˜¸…B Ùn8W}6Æ/‹|WB ‹´JoÓÒÀ—µ¹'« `ŒÐ„¢ˆØ‰xµÏæÕ:Ï<Ïq·Ä ‘L'‰b[®³*}ðŒI@™5— Æã&; þë©E`åM›Zsú‰‚r= ÑÃÁDH|vÓtu|÷yQÄiHÑz9]䦜fy55ë²:ª5¢ñ×YVï©¡ãš\8®'¦!=?ý §“€E‚h'I$˜ã»,îö[“U˜†ÙÞ§›½)C¶I!"4¦1Ñ0ƒýÅ,ÚËleÀ²A¾„jåòR»ʪXgw?@ù¸½Í7pýî ˜‡]aÊŒƒÓŒhÊÑðD†Ý8`»ìöd~û·™Wp¿ZÏW°0Ët¿AoU9î0-IlF, ñ+¶„V$Vvr‰CÐZ$ë²%ý~ð÷èˆl€xPp¹ÐØÄ±u&”õ:]iDù˜€Aaª}‘•§E˜3Ê6sSõPàÛ×oŽc‘|ŒµÕ}¿2…I˃ض¤«$÷–èÞzûR+l?Ð#­QÆ$f6Gbd=;G¤ÞÆ3 aÄìx*)º™ß®ÒínÓõËÐ ‰˧°º™»nêM瀗Ó|\æù§›‹¡Ï"ÿ”{ü,°NÑŠ6)xì}ŸùæÔ¬ùPs`Y"þ«m‚öÝ‚0o‚#f=ùö½q¸r,pB`¡à<Ñ'U7ú®®–KìëåX ŠÎNï:ö·v*æõðÎvªã Býð?uz2AŸ»Cö32s•$ö´ "?íÕ6#êÛÇ1»%—X°¬«½¶a_9C½ÄÎfÅh•ø 37õÜâ!o]íSKF@*M‰Ò•ö&ØB„¹ ºBäîêBäȶu/—-9vÔ èpe@Bç !ÄmØÒi‡»~Û{7ûÛcíPܺ¡ŽÛgG½”wލw¦SõyÓÆ‰épb${†UéÔ GÃ:—vá¾Ça2‘xøJ2èE4‰ž|ê™cƒ¯ÌÁèR󱿂áÉi endstream endobj 688 0 obj [ 687 0 R ] endobj 685 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 688 0 R /Contents 689 0 R >> endobj 690 0 obj 1362 endobj 692 0 obj << /Length 693 0 R /Filter /FlateDecode >> stream xœÅXÝOÜ8ß¿bÄà ª’³ø#•î$NGOœªJ=VíC©PØõB®» M²þûÇñ&›8Yxá)ã‰g~óåñ„3 OÍCÆ ›Ù†GA2EÃâh0hhk³«C0GáÃnBâ¾Ì²¿f_¿áË%x˜‘¾ºZørö©ƒoÞWÇïZRö¿X`l¨³Rç…០êäì½àÙÓIÜŽßrkÀÐòc±Í«uéæi ±¤õÇ>Gý ­ÄÇÆÃ×'p;ûc>ûõ=J`¾jë\†È ‹Íƒù¾+qò æÏÎçƒì¿rÈY4Ø;gÐt̪"„Ð=ŸêÌÊÆ'ëÒÇd£­SžD XÁÍ~e>\\ÎO?_œ¹+·ÛM‰ìÎH宓}:%ÿèj[d%$°NË ò,“*¹IJ ?SýPÎné±;¢‰ jVÛûm¶¨ÒeUòèc%> endobj 693 0 obj 1264 endobj 695 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.114 186.0 106.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 697 0 obj << /Type /Action /S /GoTo /D [685 0 R /XYZ 72.0 720.0 null] >> endobj 698 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.114 174.0 94.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 699 0 obj << /Type /Action /S /GoTo /D [691 0 R /XYZ 72.0 720.0 null] >> endobj 700 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.114 180.0 82.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 701 0 obj << /Length 702 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯àÓÐ5Ç‹x°.–Šb…v@šÙ¦m²äZr“üûJÔÅ-7/YÀ‡—ïÜyxèoŠ|¦îK†VÛÉ7?G‘bˆK?%$¢fm‘§JÝ®Á ¾êM@Ü£/“lBГ›[X\#€‡ 9eWç“O=ùn…¼¸ü¾œ²ÿE§C•*. þ®‚s´ "r¼Ò \;ßÍVy=3µl·”zOûïZ‘š¬í©¿ÏÚA:3HØÞ—NÐÝäÝbòó{(A‹M—çŠÃ Ö̸?†[tóJë×·hñçäj1ˆþ »lE'»5T‡¨jB=²©Š¬ò6Õ&}Œ·¶6*àƒH#f0‘Âí×5àóõÕ—éÕß×óÅ|úª¡-€2†q»Iú•1u à  ¨Tt@ [”Úä{TÞ[d“¢´ÙÊ¢|ƒb´ŽËx}OìnŒP#"ЉqjÉšïûC¶*“ÇéÁçw)! V2‚äf…Á±}œsÉïNƒËƒ¨(÷Iv÷OÛež"8-óOà´ìÀÄÒ+§¦Š#Œ D.¬Ý3kµ8Ÿ\‡ª6„~¼þp^˜¤AŒ3ò—8MÇMcî\Wî˜á| Z7„ͺb“/ÿ±«=Ü'«{´¶›’¨@eŽÞøÁ´Ùúæ‚rLbAHÔDø8#ê @3ô.ÏSwQ>ŸÊ`ÖÐ nüAøÝ«}²ëÃà- áBŠ„Ñí½QWæ×È`Š^¹íI—™žìʵŸ€ÄõTœ5”ËTOV íéÄÖ®›ÑHUà,[©»?Z޳Úg±ð$û5¤Æ‘€«‹K`u1ë8•cøF:éü Í½ÆóyC=; ;8^T¹ÆüU´äÙR aÙÀS* °-PËG ­èåSKzo´ãÆ‹õh G§Ó¸¼»y–v\\vvûœƒÖ!a‡Âî»mñÞ¶´}Œ·  p;s½xjnVJ*hÈàñHElŠYÜRuA?éB ]¸+Çùm³¼„½BòÊš‹'Gº‘;‘o»¡w±5>n½“ýpÙÛ9VŽ”‚^Oó€ªãþbrܳ¯ ¬ô#맪Ð^Ô•Cka…{M‹gë ¥b ÜÉOz.uwf7‚bõlê/„ì $T­c¡­'.ßE<8" Àþ޽ì.í:©PoÍ]#À[¤›7ÅqÏŒnR›%Y1½Ûç‡Ýí××­MtšÁÅp_•æx_¿3-â6.i!ýÃqž¬-ºÚl s(ÆîYp&–ÚôFyfÀ™ "¼Sàþ Ì_ì³JŸåÓ˜@A9fX*íÃËã²x1h‘aAqÖse«®"†kRbGš.¤„†—Æ –íÂ,¡½g<м·­E³´ÈÛÇz÷VA’Rltõ{UõXäAó£wÿjoãÒN]¦p\.×õ>ßótåáy> endobj 702 0 obj 1291 endobj 704 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 561.892 174.0 570.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 706 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 549.892 180.0 558.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 707 0 obj << /Type /Action /S /GoTo /D [694 0 R /XYZ 72.0 720.0 null] >> endobj 708 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 537.892 198.0 546.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 709 0 obj << /Length 710 0 R /Filter /FlateDecode >> stream xœÅUKÚ0¾çWÌqwÕ¸~äáiE«VU%JÔ=¬öˆ¡‘BI¶ ÿ¾ã8ä„Õ^( y2Ž¿o¾y˜Å€â×Ö‹pXn¬]ãcàs^ãr=`á.l ±]Hõ[=ƒ-\ÌKhüG+³(|µžžq3Š^-z Wž[³¿Þ¡7ç§°¶>…ÖÇ/.0 áªK‘#ˆt(~˜ ’è‡pOwŸM'áÔþýmúxÿ áwk´Æÿƒ–YC|]aŽ?ŸÔel¸îôZ õwÞšPz ·ÞJ›š5« ĘFYGuÐNí«öÄMÉÇÛÁè!rÐRŒVÿÆ);«¢ænÅ`èXU©{y ©®¬ßh2’&«•ZV*†ÅÁh»4D@¨ç!žlÎ=Äj½¤•GU´ˆJõp<>NîùÄE€Àg Èt¿TÛ*ɳu%ÕK¤íòZ#’r„Ü&þ îIâÃ*мhŸ’²5Ëd )Šl7W­ydC®:æPÂ4™{N›E5'óœÑƒ—âËòªµ£.êªH²õ‡îù°YäiûØ“:Ÿý蒰ߪ,1¤õæ(ïÒP¶ª£Ú¥m]ѰÒ~'ªÈ6à(¬K8&:‚B¥ueaÙTa4åa¹¾„]'¸Àq5ë\ßdãg!J ÅPû¤¬Jòv»2Áqä\J) Æ\)˜¤eÞÞÝêœ8’p*õ$ÖSœFHÏþWâ"ßÚõzñ^ј}/fŠòjÌrÔçïÕx¶Éœ½íá¾qÝ Š#/˜ú™Wêê„s-àcu„Í‘L‘çÌúdÑî endstream endobj 705 0 obj [ 704 0 R 706 0 R 708 0 R ] endobj 703 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 705 0 R /Contents 709 0 R >> endobj 710 0 obj 624 endobj 712 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 180.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 714 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 198.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 715 0 obj << /Length 716 0 R /Filter /FlateDecode >> stream xœÅSÉNÃ0½û+æ‡/±ã\YB@!‚êQ"Úš@áïÇ!Mš‰KI+y4ã÷Þl~#þwD±€Ç9y«}"R×.¥‡T(˜Cm+˜¹[-CüXxøKh<ÃɃr?Æà–„­ÓUà2jé»Ûº>ƒ'²Ÿ½cœA2]µ(Œi¬~‘C¥ˆÝ' ™ÃýÎáõåUp{zt·;†äŒ%J$ÿPɨʡJ½š¯ÀD«!w*dÝHkÿÊ[ JïC×v¡Y=±úô‰xÓ×ãÏÁ:ت Ö®¢»[^†H¢‡šÎ58ý-·¬7ÅîCã×±)/^/õ6|–eð‘Úe±±H¤ä⯜Ž.°ŸÈ\¯-Ú†›ŒûgðÍñ5ªÐÐÈH ÄÊs]䥭SÛôv NŒ2­‘ÉÄ‘<[øàõ5„Ö”¹×.™êCÓi0ÉmdyéóæÚüÂ/ök™/&ð°xzŸÛ¬„2orê5P(C•Áöiö¹&‹üµÐ`.¸ˆ¿à!-à¡×=°äT¸AÁûàƒó›Ñù°°vXæ¡Þ l?K›ižÑÖŒÈ79¡cù endstream endobj 713 0 obj [ 712 0 R 714 0 R ] endobj 711 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 713 0 R /Contents 715 0 R >> endobj 716 0 obj 447 endobj 718 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 186.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 720 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 174.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 721 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 198.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 722 0 obj << /Length 723 0 R /Filter /FlateDecode >> stream xœÅTMoÂ0 ½çWø¸š%iÓ4Çmbš„Zâ€X¶U*ŸEƒŸ?')ÐRØÄ…µ•bÙõ{~¶Û%áÀðì¡´€É”,+% Œ+—ŒGTH˜BeK(ì[5Cì,<üKh|Á€Ìƒg2að&l;†sÉ)é×øm„]ŸÁ'yÈÈݓΠû8´(ÒTK†—Š!¡¡ÐöMaxÓë¦YðÖí ÒÛd/¤“5¤„\üƒ”¾«ÁÕî,ðQÔM¹kFj°÷¼Ž0ô>ôxn*ª‘U§/Ä›^?Ïê`¬®¢¹W%?¿ *DM[¨³Ó¿rËZS´Ü{1X:N5ÁUæ Mn²ªÒä%¥ÆÀ}QÎ÷¸Q!£Êÿ#®>nk}(“•¯Mð›ÍÉ^!h$.}_Í¿BÊèRH‹˜m^®Ë`Qƒý£šSÉ­¯ú÷:_›ÒçŸàÅÒ8—4a¡´ô)’:5û¼Öòqv*òưKŠ[I"¦1·?°˜ŸÈ~ì¥ýÞyFi“±?Ò.s›Úl×fVæó­5«O~–7Td endstream endobj 719 0 obj [ 718 0 R 720 0 R 721 0 R ] endobj 717 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 719 0 R /Contents 722 0 R >> endobj 723 0 obj 422 endobj 725 0 obj << /Length 726 0 R /Filter /FlateDecode >> stream xœÅSMOÃ0 ½çWø‡'mÒô ÚÐЄ¨Z1¤i*탩ÛÏÇIº­%êu´•bÙyy~yî– @z#»¤™„·Û¶9©„X·)¥A$\*XA+XÚ]@#Zü& ¾`ÆÖ ážÍT|$Àžáßã¸`y‡ßVðâüŸì¶d7c¡ü8_Q"¸É"& ef å æWÏ“Ñ,½Lвˆž®P>°QÙS ùjr׃kßy,éK¹3ºWP ö+!8åÏYGûe<·--[×ÚÕ7âC¯Ç¯ƒ:ð,»*úSqQòáHcÊpÓ“ ºá+ \´Ü'1Ô:¹jhšEO“s6m5yI›]ÕxU7ã,ø+ ÄG­é$Ó"~êjU‡ºÙ5Ñ÷\Ÿ:„BÝÀ+1:À$ ׂºF-BðݴȧÃ|©Å’,Ef„ÄÕaW­›z³æsö ¤ º endstream endobj 724 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 725 0 R >> endobj 726 0 obj 355 endobj 728 0 obj << /Length 729 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_qŸ¶¦˜5¾ŠR HÛtèPèbl’|m:Ö&K‰%·ñ¿ßQ¤,É¢å :'€Ž÷~|¨§ ‚SóP1ƒÅfòäæ((ì"$ÖðÇ$Ÿøer{/—@áë„oW3ßL>wä›7ä›ËïjÀ)û_40:ÔQ©ãÂð_upz/¤ ý7ÀæÛÙZ ·s8ce›W™ó´{ZE,ií±Ï“vÖ â÷£³ðÛ 'ð0y;›üøA%0[µy®8΋ÍÁl·¯brq³_'W³Aô¿±ËQ4²Æ êÕˆB{6Õ‘UÎ&kÒu²ÑÖ(D,H(ÍúÈ2¼ûíêrv5ýxýþêO°œ‡õ”ñ ¢fq9ïSÇ ê©82À»­N* ,“*™'¥†4_êç QXy4 11*ØM>ìòE•yÃsÚ7aHű¢Î77û¼JžÆØ#Œ‰Q1Ò„t:׿#3#áY¹¨›Ö»Å”ÁpëFÔãH2CÞ‰í@{ye|÷·ÞbÌ'¨õî@ ã>ÛÇ$âaØåéÓî´1LýK‡±ÈgGRUÛt¾«tyR>ÆIÜ›&MBŸ–{-úég8ŸÈ¦ªHÌ aÜ5®ËíÃn£óª„$_ÂïI¶kMªl4–a b¥HÕ0™‚RËl­Á°A±‚jíŠTJttþð”ûͼȠØÂÍçO Ÿ·º,±ZƒqíT0*’g _·CW·0™þO4‹ã äØ`eH}™ë×nÀt o‹"ÓÉiŒa³“Ø?i|2ƒ½‡Œ—¥eU{£Ù¢öOyFÁ¡0E9þÌö˰]¶=¾˜ÿ¥|]§‹5,õ*Ùe˜¸U¯Ý`Ú,}œ/¦H€EGЏá½.Ûô±{(øO>`¾ÊwG_ݱK¸Px•ä eÛ I–ée3éÙ‚è<¨ó¯·Pñ6‹ƒ†¦ü²Îu7(õ"]¥­¾óýyÍ™9)ñ”ÄcVy¤¸•EtŒ³õç ”@n†'=QìÙêlbNŒñ7 Ø,t—O ÕËÌéÑi޹ÄIx´¿M_䟪x݃&DnØugIÑÒ»²³¸ö£EŽíl‡ø'è°®{Ëmêºá˜¿i@Â3)=£éÊ©ãíXºí¨ÖÍM7UgçYUy¡ ‘ˆq†â^Ð#…Ý¡·ÑÉitÄ|æ@@¬8ä1òð6¢Œ‡ìIÞΤeKŸF{< XH±=ÊØ³ÿõÇO§{c¬­pK·•Ò¼ÜuU^uèÎü:騒´d^äÓìÇÁUEÌçî1ÓLN°¶ |1ˆ©bå½QÇSO6e½âµs›]Ù³ú‹ö´ N¼‰µ.å N>.UÓo¯Í…æê9Ù*ù¬º»ð0ã}³Ï|×½erèÚSýŒˆ©œ>ZxE„Ç>@3Ï:å·ã|Œ%zY˜ë®â:Þ¤K W«B¨‘þDóiŒ‚S‡‹.s‡Ð±£Øˆ/Áœ&§ GT-ëë õìw bŸáAŠKLqJ¼éˆGÖ–£æóý¨õ–^¨‹"ç·!¸|Á!pb¥ˆl*l¡kd™dp“V»ÄУq@àøÛ«¹Y6q¸@ߘ֠·[¼€4£ºÓ[²Lògº—«9†9I@ â~é‘{qŠÓœ> ó¢:ÐI«·»]Æö–Õ ;Æš[×Á ííë0wÒKEëˆjÿ¨[QOÙ!¶HxPZ(Ä‘aæìæhXëòÔ\·:«ƒ Þ?œˆú˜>RÄ£ngæóìi^H2,Ôål/ :Ÿ'?Oþ&d] endstream endobj 727 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 728 0 R >> endobj 729 0 obj 1510 endobj 731 0 obj << /Length 732 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_qŸ¶¤˜5¾ˆ”T`24:´ÝºÛ€¦›ŽµÉ’#ÉKüïw%Q‘hÙ†. RâÝ=÷~ÌÃŒÁß¹~ƒåvöм£0à²y%$Pßc¶Ð¬¤úToÁÚ>Ì!\là÷Y6#ðãìã'ü¸‚32dWßÌ>ôäë/ä‹Ëï#à”ý/4†Ú+µ_þ^íœg„Ožé9®{oßÖ¹y‡oŒlý)m,Ý< ³4ú˜çQ=ˆUƒ¸íØhøå„¸Ÿý°˜}ûZ%°XÛ88¾ñBé‹-|¼ˆØå'Xü4»^Œ¼ÿ…M6ò¢–Ý)ƒÐÑ«!!„>Ó©ölÐèdTzo•QÊa?yD }>4¯~ýù—ù›÷¯®ÿCצ”z椌én †lŠ^ùbXÅU|— ’l¥ž¼làëSDYHÃâõ>[VIžµ4Çí"#OÐ0ŠÚØåæUñSK9„Q"¼HHäÅZÄõÏ@ÉÐwœ\¡jóZŸ¡I|×qhq Š*ˆƒ ëyu„N_ý¥‚u JÖóU®Êy–Wsõ””ÕQ©u’|Žfœºll9–À]§$`×rø¦‰·ãrœ.…ヌÓqF9v m˜_÷û­Êªâl¿Åé^•Ç!븡QäÍ¥{{”ÃTÉb£@“A¾†jÓäÄʪH²ûo ¼õ´+TYb2yÓèBÌAÎ1ÅÈcnl#‚>¶Ð©ú/1Â=4!~ Ýžvâ“]Ù’”ßý©–n/t$4Ào/½ÓÑÌ÷Be“ ÞtU.‹d×/ºÎ®„ÓÕ[@Cˆ±„K˜s U¨‘tœÝv§©ZÙýDqô™Çi€À¹ïy"oämÝYP‚È áàt2 ±q!µ‚MvÛ.­As»v§ýøf}žtpÚFé “Õ³®©P ºàµëã– qdè¸8~Fš„rŠQ‡$)»e›#í푘ù ¹Î—;$ ›¿+Çö¢Ç´PŠ` k¡ª}‘•#LŽÞx„¡ò!‘†ïß¼=ŽEˆ)ÒNöãF*.{Þí–¦¾8 \¢ël'läê‰^.¤'u‡#’:IÏŽl•ŒÁ›ré9 3¼Dèv_ ÛÊ0GhˆãüEÜtzûf¢\ÔG·lJ|§z*²ž ìÁIÓü±´ûª5¯KxœÚ7åN-“u²Œõ‡ÞÁucYݵí6·kþG¤v%Æl×E¾õìv±IzpûëB=ì“Âô„†4/þár`e¾Ý阤Iu€Ç¤ÚÀ»gô>.}/’ÁIÐðº~Š·»Ôo®;ƒO¨çvhÐÜŠŒÎ&(Ëù>®óüÓíå¼OùsRœ7Žc8 $Øzc¸cë¦C; 8cé vœò£­™¤#Xœ÷)M LÑ?8å3æ‰Â0h(o’•‚ëõ§¸rj` CGx?l/ˆWY34c j ï0üô(09Œà¨f†ð1¿ÓÃ(–Þ ú3BV Yîã(ÚQ¶Ö‘ß&µÇá…û4 ºËùx„8ãŽM¼…`þIÞ¥ÌRµ…æ&©öum™ôƒä8Ñ1Ñóà•.F˜ôm3fW³ìÚŒý¸î–SC‹†—5‡ÜãœÒ…3±[ÇwsáéöæâÓn{Êê‹Pg{!êÞµRn QvÊŠzH;ßâb>ÎBéûŪxn˜£bÖä“m›bIeE‚2ÇS7Û)ZÐ%.ûºSáêaóøÈ†^¢mÛó:~à\{óD`;@mê›l}Ó÷Ûg³Dýoų a\ endstream endobj 730 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 731 0 R >> endobj 732 0 obj 1485 endobj 734 0 obj << /Length 735 0 R /Filter /FlateDecode >> stream xœÅ]oÛ6ðÝ¿‚ÈÖ‰ÆO}Ø€ M‡Y.Æ6 ΃lÓWYJ%y‰ÿýŽ"%ÊŤ/]ZÀwGïûxÔ×Aþ]¨Ÿ(¡hµ›}54‚"ŠXhH"D„T 2°@™ÚÕh ÁÞÀúk–Ï0úmvw‹k„ái†‡Ç5Ì·³O=ùjwù} ¡ÿ‹J‡&*M\(ü‚&8G ‚ãã•^à:º¥6™¦EËVK™ñ´ùÕŠhPÛ£'íÀÖ ìö£±ðû Çèóì×ùì§÷Œæ›çJÓDýQ4ß¡»Ó„ŸÝ£ù‡ÙÕ|ýïì²Q•ìÎP¢cŒÉ‘MMd#c“6écº“Ú(‡xŒhàP¨ý±f¸¹¾_\|wõ÷Õ-ÒœÝ~b#¬6cç‚ÒhÈ@} èYï˼B)ʶUŠ Z§uºL+‰¶ùZ>Ë*huºsàDêóÞïóU½-ò–gÚMa'IDŒ›ny>·Œ‰CÁa†c*Œ8Ôü ,޹c§²îÂX4ôªˆñÑ?|‘ÔªÊ ô!±c®ÖònÅ.mЧ\–“¦RæâñèB9v0´œ–;}úó/¨”Õ>«_"a"HOFM/ËÏûÌkȨ|þL³}ëo—â*¨!¤TJÆçŒ vð\¢ª.·ùçs4i-á *~ÌúñúfZìvñ ¢DoÓ, ü¦Å,ˆøDÄ·u#¶K[”Åò¹ªÑÓÃvõ€Ör“Bœ*TèA.Ú­oüÊQø¤0ÁswB­1ÃüA¢š›ê)©™D©j%m,ªÃnYdÊY·Ÿn|~„¼ª ;œ÷ÚMµCÔ)•Ú7]þ, B!pŒUñ‘ ác}ÁM´éS éýǵávÕˆéÒÚÛøÆvÕéâ¢"€ž$<6§¼“ÕªÜ>ö¬óB‚ª„¹©é¶ËŸ¡‹œNS 6ŠuhØÁFUK(¥Š T7-µéªÕ±ì­ZØÓÁB¡n&hCœ;ô±na>~«‚.œí*¨£@)uð7×T"‚ý½,r±(ñ`r]eáɈ“ á Ò'J‡y›Ž|¬Vöò`aãKèªÑLóžÚõCÚÛ[äYï(s÷–ÁYk·Ø}%ËÞδ”Q ,×%\oÆ~Ç‹%a@èê1ß9N½Ìî¦Ô¥5˜ ƒ˜ŠÉqê˼0õÆ“€ëS4¤œÒ!ªìÎ;ÌxZ#ÖÑfÑøYcK»ÑSŸÐÑh¸†#‡’~gQáe¶–5QÕ° ªÆ›˜¾¤%ƒç ¡cRξYKƽÌÖ›Ö‘jèúAæÖ”ÞÂÐý3‰Àpqîݶ?It ³éSQ®-!5s—¥xFW‘`—ß7Ò4£mw[ÝS5^÷U×÷gµ°p¯'hB‘OS=ÊÕv³•=4HXÂïÐŒ t6ûÌÒþmFR‹oŠÒÛÓ§¯wPˆû›ªmä 2ÙÑ£(\ü4aŽÓ|ú‡ÓŠ^´®Ô¨éé‹3K²]½AmWuª›®Û\o—šL˜¼*òj»–¥\Ÿ÷vX°›á;‚ ;\Mˆ-¬Fʱ³¥£”xâhŽi'×f’UÓÊtÝ„L} Ÿ÷âxB qsª™w0 kmÀM äwùšQ‘Å\½P0ޱiWWÏéî1³o/×{šS`" :žþ~pôN^œÉðÀsqqz"AZqòñË :Y»Ç4?4pº^— °LËH1ä|³«“EäÕ½…^ðãâôNxîŒûÅ™SÏ0qêÙ©cut²ÇC×ôÕö…BÀÄ)LUœóab‰®6x·U¾±]ÀcZÀ sY[ëE._}ò &1ܰ‘Qö²‘½qyðJTÃ#ƒÇ‰ã‰÷_r\ïD`Æ]ò­dóJI3t»­÷©‚½¶‡œŒšÖ5´½ùøiöúABñ endstream endobj 733 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 734 0 R >> endobj 735 0 obj 1499 endobj 737 0 obj << /Type /Action /S /GoTo /D [727 0 R /XYZ 72.0 720.0 null] >> endobj 738 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.114 192.0 106.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 740 0 obj << /Type /Action /S /GoTo /D [730 0 R /XYZ 72.0 720.0 null] >> endobj 741 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.114 180.0 94.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 742 0 obj << /Type /Action /S /GoTo /D [733 0 R /XYZ 72.0 720.0 null] >> endobj 743 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.114 192.0 82.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 744 0 obj << /Length 745 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯àÓÐ5Ç‹HŠ6ÀEÓ!C °±Hó@ÛtâM–RIF’ßC‰ºØ¢åú¥‹øðòñÜýmBÏÔ})ÍÐj7ùæç(R qé§„D4ÂL ò´@‰ÛÕ#XCÁW½ ˆGôÏ$ôçäî׈àyBŽ«ÀóÉç·B~:ÿ¾œ²ÿE'Cå•Ê/ þ®œs° "r¸Òs\;ßÍV y=35o·”xKûïZš¬õ©¿OêA:5HØŽ^ßǜ ‡ÉûÅä×Q‚›.·3íþZìÐÝ-¯îÑâ¯ÉõbàýŸl²ïV¼BèN•g•שVéÖìl­TÀQŒ˜ÆD ·?®7·®¿L¯¿ÜÌó)ª¡-€2†©p|B¿2¦Žláz¸-lQh“å¨|´È¾l‹Ò¦+‹² 2hmJ³4…EÛtm_p£„ (QL4ƒe}ðÇ}º*·YÚ`NÛKj,h¬µ¢Þ^ó×´4/ P˜Q"1‹€›âÔëQýiG•*ÓJÑbútl+<¼‘$9†ª´çñüTyüòŸ}aÄxˆQöœÚü$'&C˜1&ŠMœäÃiP£ßÿ@¹-öIy>(˜(Hš˜ˆ=Ëö;›Blštþ6ÉÞ§w1!4VÒÇùÀ ƒ¼y䀃¹ðwùP 2 *Ê|›>¼CÅën™%fþù$ÌèX@ ãqébHBŵZ\o€™µRœŽ®ˆC]Boo>f&iã”üÍ$ɸjŒÀ­ë "0A톰YWo²å¿vU¢çÇíê­íÆ@¨ÌÐ[?˜6[ßžŽI ,‰†dX´h†ÞgYbMçåÓ± úàúµτ¶XåÛ§~9 Þ1\I‘Ðq{sÔÅù òKôÆé†vÁÙÐ]Ñnf zÒ¤-éⵡëÀnF+p²]·Ã±*İVNiÆòŽfr ÛíG[ƒj©áÊQÃÎF ïà[ êlFm$¶nÈZòâÈÔìˆéxEP!pŸBc`µ¢£O Ý–€ÞÃ[bxØh‰ ñ´ã½|ího‘n¢±¦î ¡zb—¦·7K“ÞQU¼ÚÞfg¬u˜í¾°yo§Ém7°/f·$î¦n6CË<ÆV„Â4¿Øw‘‡½hŽzˆîjæ´¾$bhŽÁâiVö'LK9«´—¨ïÚ‘7u=è,í½¡ëѲÛ8’œ‚c¦\“©B2ÛŠÅ£àN³Ê­5Ý÷j=S9õœœ\Ю\*'GÁ=;Sº»´@O;ez ÞïSyÄÄÙ ÕýüÍÄ##¢àã^ö)é«P¯Í][¡K¢¸ycõÐèniòû¯W‰ut„…žp1ÜAóx¸¯ßÏ©ñk Wµþ9ß®-ºÞl (Æn[0$–ÚÚtHYjÀˆ "¼Wà E™¿Þg3H’åëCA!° ©b^çÙ‹ˆA§ Š³Æ‰+[õ^®Ûro=ªºú^F‡rt‰îB ,¡Ë‡ÇHä­m-š%EÖ>Ú»730’”bW¿[UæA|!ðþ_åÖ”vZEXð—w,㗻γ§3‡ÂäÂCˆÿéAºVǺÏwœmâ endstream endobj 739 0 obj [ 738 0 R 741 0 R 743 0 R ] endobj 736 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 739 0 R /Contents 744 0 R >> endobj 745 0 obj 1275 endobj 747 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 180.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 749 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 192.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 750 0 obj << /Type /Action /S /GoTo /D [736 0 R /XYZ 72.0 720.0 null] >> endobj 751 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 204.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 752 0 obj << /Length 753 0 R /Filter /FlateDecode >> stream xœÅTKOÃ0 ¾çWø‡çµ$ÇÁaÒX%¦XIÝ‹Nb?Ÿ<ºµÝV¡]FZÉ–|ög;Yè¾Ä m9¼Ïɺ²1ÐD¯2©0I¹‚9Tº‚Âïj(|§979å ^É‚ <’ñÄ9§€îÀÁC¸pxD†øÞƒðIn3ró €!du‰$£B¢[L¡‚[¿8ds_ݽ¤ý,Mž÷éÛõ²g’f-2‚ñ 3 9„ìC‹¹û5 }n9”ͧ1{{m E´9KŒí]EÕ´JÆD¢ùDÙÉkØdÑŠ‹ïž-œ…šÖXÖÙý —쨋>öžŒKÝuÕøanq Õ§Hi”çÐ/ÊåžX+ ¤:¾× ®Êô{¹Jf‹i¾=Y*‡)ù¹˜Å¬ÜD̼ìBUò\Ô˜ä[^&«î%´Œ*f¬Õ¬*á`¹Ùåuê]1À˜¢¹ƒ²jwd‘ÓFÈ!ùñ,q endstream endobj 748 0 obj [ 747 0 R 749 0 R 751 0 R ] endobj 746 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 748 0 R /Contents 752 0 R >> endobj 753 0 obj 370 endobj 755 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 192.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 757 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 192.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 758 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 204.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 759 0 obj << /Length 760 0 R /Filter /FlateDecode >> stream xœÅUM›0½ó+æ¸{Àµñ±ín«VÛmÓ µÒjip6¨ dm’ß“á£ÝKJ"Ù3oÞÌ{À³Ã€âÏ-¥9Ì×Îsc 8x~’>0A¸„5T{ «â®Æ†w¸Ø›p³„oNâPxï<<âav=‡+“§Î¤Q¿8¡¯OáÉy:¯ÞI`ÂE="¡ˆ/åC@<®‹‹C¸†‡«›¯Ÿ¿¸îon¿_?BøÑ¹ [­xŒÿ‡V&%‡’{)0Ç¿"¥Ê­)hû¤á€S¼Ž–=È­]­*ɪÕ±[Û]û u´ÙEÛ->ìåa„-hoPý ¬£bQûÔ RGU´2kõT*«ªžlKScàõ*KOÕ¸"eß%®>í<(ó­™åÆ“Èì{‡…¨‚¿ug¹Å4Ùª/E-]³GðÌÝ4pÿ2D͈dÖŠUC¼Oó#¯¾÷JŒIPŽPZÚ”piàOpuLÅij\ß'L äÀEH¼p£Ôdn’æ¶AÌÆ€j*³$ú^,PDsRÁd^š 3Ñz,³.þÓvé¶Áf¶}úµ6IžÕ¡<í’íϵ Ú£¨;¾Ø»£mºiúµ‡³'Gš{Tõ;pŠQ8‘û}Öx{7Ü »‰b²r\I³ÏM’Åi’‘:ˆ¶³È-wâ7 rœýqä0â.‰ò >øë"9ÁSDIƒ¬'â 6Ûôw™éæéz3Ëãñ*ΰ‹ó%|:à¨HãÉ8ÆÚéƒ endstream endobj 756 0 obj [ 755 0 R 757 0 R 758 0 R ] endobj 754 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 756 0 R /Contents 759 0 R >> endobj 760 0 obj 599 endobj 762 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 192.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 764 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 180.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 765 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 204.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 766 0 obj << /Length 767 0 R /Filter /FlateDecode >> stream xœÅTMoÂ0 ½çWø¸š9iÓ6Ç}°‰ !¡VÚ$ÄA¶!ñ]¤ñóç&…¶´lâÂ)–Ó÷žŸí²a¾^~DZÂdÁ6EN@$Á‹” A\*X@+˜çOUyˆèpQðolÉ^ØpD—S@|3<¥³à„ *úù ^]á“=¤ìîY@H?Ê÷µBÄ „˜ûRç é†7½n’zÝþS罓܎ }e´fÆòÌ l ¶z;bI¿ˆÛ9×.T€õ›ÊóeÖ ú.G§_Í‹¡§+Ä…Î;ÏúÀÒV]Ô—âªâç÷!ò)ÃãÚhuvúWnYcйöÑ •NSi™EÍ“lTxr–cà~ž­ŽÆJÞ yäþ%,¯>m6^•ÉÖŒwÆ›-§fßÚ,b 䥬Óíjý;§ .å´tžÙϲ]æ­+¼´P ®D¬u$ŠöW;“9|‹0Õ&„â1J¢ÒÊAæ$êü”ÈÆ ‰-P˜e0†(l€ü˜‡‚ÊÆP´ {É w^1ÌÁÔ"•otSÚìwf™ÍVK^i×€ý(öV¹ endstream endobj 763 0 obj [ 762 0 R 764 0 R 765 0 R ] endobj 761 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 763 0 R /Contents 766 0 R >> endobj 767 0 obj 425 endobj 769 0 obj << /Length 770 0 R /Filter /FlateDecode >> stream xœÅSMoƒ0 ½çWø¸ NB\·µS§ªi•ª¦•mH-]E¥õçÏùè e\;@²eçÅ~~fÏ8 ½1q*àmËö>Æ! µ) < …‚-x_ÁÆœj9âä‘q‡Èù„V3„G¶\Qr H€o†—×YpβV}“Á«×Gø`wMp„âý<"™†2UˆiHB)Ró(¶°¼™ÎÆ‹`¼˜æE<ß® xbã¢CGrñt2Ûƒíߊ,è‹C«t'¡"ìfZ[ð?GmAébqµMjãeóÖ5â\ÇÇÙAx¦mݵ¸jñáˆ%E¤³ i<¨þ•GÖSÑÔþ%C­“ª ­3ïp²ÊÆž“£4ßÊÆ±MÒË!D‰ù3Pkº)ñˆª^—Ç > endobj 770 0 obj 356 endobj 772 0 obj << /Length 773 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯àÓбƋ¨KH±tèPdkãmš<Èk“¥T’›äßï%Y¢èlº´€)~<÷ÃC~Y„áßRþ„1E›ýâK;GPH Ú) â{”£=jiŽr¹j@PCÁ^Äý¾(ý¸ø| S„ð°ÀãíøzñqÀ_~ÁßœÿPFèÿ"”AyEù…ÂÿÐSÎ9úÀ}|üeà¸n¾ŸU ™žƒÍ[~Ê[K·¿ZMj}ôטּWÛíØjøí˜ct·x»Z|ÿŽ#‚ÑjÛÇyÈ`Æ‹h,ÿ(ZíÑçqtv‹V?-.Wïc“M¼(ywÊ€èàÕcLŽtRž [´JWÉ^h¥,6ð#Dc\®4àbµúôþí¯«Ëåê_.‘ÆvÂÀ’±Y°7”†c€ï O¢9TEš@ÍÓ½@åVÑõáþ>ÏDŠ’¦©²õ¡žÑ"´háÇö ô¾ïŦÉÊÂ`æ Ä'Q‡¤5ØõSÑ$[˜Ì=Æ[hâ©¿‘æ‘oYÙ©³TÚvÖR+#È4‹2·&YçbVØ0軿ēƒÃØ‚* QÍrb̆q1óf HP(©ç5bV›£×oTl£ûJl²ââÕ›$‡™âçõ2ÙlÄ}#ÒÓáBóh,Œ†m¾Tw‡½(š%EŠ~Kòƒ¨ç“áÃCV{ÓqPÌ&*ñ©·‚D) ¿MÒdE*Q’ v,î@ͧýºÌQY¡ëx ÔÒž[Ä0ò M}b‰$»xÌP¼©þ á(ÆaàKðY…›b.:)f£‰„P,Ы÷æ™Å¡#•|•äù Õ(ñN ¸"{ÄÛ•£.Á¡rý§Ø4èa—mv(ÛäC¤6%zÙ–féË¢ùÌ#!Á˜Ã)¥CRÊ-×r ¶<”Uj\ŸŠ¢lÀ _E‘–Õ²¾‡Ýf’Å ±ß bHTêûšG—ãnÙ&¸‹ò§w¢ê¥’IÕíg²¬ËÖöÀªæ#ˆ…p¨ËÓ. c KW ±(rAOX% < "ñ£öTSåÎm‘ fÎ"j¯c μ€™V`ÂÎi¸ nk0zÐCs1½Þ^õ­f™‚±T’x§Ï ƸbU¯Û*ðƒ¨7Uv߸¢S Ì¡ð` ’¶Ÿ1mÒ¬SDèE2 MRõ3mzõ•ÅŽ)éÄ~Zz°S°ÿ²ÍD>Ü_ùºB,ÌíÙ5rÑ»éçäØb¤YŽZ&i7ØëxÙ©s5ƈåÇpiz‘©•jiu’™Qk-¥¡žY?uä¼Z$‚ƒBvê”s›àÎó–'ئ€£u„®œ…À<¶™ðäDÃð!X¾Ì £Ï 3ê΢ΪeGZΦgèáK=¨zf‘ÃÝ$øÜ î-ZÏ–7€]E-,àÄ঩ƒHQ­1ÌИQ ö"QUA š]Òô´0ä0ÝÔÄ0bG¼Qq‡\³©Ø§[XÆb×çF„lÛQ6â1«›º[²?Ôݧu§Ö¡†ƒª¥¥³SKˆùˆ­Èk]†ÊO<‘3bÙÂåâÈw! ã¬6T¥ê¼H=3ñ~;–ÎRJ ÏŠà^€“ÍqèÂNL ¡»g3êúƒñ²Ö)Š–ws30§Ä0@»Y§µŠEõ1 †m (zÝm5ãwñcÍTÈ/}ì²k€=Ùsa™e·]c'Öð6Ñ7”cz !T¾ MwqÞC¶ƒ ;íRI™˜;7;Q‰¤û®á6¥"ë8ú§¶¢Àpa8{žÄò"ehˆ£b@ò8¦ŽÕÐ1¥ìßÇ”R<ë÷]‹±},aEÆmI%î’*Íá+ûã Ž7¥ºgÁÊ'+èbã·MìÏ ¾ÊNeG”Û²Ú'²WLÖ=äuÙŽ*‡žZisèA-6e‘öã¯ò¡Â¾q3Ä™NO(3ËwY•>c[}‡èuŠ -ö‚Ëñ½¶å¡jv¨ëlk¸å eCèÏ¡®'ºÛ¯Õ‹RÚ×è •6x ßœäÑ<¹9{F³ïGñ1ÄøíÃÐåc²¿Ï…³aà$ð"ÊW„›ñág»dé­&Ê'!noΦöá4íôú zõþjåŸ#øµâa ÌÇ#Øð-Ó¥0"/ BL£¨E^g©@—Û­Ø4õ|£> endobj 773 0 obj 1726 endobj 775 0 obj << /Length 776 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯8èÃбF‰ºØwK· é-Ö: MQÐk“%W’—øßïP”DY¢äì¥K ˜‡ä9ß¹“Ô×™ ÿÍÅX°Þ;Ös&xP·žr\0mÃr`õØDìê ¬f„?r¶ðÇ,øeöé3.F@áaFúâ*æåìC_¬oŽßÕ€šÖÿ¢Ð¡ŠJ ÿ{Fœ“Ç&§+Àµój¶¤rg$¶XJjO׿R9”öÈßQ;ˆ2ƒèýX[øíÀ ÜÏ^…³ï_;`7*Ï=Áh÷ñgA¸ƒOÏMB.>CøÛì*$À7öÚ »µ‡‚‰õ !æ‰YUp½Ú(iÓ[¶ãÒ(l¬À ®#öû’áæzÎax{ýê÷ðjþùþj RBËgºè oû w–åõ¼)¸åå!O ˆÓM–ïXg)°Uv(¡Ür`e™Ç«CÉ¡<îyÙ”l•p£±ÌÓXf› ¢¸åõ!] É Ï¸ÝÀpL?<³vâò˜–ì±a 4`&q â#ë×_ôÖ ØÐ0B¶ú‹¯KxØÆë-D|Ã0‰ (3xQófë‹iå,‹`VŠ„ó©D9ÍH­jC¦ˆæaœÏcËöð`ÀfH­:æÅ:÷ÝŽ¨=<Ӡ®ãIƦY_`yíùjºÒ= ‚ÍM ¯mRÉz<Žà1g9q‡j¤OyЧ±ecb“ÊÈ”oÉ-+ÁÔ°.5ñhЬBT55óƒ)õ B\bšx²Užî_Ôdî8¿ê2<_¼À,ˆÂÒH›êm4ð¦Xøê8áÝ**½»Bu©szòvœU%;Ç•@$=+•¥ÉQQ'åÒì@§FŠ\u¶ žwv²œ+B4jâz£ÆSW ß MLËv4¶œ‰0™dVøqWk5”'™¢#žfåÉ ;5^Qâ|¾§©…ï[OàÐÿ®©eO2+ü¸ãPq_P6ý´cQwIi“Ãmg•'\ÞU(7'¸šŒ0ƒž yuÄÊpÃoÖšªõQK…"¶¼»*·šØÄyWL­«šˆ‹ÆêæÙRÒ"ͶÖw—# Ž×‚è‰Ä]³ð6 ñí_NÄE¡ÇÇ=mÁ"Î#EÖ^³e( ïÑëX\¤ÇÄn²C^nŸ ·X³¤CÖGápŸz睊4C7càfgú,–ƹvÿPbë5ßcPÒLu°ËGP†"ó‡ïÇä WQŠ7Jbã‚ïÔo›«G¶Û'ê¥{`ck2\|Íû­¯åwÚ‡3|â(+;rþùîbh”mú=1ø¼CYÏ[=ƒ—×oClÀÃÈÝ.>»Ï³Ã^³¦øT¼ø€"ªÊû"Ê¥|\Üþôëâ{W%É”( ›Ú¡Á²-=ß±8é1É –ànÏÒcß =ˆcëAv,e÷<׫[ßoK\z}ónúàO ¸ýÀ¶yŽ—oòêÝ;dîÊ_ÅXr;âbxýæj.Þ¼Ÿñúa¯AVÑ—CW>G+:Š"h?ái.ÊçsßÁô³ÄןÔ/¸eq¸ÚlðYYL½ÃÛ4|Š=Ò|ÙËRþ„rsÄ×,Ú…\Thxº¨çŒ1 ÕkS!/ìOø–†oVïÄâ«GÑE°¡²–qy¨Þƒ“¶»xàÓ1Û«oµfÿiX«¾ endstream endobj 774 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 775 0 R >> endobj 776 0 obj 1622 endobj 778 0 obj << /Type /Action /S /GoTo /D [771 0 R /XYZ 72.0 720.0 null] >> endobj 779 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 204.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 781 0 obj << /Type /Action /S /GoTo /D [774 0 R /XYZ 72.0 720.0 null] >> endobj 782 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 240.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 783 0 obj << /Length 784 0 R /Filter /FlateDecode >> stream xœÅTKOÃ0 ¾çWø‡'m–æ¸I !Äh&„¦x˜ÔmŒ!þ=ymmöâ2ÚJ¶ìús>n—„š;±F*O3² 1’CÚ !Ñ–Q.`ÁPÙ·Z_{Æø—ŒówdN.Èxb’Ï€¦à‹à6œ+.ȰÕßfðèý^IO“³s A¿4#⌢PæÊ$ä4åÖ53Ó3Ÿ\ tµ¾ôFºŸèû›~q:}Iú:"•2þ¤†î Ž…“š›GR§w”Æ™Ö.lâMÔ5L}ÌD|o›ª‚xÁúƒx×óñö lh`›E¼Gm~x/¤-dHóh#²ƒ pä©íi{oø¤ÀŒ°9"²ˆ–WRžSQ–ЭV‹ ±7Ë!E*ýÃáªí9áÎWóP×ÓÇϺLêï÷rï¸ nÆÿŠ[MWuƒ¯Zè¿Ð–Š –+%Y }½¨×õ{ä7'd˜Ò¹Rb]2/i«åüÄç ^ endstream endobj 780 0 obj [ 779 0 R 782 0 R ] endobj 777 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 780 0 R /Contents 783 0 R >> endobj 784 0 obj 369 endobj 786 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.114 204.0 94.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 788 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.114 240.0 82.514 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 789 0 obj << /Length 790 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯ ò0$E­ñ*J6ÀÅÒ!EP µ·=$A!Û´­M–\IFâ¿C‰e‹–“—. CŠß¹óðPßGaøõC†-¶£ïfŽ IóÍ”ðáh‹ -P¢WuÚPð¨±AÒFŒžàåa<ð)» <}éÈ×oð—ßÕ€ú¿h u¨¢RŅ¿ôªà½¿é®·³•@VÏÁL-[¿JŒ§Í³V¤&k{êçY;°5»ýh,üqÂ1Z>ÌF?ˆ`4[Ù<—H°ÐPÿQ4Û¢‡k‚éÍš}ÝÎz ðƒ½Ö ¤–ÝÚÃÀcrdV\iŒªmúmUm”à <@4ô°/ôú ÜßMgãÉlöõîß³Û)ªÁ-„0ßÃ$3,úàGJå)€ÐWUîó´@åF¡¨,óx¾/U²ŠP͘-€Lâ¢ô;¤ÃN<b`ì׌?îÓEgiƒ9ï2?ô ÂPã²é!-£—:„ì{”ƒ4Ɉ±£ú;1=àŽ•Ú’±µôÔ[Ò…A2 Ê‰6$À@Ú‰zÏŠ2~úWÁj*{NU~^’ta†„HßXF QqÞ"FýúÊU±OÊËI@˜ð°„@–VèI¾ÞoUZBö¥KôW”ì›`¹×I!BOúR…ý(ôöèë€Ì`hXo0éú=*Ûy– ,GÓ/÷H½ìÀÂòÜÖ- ‘, E(s+×ÃLZ-ÎF‚p¦+kúùîþ¼0Ÿ81ÚÈ_¢$6 ²ÙºäQ!Üéâ´®› ˆ²ù?jQ¢çM¼Ø ¥ZECP¢2ôÎ ÆÍÒw”£¾"0æM€Ò­Z49®çÓŒñè0 Í&ø]‹<ÞuK¡óàDâ" Úƒ£)Ì7h,¤GÐudI­Aª¶t T®t†Â>‚i;««½el˾“g½ Úá@õ0í:,ÜŽpÆa­ø8}* bˆ}Ü|î`w1E™äCx«B£í°MVë½ÌҾ㓧jè ûÓ×(ƒhÀb¢;$j*hŸå…zÃÁV~\ôué!á{\h¸ÏÜkø}j…Ï–6N·mPêáVEiGïruÖfiÒau¼Ì pÝÒ-y_¨¼³2Ê•èMª–ØÝ­kÓñ 1“.H#P‚L j2j©º:´Ã¥J³²;aWjÃÚÞ¸ïÛ‘q˜AtýeÞwÕ£¹];°[ ñBhP‰€»Ú[ýÀø تZ§¦mlêñÝê5Z†°Ip€ ƒ Ë[µät슛>{ÛTì´_:ñOiL'(ÚhcìåÓ‹qáq,›9’o_¢í.±}—«gºo`ºnÍ%ä´ÇF Ød¥žoF€_9@ãøx}¥Añò ]­ól¿«¨Uœå70H"K«m'ú¹È¶»(=T«·Q­Ut_(‡võX¨¾@\mT¼Þ”6Ïc¥¹Ìã¼Ü,£ƒ&—ßöe oœŽê8ø"tÙû.j¡m‡ðÍ}x/º]­ *†š.‰ç hÝHÓíe©zE¼áVW/¸jº•I% ¶ïü0$PPáQHf,ì7f¯/àŒ•ðB2ÚäÛBU­R÷ð¸ÜGš4]È:xŠ) Ù›l÷±ô|¸¯Pƹñ¶Rh’Yû Â~A>Ôð0¨>ÄUŸz[£ŽÐîçŒvŒËÃN9¿lhÆpóy#ããíUq/:ìõï?bfœÃ endstream endobj 787 0 obj [ 786 0 R 788 0 R ] endobj 785 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 787 0 R /Contents 789 0 R >> endobj 790 0 obj 1351 endobj 792 0 obj << /Type /Action /S /GoTo /D [785 0 R /XYZ 72.0 720.0 null] >> endobj 793 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 210.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 792 0 R /H /I >> endobj 795 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 240.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 796 0 obj << /Length 797 0 R /Filter /FlateDecode >> stream xœÅSKOÃ0 ¾çWø‡7išä¸IÁ1„дÃ&íÉ:ÿ7éúØCF[)–]ûóçÏY±ÞV~h+`á<Ê+XgÑ\‹“‚ß-ÉÃMc¬=ªþ‰G¶§bŽ]’¡ÖIU“ïsƒ“WVœ¥î×8]f“Å|D¥'Ùf”Ûë@óÀTbÒÒU¡»™¢ÄíbžòmÆqèDsE9VGE^?M¡=]/Ê™V”ÆHZž’Ýí÷îét²ÎZ£,û˜> endobj 797 0 obj 401 endobj 799 0 obj << /Length 800 0 R /Filter /FlateDecode >> stream xœÅRMOÃ0 ½ûWø‡'išäȤ†Ri‡i'pX‡&øûä‹¶zíÚJ¶žã¼>?#ùw‚¶Ÿ:8fŒ£(ë ©yÅ„Âs®pNñ“ùùä á„×°Ùúâ3’oøú}]ln¡ñ‡ ÍÎOø KW 9¡{F$¢²ÖT “†G ëpsv»nÝâÒ¹ûõòÁ­Úó-ºX¹BäâzšøQ@tYøO³huQP••Ñôø€FB™0$îPÚgßrL?’Ò¤'ÅI4È ±Šr/f%Ÿ^ 91S,'9¹3Oí‘»×#‘{c ñBV4WgQIÓÝûçî#©úg•AiÕµ¿Éô‡Í¡ozäÜ endstream endobj 798 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 799 0 R >> endobj 800 0 obj 294 endobj 802 0 obj << /Length 803 0 R /Filter /FlateDecode >> stream xœÅSËNÃ0¼û+ö‡ºk;v’#T)ª*…q¨z¨‚Jmª’ ø|üj›4äZ’H»Úõx<žÍ0@óŽlˆSåŽBAÌA¨P’ XD¹„„\ÂÖ®j%ü˜™à™ä^HEÈreš¯€ðMðr;^¼Åo;xu~„wr_ñTC(ÞÎW$Æ šG¥PÁSûp(v°¼™õz|ÔgØVÑ‹«’Dl iÒ†rp®|k=#-÷IfŒµ3Í:²œ¹qå5Í÷®½ªñ4½¼‡(‘RTÊì”Dù©×Õúð¥«R±½;dâ0ljXãz©¨bî_d}ðd¶ÈgÃ|‰ÅaÒØÑ'Ö?®ê;¢-sò ;sŽ endstream endobj 801 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 802 0 R >> endobj 803 0 obj 357 endobj 806 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 210.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 808 0 obj << /Length 809 0 R /Filter /FlateDecode >> stream xœÅXKoã6¾ûWÌ©M5˧$.Ði7[ìb›6Û’›ŽÝÚ’#ÉMòï;õp$ZvP ˆ93ß<83ÔÈÅߨ>BÍaº=Tï„DP½R0I¸‚5Tc+»kgÀë>Ü&,àÏQ2¢ðÓèúg@‘àqD»ìJâ«ÑåŽ|»Bß\þ.Áøÿ‚Àb(½Rú…ãHJç¼XP’¾\Ùq\ó¾}[ î¾q²íÒª²tõt@ÜÐéãž{õ ­ÔoÇJ÷Ná~ôÃdôíGŒÂdÞÆyh %×öÃd ×'Œ§·0ù<:Ÿôà­Ös¤•Ýè#€¡c#J){¡VéܰRÊét¯SÊcׄÊîÁ‡ß~ùu|u~ùûùÅçàH&8 ¹•ËyŸô†ó°K ‡àC–n †Y\Äwqn 7[“L ©!‡È’ª)r —ÛdZ,Ó¤¦Ùo@Å"­CVYçê9)â§šP{„aL&‘ª(ò¯£g$=;g¨Ý¸V©kÜäá]CA ,,ðIvÜۃϴWÆW›çAœû-çãYjòq’có´Ì‹½R… ¯ÓL`}ñ¯Š‰ýr¼6‡ï¾‡ÃÀ„$Qh-$stgÙývm’"‡8™Áñjkòým`(Md„ÑÌ¥èû¢wÔX@=$“…KéŠEÿ#È‹l™Üùóú.]AšÁÕå0O›Ìä9<1Q<{L+¿Iý {dgíùLïþ2ÓËéffoWh±"…wÕd\o}7 ŽSI ñ óCæEÙ§?«ÌDàg'h·ùvÿ”~„83ð~yŸ¤øD+¾7Y†›kò øÍ)96Óß˰ù`òi¶Üì¦o–UaÇó6óåpŠë JÕ°‰€j>W+3«géA)Ä,#Ÿ¸áØ õm-|ž¥ëÃ@¬g8æX-¸ö0;ƒ\ñ!ú€ ÁjÒDbmÏ´yâ²^ú40'[[ÝÃkÃÕÒI¬¹p‚qÛNÊn§6¥4“r4õƒÍˆ}yÇŸÎÂm BáaÔbYî(Pæš%96רº”F¹Oš§ z ‹ bÒâÈL±Í’¼¬_½)#šJì6BŸû.>}Ùd™"m…?.Lfâ|×ÕžÐÁ”ú’K@hýîNør>TüÑ¡‚ÙÎ)Ðv¯‰ŒˆÛ…‚{YH.;‘ ³-«ri£$?Š×›U[8} •æPiKvÕ„Ý4§ÎÏǸž§éíÍiß–BEr,øÏ>lñ»b^D¢e¡k»ºRx¥G¼/ݳMËÿ¢£¤]¡ WoïY¶Ä]«ìîr¢”!Áª#…í”뉗3çó9ú|¨¦É5g:’QДàÚ¸GÖÚ lW6úZa/>}n‡+c~Ê#b£–h{‰EÝ–#Þ»ç!­WDikèZZ¿Ä!^áuÒ²‰B]©)Ûˆ¯€ËbÛñ ýU­{Õ*Øt‘` P™`êY™æÝ°M8Íâ¼xIRÂlW¨> endobj 809 0 obj 1373 endobj 811 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 110.084 210.0 118.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 813 0 obj << /Type /Action /S /GoTo /D [804 0 R /XYZ 72.0 720.0 null] >> endobj 814 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.084 198.0 106.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 816 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.084 204.0 94.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 818 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.084 198.0 82.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 819 0 obj << /Length 820 0 R /Filter /FlateDecode >> stream xœÅXÛnã6}÷WÌS±Y¬YÞ$JZ Ûz‹-A» ɃlÓ‰[YJ,Iþ¾C‰e‹–ã—4`’♙ùpä§ŠŸ±ùR1‡Åfôd×("´KALÀì8€Ôìê x3¯zà¯Q6¢ðëèæ."àyDÅUàé躣ß<¡ï®¿k`ü±ÀØPy¥ò ÇE*çì=$ÝÒq\»îV+…¢^ÕZ·y”Ú“¶ßµ!õ°æSåA ê?GËðý”S¸}ž¾ÿ£0[¹8WÈ(‰xlþ8Ì6pó1zq³ßF“Y/ÞùÔzŽ4º[>:6¢”²=Z•s•%UsºJ6º&å9 ³?ªÓÉõ“«Ÿ'ãÉß_§³éøw¨á-ˆÉˆDÂèŽD~˹:C˜é¢,`•o¡|Р_ÖE©³…†| ,“2™'…†B?íÌ2iÈ(É)ÊkÙ_vÙ¢\çYƒ9~naLűböܦ¯Y™¼4ÀØ£ŒÑ€ ©„Ò2©þÈG²¿±á2®ÈãÇËBôÆ´äÀ†ÜÛŸuß3Ÿ3Ÿ†ïþÕ¯jxàQ“?gz{\Oä ©ˆ<çÚÄÀQ-BøØüølu±KËÓÞgB%1mBnKÁåö~·Ñf’-áÏ$Ýéâ¸Ù&E”BÙ’«¾z™ÇhèÌ0 ÌľI†&P A; (·ëìþ¯›yž&Ìôú&Ì#Ò,0Êɰʄ¸¤TÊã:¿…=ÌekÅQo0)LqíA¯¾~;®,d^Œ!ùC’¦ÃÔ8eX;U!󇌗]véêM>ÿG/Jx~X/`©W ReídÜlýxÂ8.FÖ;[YöƒÒoÙ!æ>çyªçããÁÌFJiÀDþE‹íú±[ ½W ç!e‚ÙÚ\—æ sN$|05º˜øl'®j·KÂí8ÉÜØÄl;i¼]Y ·õÒ͇Ê#1 ‘'–˾íƒég¶`úuö&S¢˜0ËÃØ#îd4 ¡†ð΄:Ûi—Î+¹ïEêøàŽ1þŽÔ¢:œQBhÚÙÂh"Ãn¥/áTM9†ku®‹žú~…aXë©ÀÛÚGb°Î`¡?Žl5Ï_Û¡=ÃvÞx žm0%ÁåCâ6æYê¤4qîöšƒZúî ½uÛ’­nÇú%Ù¬åôuõ_Ia1Áb'ñÒ?×cU‡@*eLè†õÍàæKååÞJg³¡éf&Y?¹©=»Fnçðš öôìtÞÙ=¥1Åö›¼˜r«áƒ|ÜáXyÌNº.³K•ÏNÚ*bN°*` Ï·UòA°Óßu¤¹fÝ «{Ö¯‚±Yäüc¸·”OßTBÄDr|3,¨ÅMü˜ºVË×w ,>Å1Ú¼ãÜö;j¸YåùÝí…‡fÀ>E¬ÞþÝ ð÷ÝC±±#¡DGfšéz©a²ZaoQ %ÄË-T’2Æí%~•gú g*±‡ŠÄo:ÙJfËüuH!VEÅ’äÖýFç´ö@pÌ+ª‡.tÕx$øf».w‰2‚ïNiÌ£³˜¾¢ã;\+{dS­á2-òö¥Þ½S£"¼ý eÕO[ÕKu/Ö(DDìý@°Øê¤Ôã&Ú¼?ÉŒŸ+y¹ÍOËåò\¹)¦C+·8*X„ç n3.Mв#×|þÌŽ endstream endobj 812 0 obj [ 811 0 R 814 0 R 816 0 R 818 0 R ] endobj 810 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 812 0 R /Contents 819 0 R >> endobj 820 0 obj 1310 endobj 822 0 obj << /Length 823 0 R /Filter /FlateDecode >> stream xœÅRMkƒ@½ï¯˜c{p3ûá®Û` %DK!‡Ú6 Á”öçw¿’hÄk¢Â 3û|óöÍ0@óF6è”æ&‡Pc 9J±&)¡†Ç°³§: ?e&øC&ù†wÒ„²\™æ ü¼þ$ïðÛÞœá‹<—d2‹!”Ÿ—+šj.Ó4‘*xje ˇ"Ëß²Å4‹æOEù¸‚ò•deO`üjr7ƒßyÌͧ©3º×ˆ%ö;%8×/UG(|ÍT<·mí‚k!úA|êõø8ª/2°«¢¿7%_m iÒ[ÆÄèÜøÖFZî³Ì› "ëÉræê ÊkZìUëUMféõ=ÈDJQ)ó§$ ÚêðS5›*Ú­Ûã 9¸AÆÕ ÛÖp¨FJª˜™‚§ó"Ÿói‹5²bcƸú;VM»Ý7´ã`NþÓK_ endstream endobj 821 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 822 0 R >> endobj 823 0 obj 355 endobj 825 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.09 210.0 82.49 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 827 0 obj << /Length 828 0 R /Filter /FlateDecode >> stream xœÅW[o#5~ϯðÚ®ˆñýòR,A¥ªEêîÃ4qÚÉL;3aÛÏñÜ“8NÅCÉEc{üù\¾ãsì§E¾sÿЖ¡ÕvöÔQ¤âª’ Q™D[Ôµ%Êü¬Iƒõ-x´“ ñ€>ÎòA?Ín?ÃË5"ø2#‡Ë5à›ÙõD¾CÞ\þTNÙÿ¢×¡a¥á…ÁO㆜½Rý7â†ñq´ÈÛ1ieûWYçéîÙ*Ò6[{ÚçI;Èh û±³ðí„t?û~9ûæƒD” åfŒsí”`ìÿ0´Ü¢Ûw”Š‹ÏhùËl±< €7öÚ‘^ö`Gˆ5„ºgVC®îŒjmºJ¶®5*àa³˜(éç›p³¸þ}qõÃb~µøs‰Zè œaMA®Òôú‰1}1ú9_•nëòÕý“d;‡Š JÐ:©“»¤r¨rO;—¯îÐ#ÅÄXWµë~Øå«:-òsÚ_ÊbIµšvþºyÉëä¹Ú€0J¶0Jöf4ŸËÌì­™çî¹>t•b¡µ{U@‘]¨ )“O?RŸÚ Œ¯þv/AŒ…õÆ´ ûö;Tºj—ÕçÙñá&öЗåýÎÇK…’|þðSVܳ%%ÖjÊpÛ”¨d Áéa>6} ö4¢ô@U]¦ùýרzÙÞ*Jtsý+rÏ`fQˆã j…€]Á‰;6¬äìrÜ4ÅÝ_nU£/éê­Ý&oW¨.Ðû®3ï§¾?£œÕØ2Nˆ ²•²O]Xµ#ÐeŽÒ¼v÷®ÄçIgLb!Î,oá?ºjU¦ÓLeÂ`CÈeç’1½\ ͱAï|ÔôíÒÕ»2ºžØ¾Ýf¢¾¬‡& QЬ’,sãú‘ %5VŒ·„ÔŽF(34†¤§ùk± [C­*´ØÙHä‚Äðƒm$ö½!"¯Cs/Bç)Ò“¬ jSfa]JØãH\ƒ¹¤&]™X<'ÛÇlL ¡lÏÇšƒQ X[åÆ,ž%Un7EñùÓűªœË(¤>˜'ôi¾PDDH{,BæiúŸE˜C€˜g­}µA"T`=´vZycÜ p1ÛCÞ¤k‡› äÉ*–T„?*ÚiÔüV¬ÓMêªý#Ë^YˆÔlK0ü!¹ X;¾óápÁ"¿ã#5\a«½k €Ïît¦E ÿŠý'¬Á¶Fš¾b5y÷£@2Šj5ÖãÕ®,}fo¨ê¢„…ÀG'ǘS8œê¹×Õð€˜8Ò œ´’:€ÅÇá+á,,ýñWËÎkÇåø¼%ør?aÊ ilåšâ˜Àí!­w‰oGƒZZ%¶á²ÛÓ,ó9˜a…-½÷kõÝ$š®,áxÓ÷ÚºØ4ë—G7⟲Á¢6ïãÒ—Œ I5mÆjÚtO³È!´”„ `Z”E.I ;H_®:yQyN«±—æ¯ÐWµ^"Ñ$DÅÙ­(”Œá_±ƒ²­!v‰Ð]:t]fU1ÜÇë'Ä‹â Ã"pm®ŸGu’ v/ŒWi8w%µ›÷¤N®Õþû/j³/, endstream endobj 826 0 obj [ 825 0 R ] endobj 824 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 826 0 R /Contents 827 0 R >> endobj 828 0 obj 1208 endobj 815 0 obj << /Type /Action /S /GoTo /D [829 0 R /XYZ 72.0 720.0 null] >> endobj 830 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 122.104 210.0 130.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 832 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 110.104 198.0 118.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 833 0 obj << /Type /Action /S /GoTo /D [810 0 R /XYZ 72.0 720.0 null] >> endobj 834 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.104 222.0 106.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 835 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.104 198.0 94.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 836 0 obj << /Type /Action /S /GoTo /D [824 0 R /XYZ 72.0 720.0 null] >> endobj 837 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 198.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 838 0 obj << /Length 839 0 R /Filter /FlateDecode >> stream xœÅW[oÛ6~÷¯ ú0$EÍñ&‘°Ùæ)нí¡éƒbÓ‰7YJ%Iþý%êb‰’ç>dqñöû9<ü:£ˆÀon?R3´ÞϾº5Š$C€_”°=Œko{­ÜíåPTÊ£ ñ¹½x³MÓ7·—ƒ†Ñ"ë!º­å”^‚R W¦VôU#»Û´Øná2ϧ®<ÁCÌÕJ(×=ߤ‰ù¦Ú«äukVrƒœ¹{™ä¨àÞR¶[çNÖá½qš=´í˜š%uíɵ)oøP»âÙñ¤î¼KtÔ¥¢géH šP+-]µ4]ÅyÚ¼Û§›e¤$¶¯x¿•o·AÚ½C×™‰ ÓD˜÷Mj)k}.åM–>ž¤B@I·&97Ïùüq”6ãßL;Žòb”.t!ßJ71Ï]ºö÷/uTG/ endstream endobj 831 0 obj [ 830 0 R 832 0 R 834 0 R 835 0 R 837 0 R ] endobj 829 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 831 0 R /Contents 838 0 R >> endobj 839 0 obj 1211 endobj 841 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.084 210.0 94.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 843 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.084 198.0 82.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 844 0 obj << /Length 845 0 R /Filter /FlateDecode >> stream xœÅX[sâ6~çWœ§Nw'¨ºË~hgÒ–íl§Í6í>$yp@$nM°é’ß#_ þ¤$Yçþé;r^F (~ÇîÇ„æ«ÑK½ÆÀpº^R˜$\Á 걂ÄíÚðf„?Õ&<ÃçQ:¢ðËèî.€¢À—=VW OG·{öÝúæö÷=Œÿ/8ʪ”uáøgHYœƒJÒÃ'{…k×»ÕÒ ¨Öp¥²í%u¦ëßÊ‘jXÅSýžŒƒvaPëßÎ8…§Ñ³Ñw0 ³e‡sã%݇Ãlwß2¦ß=Àì×ÑdÖÀg­WHg»GÔRvVY\SUÅt­l”' 2ª•ÛTÓÉl<Üþ9¹ùi2þãÓôãì㧨T´‚ÌpbÚ׆õUÜsnŽ‚!˜Ú"‡âÙÂ:Ëã"ÎRÈ–Á"*¢Ç(·Û—­Mç–4¡O(’RÔª+­¶éÜéjdNgM‡D± «³6}M‹h׆cŒ*¢ ¡eCù9 ;ý¹-ÆM<ã&Þ#9Žûʇq¦ûûÓ½Ò÷Bàò+-H…Cï}VBOà›ìë€)!<®5P8iJ_Q¾ÿ66ß&Åy0!ˆ‘xv4¯ùàzó´]Ù¡¥ ø+J¶6?í¶…2ÄÔ-¹é× wüÕ‘'掀; V B? /6qútùëê1K ÛÀôö7°»5†™c)ȰƒÆ!]Rj”ñ—ÐïdOì:…8-ì“Ý ä”!­™0Tšù é5Ø»îÈ {üÛÎ øòÏŸaa—–Ù#ƒ÷õdÜl}Æ9.âi¨>ö‡Pñ{v,ãÉÄiŒqÅÊRª˜¨Ä¶ù|¯Kà\5Šp®)¬æÌÉnÄó¸Hð(ÁXl(ŽZº‰ÃN;iyµ]Atù·¶xkWæQ’ØE7b C‚PUhîûjqŽ\Zl7©]\uÁ‘\ ˜j­ÖIG¡¾¶*ð€HTÇhs¹o9N¢¼€»e–=Ü¿ëgNhq$Šä/=û°–}žž\™E½Ö0K=kŠz6†áéˆR»ˆH²ãd8̳‘‡¾ª’Ä|k‰ýG°šÙ§ñÂÂd¹DŠÍ‡Ibµ‘”1^SÙïÙ"^ƶºÈýëºe¯…F0 )2#zÈ¥ôèf¼õÈ‚#ŒÓ<Á5 ]fØöûÂgy‚9$ÁIQTÀ]ŽÛ{G™}dÜÇס (îÈ6Àªóú„õàÖrÒ®¡¦9¦s[ö£_Fâb¹ñ T€µãœÒ׌ñ9Nä<|KÐØPâ'§«™Fi;´› ^`šYÙ‘ªañº¶üKÒTÑæ¡\ÜÉEP×Ū…¶‰UÓë'"Pª:LýБ(’m­/2›·“4+ºŒìâ¼›ÅéþJ¬¬³X6ª¾Í³–Z É_`M‚Í"Ô¡©Q?µ®“> endobj 845 0 obj 1252 endobj 805 0 obj << /Type /Action /S /GoTo /D [846 0 R /XYZ 72.0 720.0 null] >> endobj 847 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 134.1 198.0 142.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 849 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 122.1 204.0 130.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 850 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 110.1 222.0 118.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 851 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.1 198.0 106.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 852 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.1 198.0 94.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 853 0 obj << /Type /Action /S /GoTo /D [840 0 R /XYZ 72.0 720.0 null] >> endobj 854 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.1 246.0 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 855 0 obj << /Length 856 0 R /Filter /FlateDecode >> stream xœÅWKoã6¾ëWÌ©Ø]Ô,Ÿ¢th7õ(ŠR»í!›ƒbÓ‰ZYr$kÿûêiëådQ¤qQ$çõÍÌGêÙa@ñ7³ísXïœçjŽæ ÜjJ¹À$á vPDv×Ù€×#|”›pð;±CáWçî7@Qà‹C»ê á¥s{fß®Ð7·î`üñÀúPd¥È ÇMŠä\,(I/WÎ×Ì·³…AQÎáLiÛ.EÒÕ³t¤–ñ”ÏÑ8hƱŠðíŒSxt~^9?|TÀ(¬¶mk+È(ñ¸oÿ8¬vp÷ŽQùþV¿9‹U¯Þµ^"­í& ëQJÙEXEruTÓ§`gÊ `pŸPWÙý^)póÇb¾ZÌ–‹Û?ŸnP 7"LJâK´Ì¥ì æ\wԔܤ&È ° òà!È dæù`âµ!µÛzÀmÉõ)êqK=ñ:“¸–GÈõ‰bžïkV!´<Åyp¬ýcŒºyÑŠ®Ü.þ:‘zr`纈oVÕGÉ@í ºÒñ†yt@ >Kr/Nm|÷¯9MârÈP¤qcÞ \?þ×3ÄK˜Ö¸à«Rnž>v&Î3â üD“»l3å2"9£TqÕ‡¦Wÿèé€ÈêÉ€ƒd ùS[ åi?~Ùi÷D¤°¼ýÌqŸš,à $ÓzÈ#§ThoÒa'{bó¶a’‡Ì:‡/Oáú 6f"D,OàCõ2«·~ ׳À™Àì¹gxüb²uîÏÛkI6·À¬ ^uVÙÛh5„ë ŠÌfªÀ'Ö:u5P9NíNÉBOv–O´å)%ýá«iâBOÉÿgéq="ñÌgÅ’Õ¼8»}Ô6ƃ ª^.=Q1u—™àn›$÷ŸßwÊ £/—ÂM;_lCrïÚ¨•ÏÌ1Ìòl¶Ÿ°‚”Þ³²¤Z»_‰ÎþóS OÆfGU.ÃÅv‹m”M•¸¤JùžV5Cµ¥fPBº¹RhRׯľÆë|à«)ùÔ´¥êâì×54/bGÏN“ñ»‚P†E®UÅìý~yŸ#ãâŠOE]ÂkSðK€÷Ÿ0?v<™ …ʱËñ§•'sÄ›˜hxgÒi¹~üÔÃ,|Œ+ª·Íp*c”0Šì«ìN3’+Ç%‡<Œ“¼­ßÕ™Ó¼—gOýz¬=‹Ú3©™E)iÈO{ÓšzŽšÜâ`ÖoD…}XÌJåX 9B@j¢"¹×Ná5ŸömLÂÎíwϸ,6êæ%+½ c°Ãõðâê)YQ†10²¤ù`hïë]|2—õSÀž½øðؤɾsEì|‚Xxµz…ÎCktfcJñ´|ÒŸêeü›ôFA–êäò›tÆæ8®S¼*Q™i1í“,l/E…nûû oó endstream endobj 848 0 obj [ 847 0 R 849 0 R 850 0 R 851 0 R 852 0 R 854 0 R ] endobj 846 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 848 0 R /Contents 855 0 R >> endobj 856 0 obj 1108 endobj 858 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 204.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 860 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 222.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 861 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 198.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 862 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 674.1 198.0 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 863 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 662.1 246.0 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 864 0 obj << /Length 865 0 R /Filter /FlateDecode >> stream xœÅTÁn‚@½ïW̱=°]`k-mÒ[*MƃQÚ’(j±i?¿³, ˆô`•d'3¼7óffÙ2HK^ a¾bÛÒ'À“`«Òå*—.¬ ´]Xê·†¬,:ÌKd|ÂË›L)¸$ÀÃCº> endobj 865 0 obj 428 endobj 867 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 246.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 869 0 obj << /Length 870 0 R /Filter /FlateDecode >> stream xœÅSMoƒ0 ½çWø¸Èœ¤ ẊM›ªJ¦ª¦ŽmH-]Óöóg壔k H±ì<ÛÏ~˜¤×«?°Ù±CãàKP¦qibÆ¥†4¶†mu«gÈ£E‡»DƼ²œ!<²Õš‚ï€øexš®Ç,êÕ¯"xñúŸì>awBòÑHnm@ Àr%+“f–ì`u³xŠ/£—p9ãÛ5$Ï,Lt”W Õ=Ôý×K–ôù¼Þô  g8ŒôTÐú;o]P9y\í*´mÖÖœ®g:>îœä ì³Êâ¢Å§áW@Ü´ 0˜À…§6Zäp‹3ëÙ2 NâHéEZzEzøIóMê}Ìöyo›K ÙXD')éGò­¢@ ]Îå¾L —ãLÔ¥¡L6pˆmVtm´ÐÑ‚„’c,d¼ÁcFÜêƒç‹8ZL׳–†¥Å¹Âé_™æÍ‹÷± Œ& endstream endobj 868 0 obj [ 867 0 R ] endobj 866 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 868 0 R /Contents 869 0 R >> endobj 870 0 obj 379 endobj 872 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 198.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 874 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 246.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 875 0 obj << /Length 876 0 R /Filter /FlateDecode >> stream xœÅRMOƒ@½ï¯˜£XgXv¯6h4M#£IÓƒ©¨$-mÆþ|–¶|”ƒ— $3™á½™73;&éu* Ë5Û51W5!_ð¸ôa ïêú«åȃGÆþDμ°œ!ܳù‚’ï€øaا«Á1‹Zõ« ^¼>Â'»MØÍ!ù8Hj®]σ4w¥© ÉæWq=‡³I脯q;O× HY˜t¹Bþƒ¢¨î¡–PïYÒðzÙ„ïa7Ó:„cü­ º6F[»J­šÍ5Ö6b]«ÇÚQx’mÝ˸hññ£* @®;ç „=€ Om°Èî=m/ò¨ÐôâàØ‹t÷æËÔÉÓ}yV'± ùwÚÒ9Ro7EVf›¼EärAÐ5jD=JOó@»”0¾åœmÊ´°gz 6—£RĤMO\ºÏвp¶ô`õÂÇ!²Þà€QŒÒ\ j•‚'Ó8šŽ×3–æåÓl‡…ii^ÐÈxkfûD^< endstream endobj 873 0 obj [ 872 0 R 874 0 R ] endobj 871 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 873 0 R /Contents 875 0 R >> endobj 876 0 obj 398 endobj 817 0 obj << /Type /Action /S /GoTo /D [877 0 R /XYZ 72.0 720.0 null] >> endobj 878 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 134.084 210.0 142.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 880 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 122.084 198.0 130.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 881 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 110.084 204.0 118.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 882 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.084 222.0 106.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 883 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.084 198.0 94.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 884 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.084 246.0 82.484 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 885 0 obj << /Length 886 0 R /Filter /FlateDecode >> stream xœÅWËnã6Ýû+ j–‘-ඞŠ@j·³H²Pd:Q+KŽ$Ï8ßK=mK–“.Ò8€HŠç¾y.õ¸Ô5ã’kšÉWWGí,ˆã4 »jW¢am4 !B`#çI*¢ zï19`÷h‰bÐÆ°CFb8ÆOj„],EáÑ1|kAUŠÍ¬-É6ªi;<*Ñé =º,+y¢ä¸ŽG Ë¢´o|Y÷‡ù>ØlãŽ@†h^`5jr¯VwwLàp»NÓû»«¾¥ûÑ1© 6 ·Ãw¼ÿpç˜gÂgÄ`eÈuÿŠVæë5Ò@>vf<¤gã. \Õ ù:Mì+‚é 0®)v÷:š³R–ÿÃ˨Fé&…1ì€\Ã]–¹¦_ļH3”ƒÜëÿc= -‚V¼ÑÓ2~¤p7&Úø É´%ýTyȾXH”Q¼°•›úÌz9†’úxaqL×´·ù>´%Ïx ŒŠ]àÆ£ ”‚c8¥†× üÅ1ž&͉BŠŠ¬f$íÐfvªf†­/[ÛáŸãÖ£êDã¢t Ž«…–«éù ®ˆÜÏð7àÚh…¤cØVû*µy;IÒ¢‹È>Ê»Y”¼Â^Së4RM‡Rq‘>=$³ü+ΡTHÀxuUFפ±°fqž¶ß1Ýg„«­eå×|ùÑã< ÕY辉ÂÌb7œ6Yü>r’}ÿ­’WYº½(WQúV¹1&²•›ŸÌø[·Ì_ÖJ>Ýž•ͽÿ,;±ûâ¬\ñæôå¶‹Åt›æQw*å»ß¿‰° endstream endobj 879 0 obj [ 878 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R ] endobj 877 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 879 0 R /Contents 885 0 R >> endobj 886 0 obj 1199 endobj 888 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 198.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 890 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 204.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 891 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 222.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 892 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 674.1 198.0 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 893 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 662.1 246.0 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 894 0 obj << /Length 895 0 R /Filter /FlateDecode >> stream xœÅTÁnƒ0 ½ç+|ÜdN€×UlÒTUBeÚ¤ª‡ªc[% í`Z? ºC×"ŲyÏ~¶Ãž @ú[úð ë-Û×>ž[Õ.Wp¸ta µíBªßj²±è0/‘ñ /,cl±¤à ~žÓUà9‹Zùu¯žáƒÝÇìîÁ¿ŸZd+î.": |nË@ÿ$Ä[XÜÌÃè9œMBk¾Æ·KˆŸXwÔØBþƒš¨ª¡*¿š±¤ÇãÕ ;×Án¤µGÿÉ[%´<&·¥õÔêÓbL£Çœ£:ð$Û*º[qÕäã ái @îwVAwt®ÜµÞ »St|³‘G…Á¹Bì-úÛW¾³ŠdÿdëdP'± y)mº)Ê#m1Æ+KyJ+9P†ÂÚQ›/ÝŸ¨ÓUQŽÑÒs1í©Ö./6å&ÏZôG.ÝKŸ¾GâœÒážÞIO؆s–—MSjÐÀ£RDågê²äP6ÐÞ R `aSÀ ê‡+Au£èÉtMÇ3zLírõuꧦj“¬ –ñVÏ"ö ŠXx" endstream endobj 889 0 obj [ 888 0 R 890 0 R 891 0 R 892 0 R 893 0 R ] endobj 887 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 889 0 R /Contents 894 0 R >> endobj 895 0 obj 429 endobj 897 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 204.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 899 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 222.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 900 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 198.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 901 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 674.1 198.0 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 902 0 obj << /Length 903 0 R /Filter /FlateDecode >> stream xœÅTÁn‚@½ïW̱=°]`®5´±1ZMÆCciK¢¨Á¦~~g]P9ÔƒE’Ì0ïÍ›wà ýsèPÂ|É6•O€–àªÊå+—>,¡²}X˜¯†¬-:ìGd|Á++Â#›Î(øH ? OáöÉ ‹ü&‚WçGød÷)»{ðA ¤Ç ŃÐGDOAÀ]šGBº„éM¥NÅ/Ñx9Ï“d˜'ãÛ¤O,J[ª\!ÿAU¼¯ÁÊ0³–ôj¾x+à{ØŽ4–áà?z÷„®õ‘Çr›Ð¢š^uÚB¬iõسWe`SE{;®JÞ¿Ú$ äAk%„н på®uÙž¢Ø<( Obgáy¹uÊlóó¬<+”`…ü+n éd;b(u´ô.†^¼•Û>X{ã][d»&ìÃAœ€.q¥%×fi´p-Öxµ­›y†›Ê 5G¥)köãœõªÌ·ùª¨ºW˜öº—ðuŽêä„’+AÕ£ÝäÁ(‰G½|Rš\ê•O›Ð%¦†eEIóFßbö jÙe¿ endstream endobj 898 0 obj [ 897 0 R 899 0 R 900 0 R 901 0 R ] endobj 896 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 898 0 R /Contents 902 0 R >> endobj 903 0 obj 423 endobj 905 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 536.486 194.44 545.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 907 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.072 536.486 542.072 545.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 908 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 524.486 182.22 533.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 909 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.151 524.486 542.151 533.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 910 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 512.486 182.22 521.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 911 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.151 512.486 542.151 521.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 912 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 500.486 198.33 509.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 913 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.047 500.486 542.047 509.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 914 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 488.486 188.32 497.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 915 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.111 488.486 542.111 497.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 916 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 476.486 176.1 485.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 917 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.191 476.486 542.191 485.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 918 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 464.486 176.1 473.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 919 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.191 464.486 542.191 473.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 920 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 452.486 192.21 461.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 921 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.085 452.486 542.085 461.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 922 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 440.486 193.32 449.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 923 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.08 440.486 542.08 449.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 924 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 428.486 181.1 437.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 925 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.16 428.486 542.16 437.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 926 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 416.486 187.21 425.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 927 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.12 416.486 542.12 425.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 928 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 404.486 197.21 413.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 929 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.053 404.486 542.053 413.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 930 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 392.486 203.88 401.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 931 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.01 392.486 542.01 401.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 932 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 380.486 233.88 389.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 933 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.782 380.486 541.782 389.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 934 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 368.486 205.55 377.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 792 0 R /H /I >> endobj 935 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.966 368.486 541.966 377.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 792 0 R /H /I >> endobj 936 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 356.486 214.44 365.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 937 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.907 356.486 541.907 365.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 938 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 344.486 202.22 353.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 939 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.988 344.486 541.988 353.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 940 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 332.486 202.22 341.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 941 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.988 332.486 541.988 341.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 942 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 320.486 218.33 329.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 943 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.881 320.486 541.881 329.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 944 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 308.486 200.55 317.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 945 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.998 308.486 541.998 317.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 946 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 296.486 202.21 305.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 947 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.988 296.486 541.988 305.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 948 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 284.486 242.21 293.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 949 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.728 284.486 541.728 293.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 951 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 272.486 229.99 281.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 950 0 R /H /I >> endobj 952 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.806 272.486 541.806 281.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 950 0 R /H /I >> endobj 953 0 obj << /Length 954 0 R /Filter /FlateDecode >> stream xœÅÝ]s×u¨á{þ \ÚU!ÒÝ{í¯KY¢S:¥²e>ñ©$´DÛ<%S6EÙñ¿O¯E`8-ižGv•ðm`0˜YêÞû¯OÖ›eÿßÓüWŸÛÍ—~ò×wï[oúvSÚ»wÕv³ÆíVoþ|óîÏõæë¬ýaûþOû¿î£ýºù÷'¯Ÿ,7ÿöä?þkÿ˯n–ý€¿?Y>üp§ƒŸ?ùͣϟ³üÓ?ÿã[PÖíåäm8©œ\¶ýÿýö„sö5–ó¿y÷þýï=}Ârÿ¾ý=÷Ÿ;ÿêëw÷ô»ßßû?Þ=÷ÿþÁ¯cyø2–ãûñÝWøÏûäËÍŸüâîÉ¿þ²Þ¬ËÍݾÏ{Ùßs;¶™ÿl7w¾ùŸõòóÿº¹û?OžÝ]èÿ“ï² ÅüÜ￘r³Åí8Ýö³¯i]Êí¨mY¶±Þlëí6ú²,­Ýu¿üîõ—o_}óúÅ×7Ÿ¼xûâæ“—xõúU¾çþ«~ø0uÿb·1gôzS×Û5jÞIëý‡ùìÅë?~÷â/oþóg¿üä“Ïþóç÷Gÿë/Û‡wqŒ›>n—ès¶úî.þø³ç¿ùìû#.Qö|Ýoò¶?`.½ùùÍÓºÜÆÍÏþò替½úêå·ïyñðÇ?<|™ïß·ß·7þþ§W_þéáÍo¿ûË_¾yóöÑ{û§—o|ùæå‹üp>×ë¯ÞØoÅÛ7ß}y^|ó‡Ã[ö·o^½|ûãî«ä÷/¾}ùÅ~Îåƒ;â›ßÿÿ—_žnp¯·óæg¯^ùõw_½zýÇ÷ïÙ?Ô×/¿ý—÷oÿíÕË¿?zóÕë¯^þ÷ˇpÿÝÿùÛ—ýîåë/_~{ûþ]ßã<ðý]xÿÖ›—o¿{óúÑGÿÃ7oþüýöî3üþ›ïÞ¾ëËïÞ¼yùúí×ÿ¸üb×eûà«ý*¿M_žîò¶=¾§Þóp‡¼{Ç‹7þöÅ×ß~óðÖ»ï¯nÞõéëGñW_ÿòð®wß÷oüòÝ·Òý[÷÷üËGŸùá»ïÕ½ô»wóæá—ÿýâÏû#ïõ¾üýçÌù—¢¼yñöí›W¿ÿîíþ©ëý›7oÿñ—êûÔþ3mÿq?öGÐzö¸ÚŒÔqÛþتûO™Ó¾;}àý[ðão^¿Ý5¾ýÁGeÞ®±Þ–(û„ý‘yÿ@þâÙGwÏžÞ}ô‹Ïž}øócÛ¿ÌȇqÄÁ‘yGäOªvó³‹÷o¾ÿ°É§ —Þ^äƒò²Z–wÊc±¼XÞ,Ÿ”×ÍrS­¦ÚLµ™j3ÕnªÝT»©vS¦:Lu˜ê4Õiª“T·…T·…T·…T·…T·•T·•T·•T·T·T·ÍT‹©S-¦ZL5L5L5Lµšj5ÕšªmÙ{= ¹ÈÛby±¼Y>)ï›åÕòAùX-ËMušê4Õiª“TËBªe!Õ²jYIµ¬¤ZVR-©–TËFªe3ÕbªÅT‹©†©†©†©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NR…Tc!ÕXH5VR•Tc%ÕXI56RTc3ÕbªÅT‹©†©†©†©†©VSÝÔ²çK·Qc쯖¾Î¹Ì~p`ƒÙìþ¬ò¼úä‹_~<ÝWÛ–cØm;8îþfõ£ èþë3_µ£/û#ŒòIùþ£¼Z>ö¼ÝO¤¯È÷Gåay§|„Q^,o–OÊëfyµÜT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mu’jNo)'ÕœÞRNª9½¥œTsz+ùFª9½¥ÜT‹©S-¦ZL5L5L5Lµšj5ÕÚOÏ FžªrEÞË‹åÍòIyß,¯–ÊÇjyXnªÓT§©NS¤šÓ[ÊI5§·’¯¤šÓ[ÊI5§·”“jNo)7ÕbªÅT‹©†©†©†©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NRÍé-多Ó[ÉWR•Tc%ÕXI56RTc3ÕbªÅT‹©†©†©†©†©VSÍém¯9%]iLšÓÛµæ™âóh.ÛÛåôvÛŸ™WŸ}úüî~zûüÇÆ·—^9¾½<ðGÇ·×ä“òÇãÛkòjù£—™WäÇ·×äay§üñøöš¼XÞ,Ÿ”?ß^“WËMµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT'©žo¯ÉIõl|{MNªgãÛkrR=ß^‘o¤z6¾½&7ÕbªÅT‹©S S S S­¦ZMõñøöŠüñøöš¼XÞ,Ÿ”?ß^“WËåÇ·×äa¹©NS¦:Mu’êÙøöšœTÏÆ·Wä+©žo¯ÉIõl|{MNªgãÛkrS-¦ZLµ˜j˜j˜j˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê$Õ³ñí59©žo¯ÈWR=ß^““êÙøöŠ|#Õ³ñí5¹©S-¦ZL5L5L5L5Lµšêãñ­ŒIÏÆ·—öq0¾ÝŸÝœW§ÉíÓg¿ûôùÝó§Ÿ_L'Ûm)9ÁåàØû›vZŒáâÀy;j,K™ëÁ—ƒÇÍòjù |&ByXÞ)ߟ‰P^,o–›j3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NRÝRÝRÝRÝVRÝVRÝVRÝVRÝ6RÝ6RÝ6S-¦ZLµ˜j˜j˜j˜j˜j5ÕjªÕT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mu’êþTÕrR- ©–…TËJªe%Õ²’jÙHµl¤Z6S-¦ZLµ˜j1Õ0Õ0Õ0ÕjªÕT«©6Sm¦ÚLµ™j7ÕnªÝT‡©S¦:Mušê4ÕIª±j,¤ ©ÆJªû_XNª±‘jl¤©†Í–ÂfKa³¥°ÙRØl)l¶6[ ›-æ”[YÖ%Oz€aài‘€hsö¥8–ƒ9ån|^½[(õÿ~úìß?ì/ŒË:÷Ú<8ðþvÕÃÓL÷o¤\BmF=8ðb4‘/‘%¯–ïßH½-K_޾üË™æjyXÞ)Ï—È’Ë›å“ò|‰,yµÜT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mu’jžJ9©æ‰ ”“jžJ9©æ‰ ’o¤š'‚RnªÅT‹©S-¦¦¦¦ZMµšj5ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:I5O¥œTóDPÉWRÍA)'Õ<”rRÍA)7ÕbªÅT‹©†©†©†©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NRÍA)'Õ<Tò•TóDPÊI5VRTc#Õ°ÙRØl)l¶6[ ›-…Í–ÂfKa³¥°ÙÒiÀZcέå?<È<º.ûQÛÁ€5>\«õ´ ëÑxuÐ.9]Ñ»¿Uóh¼š'­æ•ðs­^Ì1ö‡/åÅòfù¤|øR^-”ï_ÊÃrS S S S S­¦ZMµšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕaªÓT§©NRÍÑ0多£aÊI5GÔ“jކ%ßH5GÔ›j1ÕbªÅT‹©†©†©†©VS­¦ZSµ-kÄ5u[¨.T7ª§Ô}£ºR=¤+ÕA5YN²œd9ÉrŠe΂¥ËœC½ŠeΥ˜K-–9–š, Y²,ddddYɲ’e%ËJ–,Y6²ìdÙɲ“å ËA–ƒ,YN²œd9Å2G½R‹e,b«XÆ*–±Še¬b›XÆ&–±‘e!ËB–…,ƒ,ƒ,ƒ,ƒ,+Yæ`wÖw ¡Âõ4Øë²Ìztà8Ø^k«.ãzZ 5»볞Mv/Ž»v²{qàOv¯È‹åÍòIùÙd÷мZ>(?›ì^‘‡å¦¦¦¦¦ZMµšj5ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¤z>Ù½"'ÕóÉî9©žOv¯ÈIõ|²ûÓùFªç“Ý+rS-¦ZLµ˜j1Õ0Õ0Õ0ÕjªÕTOvº~<Ù½¢.T7ª§Ô'»WÔ•ê!õãÉîuPM–“,'YN²œby6Ù½¢˳ÉîO׫XžMv¯¨Åòl²{E-–g“Ý+j²,dYȲeeee%ËJ–•,+Y6²ldÙȲ“e'ËN–ƒ,Y²d9Ér’å˳ÉîµXžMvº^Åòl²{E-–g“ÝŸ®7±<›ì^Q“e!ËB–…,ƒ,ƒ,ƒ,ƒ,+YžMva„z>Ù½8pm½Õ>\á5‡º?¼tër»¦»ËÑ¡÷·,nËÁÒ­å¶×ý ã(õàÀËf³|îyY–:nÖåLr³¼Z>(Ï%ê%Ë;å¹D½äÅòf¹©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê$Õ\–rRÍ…a%_I5†¥œTsaXÉ7RÍ…a)7ÕbªÅT‹©†©†©†©†©VS­¦šÛæs‚¥o×ä¹ý¡äay§<·?”¼XÞ,Ÿ”çö‡’WËMušê4ÕIª¹0,多 ÃRNª¹0,多 ÃJ¾‘j. K¹©S-¦ZLµ˜j˜j˜j˜j5ÕjªÕT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê$Õ\–rRÍ…a%_I5VRÍ…a%ßH56RTc3ÕbªÅT‹©†©†©†©VSÍ!h¬sî/-iÔxZvÄœk´ƒÇÑVýÃåcß- ûé¯>yö»‹aãúheØ‹#ßݰƒ hÜŽ¶ìÿ´õà°Ë‘f§<—ꓼXÞ,Ÿ”çR}’WËå¹TŸä¦ZMµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NRÝRÍý)'Õm%Õm%Õ\S\òT·T·Ts¹É‹©S-¦¦¦¦ZMµšêi§Ä9GÍÿÌyE>)?í”yµ|P~Ú)ò°¼S~Ú)òb¹©S¦:Mu’jYHµ,¤ZR-+©–•TËJªe%Õ²‘jÙHµl¦ZLµ˜j1Õ0Õ0Õ0Õ0ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÝT‡©S¦:Mušê$ÕXH5R…Tc!ÕXI5VR•Tc#ÕØH56S-¦ZLµ˜j1Õ0Õ0Õ0Õjª§ èþZbÔ€AãiþÙ÷ÏÒj?8lmŒ5>\Ýõ´nëáôsT=\ÞqÜý»bm·mä £²v1•Èë-%”çõ–’‡åò¼Þrçº_Ÿ÷мXÞ,Ÿ”çõ–’WËåy½¥äay§¼™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NRÍÉ-多“[ÉWRÍÉ-多“[ÊI5'·”›j1ÕbªÅTÃTÃTÃT«©VS­¦ZMµ™j3ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT'©æä–rRÍÉ­ä+©æä–rRÍɭ䩿ä–rS-¦ZLµ˜j˜j˜j˜j˜j5ÕjªÕT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mu’jNn)'ÕœÜRNª9¹¥œTsr+ùFª9¹¥ÜTm¶6[ ›-…Í–ÂfKa³¥°ÙRØlé4¹}?‚½zHzº|?Ï)­6vÜʧqçÕiaÖÓäöÙÅÒ¬ûwþû«÷/¼¿Y ³æÅ<-ÏwmqpØÑt•ò°¼Sžóôý.Ý9WåÅòfù¤(Ï‹y$Ë;åÍT›©6Sm¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu’jNW)'Õœ®J¾’jNW)'Õœ®RNª9]¥ÜT‹©S-¦¦¦¦ZMµšj.³ÿ’sY¯Ê'å¹PŒäÕòAy_-Ë;å¹PŒäÅrS¦:Mušê$Õ,('Õœ®J¾’jNW)'Õœ®J¾‘jNW)7ÕbªÅT‹©†©†©†©†©VS­¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT'©æt•rRÍé*多ÓUÊI5VRTc#ÕØLµ˜j1ÕbªÅTÃTÃTÃT«©æt57JèµÁó4]Íëöëº6¶½Ê§BçÕi°úë£>ž¯^{Ãöûý`m€ýþ*ítÛ¼œ#®–‡åò|"y±¼Y>)Ïç!’WËMµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT'©æŽM”“jîØD9©æŽM”“jîØ$ùFª¹cå¦ZLµ˜j1ÕbªaªaªaªÕT«©VSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4Õiª“Ts'ÊI5·p’|%ÕÜĉrRÍmœ('ÕÜȉrS-¦ZLµ˜j˜j˜j˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê$ÕÜá‰rRÍ=ž$_I5wy¢œTsŸ'É7RÍž(7U›-…Í–ÂfKa³¥°ÙRØl)l¶6[: 5·<ùsÚìðt¹î¢0—rpà<Øó)ÿ+éyõÑÝÝŸþâ·wÏžÞý¿ÏŸŒG^ÐãèØû›¶ÜÖ˱æþ\¡äJ¬‘wÁÅ—ƒÇAùþ\ò°¼S¾?W ¼XÞ,Ÿ”ïÏ(7ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT'©æÆI”“jnœ$ùJª¹q多'I¾‘jnœD¹©S-¦ZL5L5L5L5Lµšj5Õšªu†Ðû5y[-Ë;å}±¼XÞ,Ÿ”Íòj¹©NS¦:I57N¢œTsã$ÊI57N¢œTsã$É7RÍ“(7ÕbªÅT‹©S S S S­¦ZMµšj3ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÓT§©NS¤š'QNª¹q’ä+©îa9©æÆI”“jnœD¹©S-¦ZL5L5L5Lµšj5Õ<.Õ§{§ÁãºüÐç™û,å%çÕéjõóéãÅUëíñøñâ#ä óv½œ>¶z»¿|˜³-óร9•ä}µ<,ï”Åòby³|R>7ËMu’jΩ('ÕœSI¾’jΩ('ÕœSI¾‘jΩ(7ÕbªÅT‹©†©†©†©†©VS­¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT'©æœŠrRÍ9多s*ÊI5çT’o¤šs*ÊMµ˜j1ÕbªÅTÃTÃTÃT«©VS­¦ÚLµ™j3ÕfªÝT»©vS¦:Lu˜ê4ÕiªÓT'©æœŠrRÍ9•ä+©æœŠrRÍ9多s*ÊMµ˜j1ÕbªaªaªaªùŸ-枯Û*ƒšÈëhÆþÒ{2wpܺìX“ NüØ$ébˆ´ÿ¯5—V\êÁÁyÛòŒ–ƒSØúí²?aX¢·ƒã.Æ û‹;Ê‹åÍòIùþâŽòjù |qGyXnªÝT»©vSí¦:Lu˜ê0ÕiªÓT'©æÅ°”“j^ K9©æÅ°”“j^ +ùFªy1,å¦ZLµ˜j1ÕbªaªaªaªÕT«©ÖTÝæ˜G¿Ž/‡q Õ…êFõ”ºoTWª‡Ôc¥:¨&ËI–“,'YN±Ì«_¥˼öêU,óÊW©Å2¯{•Z,óªW©É²e!ËB–A–A–A–•,+YV²¬dÙȲ‘e#ËN–,;Y²d9Èrå$ËI–S,óâV©Å2/m…z˼°Uj±ÌËZ¡ÞÄ2/j•š, Y²,dddd¹?»±?]_û*ó°œÕÍÖ–¥ÄvpܺíQÒ>\kïã/ž}t÷ìéóg¿ùí³_}|q½éþ2(rßë-âààÓm«·—_çcîi_çÁq—ã±AynÞ-yXÞ)ß_Q^,o–OÊ÷E”›j7ÕaªÃT‡©NS¦:Mu’jn€A9©æ’¯¤š`PNª¹多`PnªÅT‹©S S S S­¦ZMµ¦êþ$t‹zU>)o›åÕòAy_-Ë;åc±¼XnªÃT§©NS¤šë+SNª¹†ä+©æ"*”“jn€!ùFªyå¦ZLµ˜j1Õ0Õ0Õ0Õ0ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÝT‡©S¦:Mušê$Õ܃rRÍ 0('Õ܃rRÍ 0$ßH57À ÜT‹©S-¦ZL5L5L5Çk¹(Û6‹Œ°Nãµ¥¿;îâ¸u9Ú¤¢¸æÛ'_üúó®åÉïÛ²ìŸb;8ôtËæÑp-W _÷ÇqÔ£ã.¦¹j¸ä“ò\5\òjù ¼"7ÕbªÅT‹©†©†©†©†©VS­¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT'©žO¯ÈIõ|2xENªç“Á+rR=Ÿ þt¾‘êùdðŠÜT‹©S-¦ZL5L5Lõl2xýøí|2xqܺíÃ0?\dïû¡àÓg¿ûôùÝó§Ÿ_L¾Úm®î³¬£~ºuq´ Cþ’{¿„àÅq—3­Íòjù <ÉI–wÊó—œäÅòf¹©S¦:Lušê4ÕIª¹多kÐQNª¹多kÐI¾‘j®AG¹©S-¦ZLµ˜j˜j˜j˜j5ÕjªÕT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê$Õ\’ŽrRÍEé$_I5—¥£œTsa:ÊI5—¦£ÜT‹©S-¦¦¦¦ZMµšj5ÕjªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT‡©NS¦:I5׬£œTsÕ:ÉWRÍuë('Õ\¹NòTsí:ÊMµ˜j1Õbªaªaªaª91{¿NÜõ3©œ˜±.ë:ÛÁqëz°ßD€`böÙGÏï>œìÄïw›¸<ôÝ,oœJ·Ý.1欳w1lÈ…i%”çÒ´’‡åò\Vòby³|RÞLµ™j3ÕnªÝT»©S¦:Lu˜ê4Õiª“TsßZÊI5÷­•|%ÕÜ·–rRÍ}k%ßH5÷­¥ÜT‹©S-¦¦¦¦¦ZMµšjnms>±•kòÜÚHò°¼Sž[I^,o–OÊsk#É«å¦:Mušê$ÕÜ·–rRÍ}k)'ÕÜ·–rRÍ}k%ßH5÷­¥ÜT‹©S-¦ZL5L5L5Lµšj5ÕjªÍT›©6Sm¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu’jî[K9©æ¾µ’¯¤+©æ¾µ’o¤šûÖRNª¹o­äÅT‹©S S S S=y·?Ýßæ&ÓºÓ™w³ÏQG·öƒ9âöáš~ï爿zö»‹9b^’».ËÒúzpè_’»dÚëÁq—ƒÁfù¤<Ï(‘¼Z>(Ï3J$Ë;åyF‰ä¦ÚLµ™j7ÕnªÝT‡©S¦:Mušê4ÕIª§Kr%'ÕÓ%¹¯¤zº$WrR=]’+9©ž.É•ÜT‹©S-¦¦¦¦ZMµšjžQ²Ä²ÿ?úõ}™OÊóŒÉ«åƒò<£Dò°¼Sžg”H^,7ÕaªÓT§©NR=]’+9©ž.É…|%ÕÓ%¹’“êé’\È7R=]’+¹©S-¦ZL5L5L5L5Lµšj5ÕjªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:IõtI®ä¤zº$WrR=]’+9©ž.É…|#ÕÓ%¹’›j1ÕbªÅT‹©†©†©>¾$Æog—ä^·®»xäÝúá`ða­¾§Ÿÿúù§wŸþúWs’Ç‹‘·p¶z0 ÜàÖ¾?žëZŽ»Ç4Ë'åû\Ê«åƒòý.åay—þèîÙÓO>ºûè=¿Ø‡uu1ç²11?Í––Ûr9¹ÉMagÙ+ýซC Ë;å}±¼XÞ,Ÿ”Íòjù |šê4ÕIª9u¢œTsêD9©æÔ‰rRÍ©“ä©æÔ‰rS-¦ZLµ˜j1Õ0Õ0Õ0ÕjªÕT«©6Sm¦ÚLµ™j7ÕnªÝT‡©S¦:Mušê4ÕIª9u¢œTsê$ùJª9u¢œTsêD9©æÔ‰rS-¦ZLµ˜j˜j˜j˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê$Õœ:QNª9u’|%Õœ:QNª9u’|#Õœ:QnªÅT‹©S S S SÍs†–²¬u/`®sZ”l©sÎÞŽ[×wËø?»{ò›ýÿª¶> endobj 954 0 obj 8333 endobj 956 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 180.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 958 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 174.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 959 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 180.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 960 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 643.364 198.0 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 961 0 obj << /Length 962 0 R /Filter /FlateDecode >> stream xœÅTMOÃ0 ½çWø‡;mÒæX` !„4VÄq([€I[Çhùøù$M·µtÒ£­ËÎ{γ®Úwà–H ˜,تöDU»¤ ¹°€Ú–0w»†X[vñ›¬ñ ÷,g—ìáѧ€ðÅð7]³Q#¿‹àÁó#¼°Ó”\H „ôy["pÄPkM bíéŽÒÛ»›³$Γ49MÆÃãGH¯Ø0m) Hüƒ¢Qu†JBÕga¿ˆWÍndˆíHc6þ­·JxŸõøÜ.4¯;W¯þ ÞôzüÚ«·2°©¢=MÞ?‘ò¸5Dºw\µN#]îžÈ66FDjɪšÕ¢¼¦±1Ì‹åFØ–7Œ!@ù¿EÅ«× ;Wfú¾|”ÙÓÜì,•å Å^œŸ3óÕG)ý(gùÔ|÷q*µgaV&Ÿ4ÕÿÕ ¸¤XëˆêžÜ,KSx‚‰íÙÈÞÛ…åÒÒCÊ÷|’•f0Ílñ³Â¬áÑ&‰;ð0+ ƒ5Hu@*æŠìáQÑôÙõxtÝŸQ;°­“t÷¤›Ú|—&/fËœ7Š6b?h¢l+ endstream endobj 957 0 obj [ 956 0 R 958 0 R 959 0 R 960 0 R ] endobj 955 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 957 0 R /Contents 961 0 R >> endobj 962 0 obj 445 endobj 965 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 336.948 234.0 345.348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 964 0 R /H /I >> endobj 967 0 obj << /Length 968 0 R /Filter /FlateDecode >> stream xœÅVËrÛ6Ýó+°L2‚7ˆîäDiÝq3ãšii´Zœ¡(™¢Üæï{P%‘”³q-ϸà¹oà)¢ˆÀoâm𝢧FF‘fˆ«F$¢3‰V¨™KT¸¯:¶ŸÁ>‚É}ʈ _£oßasþ‰È©:¾î:öÝyuû]8eÿ‹Î__ÿûâmHAŽw:…kå©7ȃ $Á¶Û*šL7cp$LCL?ü6›$ÓëÛÙäîËìÏ›ÙýäãìÓôËmò½7X¡7Ai«Š1‰µR„(¡Ï•þ͘>ð1@ÇÐýÆÎó,·Ûެ^ÚÎja³tWÔɃ]¦ÏùzWudÙº»š§óe^>v$묳HëºÊvµ=ñ2&(ø ~Ó¸Iqýcc·xŸdÝ“dÉ11¢SñWZåéCÑf¸ž1Å MÍZì,JÀäXU)‘8& ôpSôœù¥ÕãneËÕk䳨h'j¨XðI Ó£0×ùºt‚‚ç#h´I+èÌÚVÈå½ÑbNµ0®1%„Ù£ÅÑNj—ÊÉÓÎVÐ$ƒqI±;±Ö}]¡[ŒÖ¥uˆ›kV,E–d¸(DŒ¯†M bÆŸon‡ÿý%+vÛåiK‰¥”欅/w-åî"“„ˆ¸9Ï7e^çi|ûŽv®Œ±äÚÁh™/°+lÜÓœØG»Wùf´IÿQh -„ØØëòÆtO6~z`¿t4“?šñ‚À1~z ¿ôìâg-µ´ú=ìWØ´\¶+ö’g—³Ö›´jÃ] Ù`\˜XrÙáp—rÃÆ€W—-ØW€¡Bõ(mV*Ç müåb? ÝÛnlϹš1~¢fáÛâÁ.«Õ„nSîRRÐûçª.1 °þúˆ‰‡ (¬ûà?E}Œô+yÁQf@›ðŒÙ¿éjSŒsY×  ÊŒÖMÝW_`ŒI Å e nšev^C±®Œä XYÀÌØÏÙ“Ð9@DRÞ~kÑ´Ø®ÛwàáæìhŽ©ôo1ÿ;+\ؘ½)ëäߘ^sŽú G£¥ÚVç^8ꥮ9¢ÎrámÞEÿ  * endstream endobj 966 0 obj [ 965 0 R ] endobj 963 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 966 0 R /Contents 967 0 R >> endobj 968 0 obj 956 endobj 970 0 obj << /Type /Action /S /GoTo /D [963 0 R /XYZ 72.0 720.0 null] >> endobj 971 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 544.028 238.84 553.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 973 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 438.556 238.84 447.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 974 0 obj << /Length 975 0 R /Filter /FlateDecode >> stream xœÅT[OÛ0~ϯ8ê %ØŽs1Ò&b+Í´ÊCH)hR1þýŽã´M›–í ÒJ¶||¾ï|çâƒÁŸ©O0ˆ ã¥;£à1°ÝîÈqr‹9P@·w W·z¶Úá¢/áf¿Ò ð͸@c^ ² ×:OI_Yȇóx2ÎCãôÒJ L7)bèJ¸‚ºà[6êcpt1¾¸ Ìp|~˜“_ÁÝu0=~€ð»„[šlÊ>AÓ¤¡ÑVšáß³ÚroN¶-½VXŸoN[B[Ÿá‰æV¦¼«]·ê@ôVëÑëAd#ƒôUl÷Ƈ’n O9Rbù[ A™}°>8kƒB*îµ±«‡ûª»¥Åuµ˜ÙQÅsi6Ñc.Í—¥\d²†QZU#8‹â&«J8Kóe=ŸkÕ}4œÛ%ø¹TÃ}ù Ã[6Û¹5;ʳº1£¦YdËÙßžW¬ûh8ÒÌe”%åõmÈÃíõ ÐÙ1Fs™=Í4]Þü‡(ºo,£B¢éüçÅÕøN=ƒmHë¸;´€"ÄUQȲ©7(”Ì> ×ß]¦N/m 8€>ÚéV¹×òTóyÔÖŽÓ,‘¤©Œ›zå>h[d¤ŒZÄENê íÎ%de#e”Ã:óÐVÒj±ŽÁvð¨‡ùwtøCà$ÂÞ‰jy0ÆØ;îÕPTI–f2±þÊ…å 3¦¤·Ù <¾­Çr3*®cq=ûÇœ Þü“=Ca&2–ysÒþïp°Œ0œV”Î}_bù¬† ‹0Íše¤öïV’1×rlOnw·U)ÿ#SÌá–3ew]7•Æy]íOÃ×Npþ i²‰gy̾ðœ•ÄF¾›ß‚SG„ç ²ÒrNŒ¿Ò/ýå endstream endobj 972 0 obj [ 971 0 R 973 0 R ] endobj 969 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 972 0 R /Contents 974 0 R >> endobj 975 0 obj 690 endobj 978 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 439.156 204.0 447.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 981 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 427.156 204.0 435.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 982 0 obj << /Length 983 0 R /Filter /FlateDecode >> stream xœÅVKoÚ@¾ûWŒ8Ág~m¥TM[RµRS% UUààà5YÉØÄ6Mø÷õlÀÐô’¤ïîÌ|ß¼àÉ¢@ð3Ô‹/Ì—ÖS½GÁgÀ½zËõ€:6sa µìB¢oµ¶•p1—Px„ŸVjøbÝÏð0‚ Ï94W)­Û–}BÞÜ?…õqb]\»@ Lâ&Dܵ}ß%„º›3¡“%Ü÷¿ÞŒGw“áÝèÓ»ÏãÁ &߬Ñd§ì?й­0Tø«$3üúv•é½×!û'­*Øí7»•CnöpÇøÖGI¶z5@Œhø˜õ$ÒÐ mûeñ¦ÎOW„¯)±ƒ½Z Ì=Yoµ£Djß;>âèÂv5Ï3d ~ÞÅy†ïr¹J²”3ð­ÉˆÍ=‚GTŸe.áþÒ¨«h”ÎàØg§,ÄJ&Ñ0 —²€T%ÓÁ±²ã(_¾‡iÚïýZ窽/á"ÌUŠÒÂHŠì·’¥å‹ÞtÐeÒõ:ñ˜‹×(öE€çt/ŠÇöuMø”űŠ$ŒâXÎËb«~TMè‘a}Ò@ÍïY¤b5K•¥„Çeˆ¶Ê ÊG ë4’y²Q颰 ÂBÚ‡G¹o»èñÕ^®*h2‚‡ÍYxµÂТpâM–¾Ê£Ðe‰³Ó £8z™Ë•&b­ªrmžsÎôp侯m\¥0€¡ãÛôežgyóšÅ\nV²y+ž’á6V•0> endobj 983 0 obj 784 endobj 986 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 441.156 204.0 449.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 988 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 429.156 204.0 437.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 989 0 obj << /Length 990 0 R /Filter /FlateDecode >> stream xœÅVYoÛ8~ׯä)j–‡Î‡]4mÝb{¥öb±hú X´#@’jã¿CQ–,_›¾¤¶f8Ç7ý0 ø¸G’qX¬ƒÇŽÇ á âŽÅÀBÂ#XCGGP¹S;ßRøð‡¸‡‚: ð1øü…PTøÐ}s­ò,¸Ùñï$ôÅýSXoçÁë0 óå"!HE”RÁ %‚gîÃa¾†Ï—ÿõþz>|š¾ûóÓûÙÕ˜ÿLç#8‚ñ禡¿-2Ç_BÚJQHÇ’.èù·u(<9Þ·U]Ùº§Ä“žÄAtŸ-^ÔùéŽHœ"£$õãÉÉxá¬ÒùîñdûxÂÔ5vä°Ä±óÓÏp{y{yño£Ë ¸ø˜¯r]ÖH­<õƨ¯¥´DéÕÅíÕí•G¾k‘S"bœ3oÚ?øúƒ†Ý•¢œb¡¨K’T  ‹¼â¬,$L—K¹°f«~Pô˜BctÉÒÌ+þ®ŠrY.r[ªÚ@®%¬s4eØ{ M]H]mÊzEnó»ÜHòÿÑ1ÊH„²„u^®ÛÈdw›sÑ1‘”r´¸Åõ‡ªŸå1rs (LS¯8}ZÈ*Ç‚—¶ñÏ:OR‰$ËBÑÙ¸®á BAB¸”Z+Ý¿©eOÚ̓ì_Ìc5Ùæ©%&c½Ò GˆVaJzá`t&£ûqò˜“$Ä,:1º®äI<;«|,ÌZÙžÎwÒñT뺢Oƒs<¨ŸEd¡!3Â#ÑlóxºdèàŒþ«c‰Åž>œB–Ñ=]ó 8mq&Ø’ˆÝZ]Þ5Vš¥eOû4yz©pjú·¶úžlã𤛭-=»ù­§Í­\Ëz°¦¥iª.Õ}­ÖG ™ÍúNUå¢gȧT7Øø=ët9øÃL|»—úL Ü ãû…S˜$—-m£kÈá­R•ÄîùšWÍvšG6x¸gã—e»~ä“\4npAy†ËÕc#õÐ`aÜšÊë ´Sf^!íÉö¸ÌÑ@z6w?{ÏØ,<â$Ë(î2Ñíè™”p]Õ_dÃ=â°Ä)ÉÂÐ]&Ç/zð©¬Ôv¢åBé½á”~¯áBVÒÊ#†[§1 $<ÎÒ,é×0vþ¹6!'”¹ )I6wëó&ø(³•³ endstream endobj 987 0 obj [ 986 0 R 988 0 R ] endobj 984 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 987 0 R /Contents 989 0 R >> endobj 990 0 obj 884 endobj 992 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 204.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 994 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 204.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 995 0 obj << /Length 996 0 R /Filter /FlateDecode >> stream xœÅTÉNÃ0½û+懚±×ñh@BÔ6RU¨5‹Ô….ˆßg¼´Iºq)I¤Íx–7oœ%€ô¶¼0VÂxÆ–É&ÀHPídÒm—ft Sª¦È­F""ålÎîÙpDÎ |3ÜO‚û¬[«ï=xöúoì¦dWwBùZHe\å–e!çJz•fVÎ`xÑ)‹²hõŠÛç^§9‚òeŽòàtC¡ÿ@²¤ÏðÀtá3lzj[°³WÖPPEYbmïš&Ú’ŒD5â‰ò$¬``Es-ÎZüôF(ç]Òž\€3Oí€H_{‡G bsD X\“@EL}çàzº^ì€Uy³r!¯ÝŸÜ—ùÚ­6­•/V“õÑqQÞLþ5ï×çäeãŽäý°±\ ºÜF$ÀO‹KñGˆ§Þ*ž£¤TVoCæŽ×JvÙ5Yú endstream endobj 993 0 obj [ 992 0 R 994 0 R ] endobj 991 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 993 0 R /Contents 995 0 R >> endobj 996 0 obj 362 endobj 999 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 521.156 150.0 529.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1001 0 obj << /Length 1002 0 R /Filter /FlateDecode >> stream xœÅTßo›0~÷_q›Ôx¶Á€³ŽM›ÖNQ¨:©ê &A"ÐÙšÿ~g›ü Yº&äÃg œA’ï)”dŒùDÔÊ<’%<¼‹Æ×wI<ºþqs3¾ýôþ’o$Nx<.þž‰íÁ°Sø…ÔŽz>Fd°óï½¶ ç|èqµM¨ìçÖ¯®g:ñ~‘vú—n@»dèô‹ž­»¢® Î­c:ùm‡;—ºê`‘¶€1XW™nÊMQÍ!K»ô)mõ9¤Õ†nû8 #©ÄNTÈûnƶ ÁÓæ-ŠÓˆ > endobj 1002 0 obj 554 endobj 1005 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.09 210.0 82.49 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1007 0 obj << /Length 1008 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_qЗ%@¬‘")JZ Ò"CP4‹·¢hŠA±èX˜,%’œÖÿ¾GQoÖ‹kdXБҽ<Ï”žfþæú"}–›ÙS5GA:ÀÜjJ¸@¹íØ@% ˆõSÁ©%¼˜‡PXÇY2#ðvöé3Þ  Â—é›+•og7ÿúùáþ <Ì~[Ì~}#€X¬ZŠ\bKéû¾'=ðlæøúÏÅ>ÜüuùçÇÓϰøcv¹ØCÁ¨óPÜ”1”a—¹uð_Úe‚÷nNöït’ßÌ·³¥CfæpÆøÖ·â*[ÕÕbDƒÇ\'q風¯†ê|º¤V¤ÄööJ€26Y?˜µA"µï¢éâÂ^E*çI°Q¹A5ÂÅÚìëÁ)0Ëæ$ʱ6à 8Üö<—*ü¥Å´_F¦Õ¯÷»F Õ*ØÆE3þ²Ž–ëf´QAÒ[¬ƒ¢3Pœ«eš„Íð9ˆ·íÍLÛ,Qáü ‘â(om§«Öt‘EÉCÞ±ö˜©\%κ©rH²‰rî0Û‡“eo7%žj"W±ZehÕLÉL%×$‹‚r\þÒE/#.Ÿ¶*ÛÍÕWg¥Éd®Φ­ØmW«cbr„´}*ñš;¦f™v1i¡!ʇñ ê—1×&®ã{ÞºwW×Óa~@ó¬õ½—Ûª~ªQºêg½—$tÑ Ëˆ96c‘ÇŒ×$- ©ã ‡ª’/KݞΠh $!.­rÅã$|9¢¡£Åôºp²òv´b»Œ«‰z VCCˆ‘§{ޤ¶ïaAú‚ƒ8”3êù4[×uw©†u{©†UiFøq-!¼.ölïnÓbêÛã4ÕU2$EßÉí«ÎÌ›ë‹Åûam¸¼‡Î,É«—¦V¡‚ õ§›¹Ë¨ÕNƒ²ñ–bšÄ»VVµh¸«Gm¸]Öôx•fµ¨“&óØ2Íš‡º-Sïw}ôÃEÀ¶n«OC G÷KNÄ3guUÝ´ÈÀX3Ã|J·g¨»Îì÷š°TÐ5Ò¬u†ËÅv<ž½(5zÇö8ö‡UMëòk°yŒÛÖ;(Œƒ2iS½ss—­;C X†sPh# ÏVQ–ÿè.vµ´VÑú€U–nÊçÒRðe­p•5xÔº;â§Üïù}õîÐ9ëï8£M”Y`]«$J, ¶.w]’»Ó»S$}hÐ¥=ƒhÐ2q ©(ãQzâgg ‹ßO ˜¿óΆ IÅìÿÀìˆ9Æ~ï3?AÁˆª˜bÏ,Ìy±{<@Ÿ;AŸ…qŽh5 Zú?…@F^L £GøËÝÉy” çaº½Õ8x”zIENߣ³!ïk¯AXH…>A1êÇíóWm]$a–>¦Ïðïh0QÉ¿)ÊoÓìw/¥ç?*ìþem¼ßâ ƒ5Þ°˜a´­i,,Númî…ð)«Nûì6Uc¨Óqެ´Q<ƒýinÎ|{Ov ãåû;#—Âvži¤Fó6 \®VÈ×ô‹‰ö‰Ï–x¾ô„Ñü€‡Eõ¬2PFô¾¯¾ª%f:Mô†­'no®ÁdEŸœq^On“Peñß ! Šà>ÈÕD¸Ã'»#¶woæœqß—Â5¡\”à‰á~wƒà®-¹ô=áU¼½ÃSÚ1%¾(2Н#DÖŠ¥zÔ8ƒn£bhù ¶à9¬"ðjõ=Êb„Èkª‰•ei–Ÿ¡lÄòql??ÅóšÆ¹¹…gÌ H5_¦› ˜;£ôï×X>Û endstream endobj 1006 0 obj [ 1005 0 R ] endobj 1003 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1006 0 R /Contents 1007 0 R >> endobj 1008 0 obj 1421 endobj 1010 0 obj << /Length 1011 0 R /Filter /FlateDecode >> stream xœÅM³Û¶ñþ~IFb‚$HßR×é¸ãiÆã7ÍÁÍ’(‹DÊ$ågýû.°ø" BozHmÏhw‰‹Å~ð×'ø»?¼L¢ýå髢ш'Ë)Ë#šÆI]"gÑY´r€DCðƒ8E¿=µO$úûÓçßáã!"ÀðòDæÝIæOOñÅò§O¢/O}~úË/YDIô|´*ÊÊ8Ï3B(ªˆYRŠ?Iô|‰>ÿðé݇woŸü=zþÇÓ»çÉ4MþÓø(erËÅMàå O>d)™~qVßÐ-UÈ[|:«åR¿(‚8ü]±Ó î,¦æð§¾n \0R ¬X5€?Yk‹…c›ùÀlfJ‹…E›ú|ضեpV=Pðs¾Ÿ£#Îbý°ëºs]µiÆ“A*êcu;ÿVoµÁº£µå\Œ$;MBRV.äy^•>nWÙb3ìo§º},#ð=çÀò¥NÖe`¤\gÛ˜aÇS3äxk÷cÓY¡úz¼õíàÑíPï»öðXµ 8YØ„ÌÄ97ƒX¥4ãCf¥¥LZLlP¥=DÖWñ˜–à[9K–ÿóý‡õEÌ²çÆ ­4¨$¶T³iÏwƒXuêµµÛ:Ý[êšžúîeˆõD¼{Úñ”B)CùûúØ×Ã)¸LÏ8ÕmÉ\‰ê~R³VXÊÐê¾>XÚ ®žÂÞ~øõ“ýûO½îªÞgW7í‹õׇؒ~v£§ða–Î&§œÈÖúvæD¶KßZKß>p"Iç¬CÊørØ  ¦y€36C«­°U;º~,¬ÛhÝó€ä)Œ˜æÙrø}µ?ÁJ¬; " p›Ñÿ¨ï/]08šQX°”±¸(Ó²( ]v½îÁø6žÕ7·õOž/)KÎ(ò¢/d"zþP½5 øº iu&´ä1I‹²ÌJ¾ìm{Ý<@ ëÌfð}u>ä¥qôGE£@xgkoMýb»;WÃ`°¦ƪÝÛ¶jóÆ† Œs}þ L^Ì$è›x±dã¥Æ!¸>lQÄ%‡ÅJºìjÝ€h™ø6fà7$"ù­LršV®¿ƒoGǦ¦¡k9Ñ "|»ªQúSõÍ6kk`ªþÒ{G˜Ûþä1è’Ìæ²¯†zØD÷î]ª{ôÒ §hì¢î[Ý÷àË#!û©ëþˆyK3 X®EÿzzÛG‹ $ÐM8êÁÖŽiy$b¯sZBK.÷r(Ó¬OEÌù ‚"“˜‡$òQOqš€‡8®4Â:Ü!æF;¤ül[š¬XͳÔ4ÉfÓ“î.Ë¡"s£LACÂë ˜4å°d$ó ÷“d«ã§õB“PGñR–|ÙE*JkÎ=]¼ýðéãzüe©`.1^,™íðb&r§j5Ù  Mkáj¿‡€'Œß·:"_Í`̤˜¦%‹·yÛ].] °¤¦ëþXíë7–VYÐdí Ÿ„*E[ßÐ1ª€³”óA¬‚,&ÀlGWÁJa*Z)Ì„+« ŸÓr&™e2„aè2!K‡ª°á4Îr.?KuxÀzÃ.dÁ$¶iBãÒ$ñˆôõºýã&G".²n0à~Dt¨-ÜíÆªiÑ å—®7p &i{¼]϶OiŒ¯jã¶ëzskZ°ÙôÁ8.ÂÊ`hY/ %l¢—SBÚŒ`>Ǩ’ôœŒ°![5Ž}³»°€Â Ø„1!³p 'lM:Y B‚I8|(3”äoõ°ï›«(ÒÖcNu#82’¨‚ïÝ÷zrÈ=Ø,Á¯·º¿[TÖ ^7.ÊÀŠY¡-£Ëñ ¾W;ÂëvVûFI 6‘Ô²AOÕ`‘Ê‚ŽëG‚qýˆ¢ëGظp-åOÎxõÞ7Pº,iw·°raˆï;ѽØÁîdêïb— °d2͉™Èc®×3Ž!ñÛ ’'¨ÄJ€}}Mâ|«ú/7aЦ'¹$´¾T‰ˆ¨%d!ŒæKñ Ëõ“¬ ÑuV™£Åi)F­ÁuL¡äP¾p^.»z䀳$À¬Uàœ_H|_pW[][½CN¨ /u;/•ÄZæt¶–=$®‘Ø0 nç]N[£ z樃6­Hs!jõwãª'_ÃB“Rù™í&‰5„!4I$¹oã^DFLÞàš RÐÌï^ö}w¾]Z§­JÛ aççÓ~DÙZ‘„fË0Ü/>¥—ÙL'»îÜìKúlÌ0JLv†•^CøÞö‹ù0‹UèþVÈy¡ìþ^–€’ö|¿šï—î }ü½!µ‡f_Ù.ÇS5.çÈŸÍQ9ÈRR弋;+ (Ǿ»XlÂ<ñ`Hµ¸:’Ò[¨‹&½Ë}ñʾ!è]Ö ­Ø¢Ï.³sX¢Åð,?£åL5Öv·)‹«+ LÌE(7±ìâòz@"IˆuóšÑ)¬*Osé.–]dpr4Ë쯓 'q™0U¤ @®¼ç($ey V‹·“ö(=sÌ€°:^1¨>fÑ}.²ätÎEàž‹¨æïªh,Þ5È·K±%%q;²YÁmGüPƒzÕA†$ü ï¸y+. jÛZndÂÁ·Ì$7‡BynÏ×Ög¥öcµ;cÚ€hg@Ö%*—QwØX½NˆÞ@A5À3Ÿ¸ÍÓF3¨}Ò„xe IIS) *E#òV=&@̽óFÊË©s&oÒ=ËÕÒT<ëñ)C=ZDŸú$΋…¸gYŠdO‘W‘|ÉÛ×âNÏi‰~ž–ÓÓqü.ì ¶ø'˜æÖæľ®R‚Zð\©ÎŽ|W‘ÑË®(k–Ë“™Êð¤wËÅ©’<`D°¾\ÏÝ¥•Ì‚$x­úÑ ¨îœwIØ­v$A•;꣨w ªë*‰4­·¿@Í 5ožS>7õÌ/\2d6Ã;p¨ åþ¬¬ÝBÔå󥤌Å#¤2)Ï`6%8½÷ƒw€E:kÿèýEIJ"ÆGáŒ]%)n¡& æù~„èúÍùª8³—èÄû™pe&^„$%ó ÷À)„ˆ·ïéå·¦» Xƒˆ«ÁºÖóh†á†×Ù{œIî)5J¨ìËTÜ€&žÁ™¶(3ìF*­Êþ&£-3õŸ€”©PŠäÒf²\Ҍ̣©›½CÂa_¼"b{鯃…Ís/KÒ11å=qrÝW{Xi+χÐs«~íå ¢¬W]9ñÌsþè«>„®à³dÖa)„iƒ*À¬!ÔA±z‰ªöY%`”÷Y>ÐÚ3+âÉœ3ñÔ9Ï0£´™ó–f2vø1“Ä}o¿ì*âD<¨–ÁÂ>°d6Ã7vVpeÏ8 õ²_!®BýppÖÑBUxÆ„°:cÒ-÷úv3vŽUÔ endstream endobj 1009 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1010 0 R >> endobj 1011 0 obj 3635 endobj 1013 0 obj << /Length 1014 0 R /Filter /FlateDecode >> stream xœÅWÛnã6}×WŠf‹Æ%)R– lf‘.°› b´X8B¡Ä´MX½”¼iúõ¥n–Dd=¥NŽFä\Î9Ù_‚°ù»Î—錢ç½óµò4¥Èó+÷aÊÑU6Gq¾«eÐÚ2K¹É[ô—“8}t–¡¹¹BØxq°®8üàÜ·òçwð›çÇhãÜ,œŸ~åˆ`´X7ñÙÄ÷9ÆØL<:Ë?-öhyõp{wûañ.D‹OÎí¢Ó†GèÿÐÆ}QCQwA.5ÿÓIÁpçg¸{§ÅþÉßx‹„^é3ž2w~+®èªÖ²Ò,û)×Þ>pÓnwѕÛ&ïWÂ4?Hð$èh€x³^¼1jgDæ¹OýÌì~X šç½ø~Ù ‚>s-Òcœ]g¯‘¢Dƨl¸ˆâ‰ç›‡ûd(’Ò+¡¯Ÿ^Ñr-uš]'Ñ^„ïÎãyÔŠ÷þgôxåÞ(-S¹ŸT*Öfý¬’4‹’L&æâN¨z‘+cü&wÛHÆÆú]îdãÏ8ZɽÔîyFÆ€Ü/G-]¨@?°¶?^¥"ÏY§5´|VÇÄø~C4_kevŠý!V¯B„çAƒQ(Ž&efƒØ °Ñêx°¹8B0Ì0£@âEYK¯Š³E/à„Úˆ’h‰‚¢r‘Ô⨯;"©•XÚ—…hÈ6a3æ\£±:ÒIkµã¤9äÒÊU¨ªÜfómÈqÅÑI[¶žéì'ø_¶B [îDÏ4"÷;¥7.De`q&…¦HhRÀ"·5  zÔ€¢°Œçë8Ê(ƒx ž^9…~IVZÔ7Cáÿn‘› ˆ‰HvÊØ•~Šž·…ÿ³>¦•y'’B„s1 ­ûEqqn¡U–î^õEÄYj|`ÙSZŒõ€{Ü–Ï>ú§TŒ\ Â-`V°¾T ŘùbŒ ßÃÁÈB:j˜GÇLÁolÅ+È%ÜÌlH£o´Ü ¹Ùf¤'\Æ 9ÛH•EMx`ÞÒ<`+¸¼Àî¥)¯"{xrÔà}³Ÿ˜÷2DÃÌW5†I-ï|¦ýœdP’yšÊ„FÓy炪fÔæßîÍÓLËd3J׌ÙõÈ µÀ!­gÉmhúC^Ö;óG>xÃ3ŒMAEõ¼ç8¾,¤sñ4ƒ¿ÞD&Á©qN”Éö$²!óÍ©%Iæ×¼6Ì÷Yc…ÀK†Ó‹à €{—æÖ ôœÙŠ-fd~a#ž˜Ü½ðazgv ±Lš€ß·J‚ ìÞßïÖ£ÄâŸÍæ>ÖÀ¯æ8¢,Ü‹Ÿk÷ÎÓW÷ endstream endobj 1012 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1013 0 R >> endobj 1014 0 obj 997 endobj 1016 0 obj << /Length 1017 0 R /Filter /FlateDecode >> stream xœÅTKs›0¾ó+ö˜¬Ha¸6ãt¦ã‹ÇÌôÉAÓ‚” ¨ë_ 0œ[j<£ew¿}|»èÝ!€Í³²Ç:¤Î{§#°¦àúŠù@> endobj 1017 0 obj 598 endobj 1019 0 obj << /Length 1020 0 R /Filter /FlateDecode >> stream xœÅRMoƒ0 ½çWøØ IøÌuÒ:išÔUCÚ¡ê!£´e‚¤-Tëþý¡K ãÚ’gìçûˆàæu”‰…´DÇ#Qð B ¾K(¡ó(Ô_–C¯^côO³‡w$†'´Z7Á à&á áa¹6ù --~ÁwçǰC šÍ ’­¹¢Ðw™ï3ÆB±ëQ¦ I «ÉËbñ:]CòŒ“žÐ±l{h»nGK›/rÛùöûkö¿¸A[BOc ¢¹U¨è†ÕY݈vµmGu`#Û*úËpWòñ=ˆT"ÁnÜÛ⇣ pç[»¤â×ãÇ7ëœì3˜‚ãÇn“ìRgb“m ¢…ÎælXŠàÀ ›N†õ )פ~BÙŸI†¯ú5¿˜s^?•e)…9óô$++^ÛR¶g‘Ö¹¼°„¥L~|fiíÈSž‰Ú–¼á57§’‹üp.¸ªeЂ G«´ï–â®Ý™ï²Êµ¶e‰~ï *‘ endstream endobj 1018 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1019 0 R >> endobj 1020 0 obj 382 endobj 1022 0 obj << /Type /Annot /Subtype /Link /Rect [ 510.0 616.382 540.0 624.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1024 0 obj << /Type /Annot /Subtype /Link /Rect [ 137.251 604.382 227.251 612.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1026 0 obj << /Type /Annot /Subtype /Link /Rect [ 290.955 604.382 326.955 612.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1028 0 obj << /Type /Annot /Subtype /Link /Rect [ 174.44 580.382 222.44 588.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1030 0 obj << /Type /Annot /Subtype /Link /Rect [ 227.44 580.382 281.44 588.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1032 0 obj << /Type /Annot /Subtype /Link /Rect [ 407.79 580.382 431.79 588.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1033 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 512.486 293.87 521.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 1034 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.392 512.486 541.392 521.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 1035 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 500.486 234.99 509.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 964 0 R /H /I >> endobj 1036 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.774 500.486 541.774 509.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 964 0 R /H /I >> endobj 1037 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 488.486 204.45 497.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 1038 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.974 488.486 541.974 497.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 1039 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 476.486 208.89 485.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1040 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.944 476.486 541.944 485.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1041 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 464.486 207.22 473.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 1042 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.955 464.486 541.955 473.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 1043 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 452.486 222.21 461.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1044 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.858 452.486 541.858 461.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1045 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 440.486 154.44 449.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1046 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.298 440.486 542.298 449.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1048 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 428.486 186.66 437.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1049 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.089 428.486 542.089 437.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1050 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 416.486 156.67 425.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1051 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.284 416.486 542.284 425.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1052 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 404.486 172.21 413.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1053 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.183 404.486 542.183 413.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1054 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 392.486 146.11 401.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1055 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 392.486 542.353 401.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1056 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 380.486 179.44 389.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1057 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.135 380.486 542.135 389.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1058 0 obj << /Length 1059 0 R /Filter /FlateDecode >> stream xœÅÝMsG’‡ñ;?Žö„‰­ªÌªÊ²÷iùýÒé e½l,Y?w6(m«R÷»÷ôÅë_<ºA’FÛ¹^mîŽ;ç«»6÷«^}XÞnµûgsë·ÛÕÕÙL‹ë›“›Õ»ÕÅÍÝC¿ŸÝ¼½{’·«O}¼¾=¿¹ÞßÌœÊÎv^þ2Úæ»çþI7 ®V7·WÓK`³ädëÑg×ïïïÝ||¿º^Þß_oËæÎƒno–­>¼ý¼~lí×7WcÇl-xwòñþÎÏ«íÅ^Ü^Ïf§ÜõìíVøîõç{”ÌížØ%?wæqòš{åÊx9æéZ§¤q¨¸Ö™ul6éðôòÝ8Vß<Ú\c59¥žæºrßOÇÉò~ÙútñG-Ù–^ë8ñ™Ì<Åõ8:Noí`©ú¹Öûüæ~ÑtnÚܾÙîëå¸wu÷íØC[ÍNÎÏ/¿ÞZóåÕ#ë9ûãæêöôpæ@)m§«›såaïl‹Ía³¾½uجœmï’õ½ÛëõÁ¾¹»éÍúÎõÇw?_žŸÞ/ÙBw_Üœ|XÞ/x~6Îîç¿ÙzÞqç·o­tçLÿHï?ÞßÝœ:¶V:w‘8?7CÍuó2¸}ÿþò*Âx›xìµÇ—êxã,ª3+ysyøùã-×ô¹öß|æ™Çò™–ïNÞÿÁS—äŸ[Á"Žú“‹ÅêÃÍê"Þ4OÏOnÇé?^|“òc©Ëîc½VçÖ{~yùþñ·ÌêŸk»xwrzu¹¼k>Ž¿ñ‰uR~°–ñ1ÈKg‘Z6Mãýj1^&O/ÇÇ‚‹»·’ùS`Iu)*ãT6>OÍÿòôÉÓÿ9:<~ò×G‡?þtôêׇۣώž?ùéÅñ_v^Ne|š²¶yßß_U¼›/ÛÝj«]]¦6>¾¢¸°xcqGñ(’8SmLµ3ÕÎT;S5¦jLÕ˜ª1UgªÎT©–„TKBª%!Õ’‘jÉHµd¤Z2R-©Æ2gªÂT…© SU¦ªLU™ª2ÕÊT+S­¡:>ˆä^¾$Þ2‹+‹wï‰Å…Å‹;Š[añÊâLÕ™ª3UGª1† Å‘jŒ!Cq¤cÈP©Æ2/H5Æ¡8S¦*LU˜ª0UeªÊT•©V¦Z™jeª©6¦Ú˜jcª©v¦Ú™ª1UcªÆT©:Su¦êH5Æ¡8R1d$ž‘êx€Å‘jŒ!Cq¤cÈPœ© S¦*LU™ª2Ueªãí@7¿ "å·¨ zQOsO“‹ÎTchŃØO?<{r|ôhe°-Íâ÷Ýâ3m§®ÅUö*ƒñw»–7›´×n¿',ÞXÜQ<þnGâ•Å Åãïv$®,ÞQ¼3ÕÎT;SíLÕ˜ª1UcªÎT©:R- ©–„TKBªñ+UÏHµd¤¿'ñ‚TKAª¥0UaªÂT…© SU¦ªLU™jeª•©V¦Ú˜jcª©6¦Ú™jgª©S5¦jLÕ™ª3UgªŽT%!UIHUR•ŒT%#UÉHU R•‚T¥ U)LU˜ª0UaªÊT•©*S­Lµ2ÕÊT+SmLµ1ÕÆT;SíLµ3UcªÆT©Su¦êLÕ‘ª&¤ª ©jBªš‘ªf¤ª©jFªZª¤ª…© S¦*L•Õ–”Õ–”Õ–¦Ú]ÏnjȦÚÝærL3íri3µ»x/y{vôâè3µ»º,%®–TÊLÛM×lfTŸ-›o.ð¸ßn¿º–Y\Y¼£øxwFqañÆâŽâãÝÅ+‹3ÕÎT;SíLÕ˜ª1UcªÆT©:Su¤ÃôP©Æ0=ÏH5†é¡8Raz$^j ÓCq¦*LU˜ª0UeªÊT•©*S­Lµ2ÕÊTSmLµ1ÕÎT;SíLµ3UcªÆT©:Su¦êH5†é¡8Raz(ŽTc˜Š#Õ¦Gâ©Æ0=gªÂT…© S¦ªLU™ª2ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;S5¦jLÕ˜ª3UgªÎT©Æ0=Gª1LÄ3R°8Raz(ŽTc˜Š3UaªÂTYmIYmIYmIYmi]êknÞçâÖÓ¦R_U·VûL»\l¦Ô×v/ wô·£§?>}ùÝwO¾6S÷ŠëŸ§ÖóLã©oeéûµ¾(€“PêÑ·½v³0w‰W7‰+‹w‰3UcªÆT©:Su¤:ÀH©N0ÏHu*€‘8R ` ^êT#q¦*LU˜ª0UeªÊT•©*S­Lµ2ÕÊTSmLµ1ÕÎT;SíLµ3UcªÆT©:Su¦êHu*€‘8R `$ŽT§‰#Õ©â©N0gªÂT…© S¦ªLU™ª2ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;S5¦jLÕ˜ª3UgªÎT©N0GªS Ä3R `$ŽT§‰#Õ©FâLU˜ª0UaªÊT•©*SX1·ÚH)ê_VcâáÙÚT–4Sÿê»×¹‹ù þ¾´­É÷[LS¦ÆÏ±÷zdm™âW­-®Ó½×nw³ÍIzì’®(m$SfqeñŽâ9±¸°8Í‘æ‚LsA¨9æu´qjL8òÇñ˜×‘Ä•Å;ŠÇ¼Ž$.,ÞXÜQ<æu$ñÊâLµ1ÕÆTSíLµ3ÕÎT;S5¦jLÕ˜ª3UgªŽTãgÞ(ŽTãgÞ(ŽTãgÞ(ŽTãgÞ$^jüÌÅ™ª0UaªÂT…©*SU¦ªLµ2ÕÊTëúÓ’yÌ üÇñ–X\X¼±¸£x/,^YÜPÜ2‹+‹3UgªÎT©:RŸy£8RŸy“xFªñ3oGªñ3oGªñ3ogªÂT…© SU¦ªLU™jeª•©V¦Z™jcª©6¦Ú™jgª©S5¦jLÕ˜ª3UgªŽT5!UMHURÕŒT5#UÍHU3RÕ‚Tµ U-LU˜ª0UaªÊT•©*S¿„ªm&a¥f­uYÜÆ÷„\gf™›½Åv/åøÃ«o¿?>œ+dzÆlÅIZ›i8ul|uäçøÒ[RM)›Ì4ܯRfWï(>¾ô¢¸°xcqGññ¥Å+‹3ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;S5¦jLÕ˜ª3UgªÎT©ÆìÖ(ŽTc~kÏH5f¸Fq¤s\£8RY®Qœ© S¦*LU™ª2Ueª•©V¦ZCõîw0_wo…Å+‹Š÷ÌâÊâÅ-±¸°8S5¦êLÕ™ª#Õ˜ïÅ‘jÌwMâ©Æ|×(ŽTc¾k/H5æ»Fq¦*LU˜ª0UeªÊT•©*S­Lµ2ÕÊTSmLµ1ÕÎT;SíLµ3UcªÆT©:Su¦êH5æ»Fq¤ó]£8Rù®Q©jFªZª¤ª…© S¦*LU˜ª2UeªÊTk^ÖžÛ¤¢Ê¤Öí÷^Ã,u¿dÍÆ^½8zz¼“ŒŸ2Ä<;–ûL“»*îþÕ:cvœ×óqî·ÛÝò˜Ü¤¥;Iç˜ÚƒÄ…Å‹;ŠÇÔ$^Y‘FùÅj”¿I\˜ª0UaªÂT•©*SU¦Z™jeª•©6¦Ú˜jcª©v¦Ú™jgªÆT©Su¦êLÕ™ª#Õ(£8Rò7‰g¤åoGªQþFq¤åogªÂT…© SU¦ªLU™jeª•©ÆÔ¹¬'…ü’¸£xLíAâ•Å ÅcjWï(S{¸°8S5¦êLÕ™ª#Õ)AâH5Êß$ž‘j”¿Q©Fù›Ä Rò7Š3UaªÂT…©*SU¦ªLU™jeª•©V¦Ú˜jcª©v¦Ú™jgª©S5¦jLÕ™ª3UGªšª&¤ª ©jBªš‘ªf¤ª©jAªZª¦*LU˜ª0UaªÊT•©*SF oVÕš§Ã6²­ÎÕµ³ô™òwÞ›êåüpáéoV1Ÿ{škµ.ÊûÜ„îãðµTRÊ^gΕ†QÜQ|¾(^YÜP|¾(®,ÞQ|¾(ÎT…© SU¦ªLU™jeª•©V¦Ú˜jcª©6¦Ú™jgª©S5¦jLÕ™ª3UgªŽT£4ŒâH5JÃ$ž‘j”†Q©FiÅ‘j”†Qœ© S¦*LU™ª2Ueª•©V¦Z™jeª©6¦Ú˜jgª©v¦jLÕ˜ª1UcªÎT©:R¯)(ŽT£4Lâ©FÅ‘j”†I¼ Õ( £8S¦*LU˜ª2UeªÊT•©V¦Z™jeª©6¦Ú˜jgª©v¦Ú™ª1UcªÆT©:Su¤¥aGªÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÊjKÓPgÏ)‰TUZo¶ñéI|®aÖ™«CL~{ñòå;¹ñ±9Çt`©å™ëâs_ö½ÏÏÝzJãÉL»ÝíŸIZPº¡´“ôøèLÒ¥¤ãÍ(®,Ž8ãÍ(Ž@ãÍ(ŽHãÍ(ŽPãÍ$.LU˜ª0UeªÊT•©*S­Lµ2ÕÊTSmLµ1ÕÎT;SíLµ3UcªÆT©:Su¦êH5®ÑŒâH5®ÑŒâH5®ÑŒâH5®ÑLâ©Æ5šQœ© S¦*LU˜ª2UeªÊT+S­Lµ†jsëò%é–PZPº¡´“t/(]QÚHÚ2J+J#KG–Ž,Y:±Œ‹2“4±ŒK2ƒt&–qAf’&–q9f’&–q1f’F–‚,Y ²Td©ÈR‘eE–YVdY‘eC– Y6dÙ‘eG–Y²4diÈÒ¥#KG–N,5KMÄR±ÔL,5KÍÄR3±ÔB,µK-ÈR¥ KA–Š,Y*²Œӽބõ™øãE먢K-1áÚÜódÕ™*ºì^Šù»'?<2dºßÏ2¸ßl]ÜoK›¹Âr^¦d)3 ÷ žÊâÅc– o,î#ÞÝkË_Y*H¼²¸¡xÌRAâÊâÅc– o,ÎTSmLµ1ÕÎT;SíLÕ˜ª1UcªÆT©:Su¤ZR- ©–„TKFª%#Õ’‘jÉHµ¤Z R-…© S¦*LU™ª2UeªÊT+S­Lµ2ÕÆTSmLµ3ÕÎT;SíLÕ˜ª1UcªÎT©:R•„T%!UIHUR•ŒT%#UÉHU R•‚T¥0UaªÂT…© SU¦ªLU™jeª•©V¦Ú˜jcª©6¦Ú™jgª©S5¦jLÕ™ª3UgªŽT5!UMHURÕŒT5#UÍHU RÕ‚Tµ Ueµ%eµ%eµ%eµ%eµ%eµ%eµ¥iPskn-Í•K¯{Nƒš¥¦ä½Ï4̺¹€ÅÑñÁã¿ÿ~})ƒ endstream endobj 1023 0 obj [ 1022 0 R 1024 0 R 1026 0 R 1028 0 R 1030 0 R 1032 0 R 1033 0 R 1034 0 R 1035 0 R 1036 0 R 1037 0 R 1038 0 R 1039 0 R 1040 0 R 1041 0 R 1042 0 R 1043 0 R 1044 0 R 1045 0 R 1046 0 R 1048 0 R 1049 0 R 1050 0 R 1051 0 R 1052 0 R 1053 0 R 1054 0 R 1055 0 R 1056 0 R 1057 0 R ] endobj 1021 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1023 0 R /Contents 1058 0 R >> endobj 1059 0 obj 5113 endobj 1061 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 186.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1063 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 168.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1064 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 174.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1065 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 674.1 144.0 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1066 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 662.1 156.0 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1067 0 obj << /Length 1068 0 R /Filter /FlateDecode >> stream xœÅ•ßo›0ÇßýWÜãúïlcŒ_Wu“¦j+ÓTU}@ÛFãGD]þûÙ˜&@)/ ùtö÷swÜ…ì´÷Ê-JsxÊÉ®ó1PDعd, \B-!s§z·ìâYã~“‚ |#vs hoǸV|Gâ^|·ƒðB¾$äóW !y>½¢©RZëHEQÁµ»8$9<|ŠÝü¼¿z„ä;¹IUÆÿCq›C›vÛ[nEÛ6d€Ã^óþ“· (¼Ïz|l·•uÝêVŸˆ7}=~­Oe`¿Šá4\4øü ('dH£Á0ÌÀ…ßÚ‡F»D~"êq…øaÀ·Õ¦hV»½©“UZ&ãçB×å2‘çót»Œô_´sYYnçhö9“V›Ì<5=ÞQ,€Ùß[„ˆl̨r³¦˜ðecjϘO× ÔÃТ"í%É«w…=?þ´…¥,PNhŸ7&[¯Š4_Ê_B@Z¬â3Éh ­ZzB]™zŸ5«æ°]È€s±Ä€?æðVVkH«—}nЦ¶–ô˜U8ÚÆQ &€×·wñíl6B:±û³P“Ù˜¿)êMYÐÞ,ÄäO˜$ endstream endobj 1062 0 obj [ 1061 0 R 1063 0 R 1064 0 R 1065 0 R 1066 0 R ] endobj 1060 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1062 0 R /Contents 1067 0 R >> endobj 1068 0 obj 474 endobj 1070 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 427.156 150.0 435.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1072 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 415.156 168.0 423.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1073 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 403.156 174.0 411.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1074 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 391.156 144.0 399.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1075 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 379.156 156.0 387.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1076 0 obj << /Length 1077 0 R /Filter /FlateDecode >> stream xœÅUÉnÛ0½ë+æØ5ÃE¢ÈC‹&…¤KÇn‹ ÈA¶h[ˆ,:’œÆýú’¢¼È[âKJà`ÈyÃÇy=z°ùµìJ ƒ‰÷Xû„¯]â#Àj;€ÔîZ3èÂ2“ÛdŒ1üö2Ã…wwocÀ&à‡7áªà®×YËoWð›çÇ0òÎzÞÉyCo¸º"ßGœK) A F¥z¸{w}syÕku~¶onßßCï«×î5¸0Bÿ—Nu†êðU…©ù‡¨*sc!ðqseMKÿÊ[%dÎg<.·]JëšÕ³;ˆ37ïåW4ð:‹¦&Þ4ù~9„6`$B ŒïÀßÚV!mî%¹%oaUX.œ;2Àw¥³$;Îrõwœ©'€~m}.ôS¢J¤ó€£½G1b›Á‰Ãã·³<7N³8×Smð¢ÚzÑ ¼à›ÎŠ2ÊÊ$ƒ/c•g*{Ð0XXë€ÛxæA7ñÀäa%©=ß…Îû‘z‚ÑÂ:Œð > endobj 1077 0 obj 738 endobj 1079 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 225.156 150.0 233.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1081 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 213.156 174.0 221.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1082 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 201.156 186.0 209.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1083 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 189.156 144.0 197.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1084 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 177.156 156.0 185.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1085 0 obj << /Length 1086 0 R /Filter /FlateDecode >> stream xœÅWmoÛ6þî_qð—8@¬’z¡¤viÑ.ëšÅCQ$ù@Û´­E"½¤õ~ýŽ¢lËzqšËl:¾ÜŸçNÇóÀÁïX?üІY2x¨æ(ø68¬šòPײ=H ’=ˆõ®š`o%|˜M(¬àË@¼ÜÜáâ*|¦¹RùzpUó¯WÈ‹û'°¼™ ^½ó€˜,öyÔ Bâ2,ÇõdžI7£_~_ýyñÇ×Ó;˜|\L€8Ôþ€\•g(O^†×ÆŸo•1>Xð\r¸R‹ÿn~?[:tÌÎßz)®V=ÍAŒhð˜g/²‡Aê(âE÷炯)±‚ƒ, ®Ó›/ÌZ+Ú÷OØÄã:¥=…1æ§ŸáÓ‡Kƒ§¾Ï±-‡á[@5oGs5~(Dº[d<æ(JžˆÛSf"³Ì왞…EªÈ¢d‹áíiÛƒë6<NE^¤…™’8Ñß¶5¬  ÛÑê)‹!X0üGgð9iÚ}’€´°Æ"/a¦"+âNPî9@Ø$JÃ8 ªâè¦âè&æY>Ö“wðº$éF Ij#Ä]Û<%mšú?¯U:éxº©{¹ë:6¥Mâ´þíh]d«’p0лAS;hio÷wìv›› }qžErÃIªòì~ƒÒuÎãrês‘—ÏK!Ëç¯i‘ÍVâÅ÷*òRîðåµã0|»©ò^¡ú›Tü½’¥¥s9OÕZ=v¦õ›='/hЦ¨‘õ¬8ÙæÀ3bh“&¯µâ+«|üÈãB€€“-tz,´6mØZÛn¦çZÛéJÙZÛmGÌÎWï ¾e¸N (“ÂÇû{£xÍ\,Äl«ÞºHtA%Ô" }†^u|Yñ\<Š„ц|…‘ú.fH’ åÄõÕ%˜”Yñ p^OS$ÞDr sžó)ÏÄD àrc=›Ë£!¡¶[8/O æ0ÝÅà9V@0íèý'%Åx l¼¶°«rƒÀ(^|Ÿ‰µÆÉñ.‹ò‚kù(.a–çøaè:•‹§(‹Ÿ#¯JXÿUš¡lÄrûf- {ˆÇ[Çf)ÂË'Zâáb1·:î.¬­³œâ¢gù0ÒgØ d‘L1Æ»±ªm|äiħq}7¾ Ù~ɽ¼å™iCƒ{Ö`dºŽÆÓe?±6uŽéVœï{„¬Õj­> endobj 1086 0 obj 1254 endobj 1088 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 173.076 150.0 181.476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1090 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 161.076 174.0 169.476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1091 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 149.076 168.0 157.476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1092 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 137.076 186.0 145.476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1093 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 125.076 156.0 133.476 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1094 0 obj << /Length 1095 0 R /Filter /FlateDecode >> stream xœÅWmSÛ8þž_±Ã}(i\Y–_Ĵ̵̥¹R†Üõ:!L¬ŽdÈÝÜ¿•_òb+îg,VÚgµÏîJ뻎 ºúås £iç®’ÙàSp¼Jäz`3‹º0…jìB¢W­ h=ÂW¹øÑI;Î:ƒ!NF@Pá¡Cšp…òeçb;ž!¯nŸÀMç¸ßyÿÙ›@¼¢ÈcgŒsîq,‡rýPèOa°ß;?ÿþvý/Óþ†ŽMÿ'.Š=».BKñ×·ŠønL¸ŒlάÅ~)_I ƒN)CIi[O%U°ªw¹‘rXúS¾·úAVnu/6“áUoÏ_+ÚÄ 62ÀfîÖxeÖZÔ¶—þð¦?,Ðéìj_<¯tæðþ„Ÿ‡ÅË)½_G¥Är<‚g/as‘åÝ©Ø ÖAÝ6¬CÛ°íUŒµWÞ‹4ïž©p69hk¸^[ããÚÓÖð‚¶ÆIïüŽE:šLCu hP-¬mr£ƒ·Ob*¡/sË2¢ínà-’qÞÍö¿‡Ã&¦O´ÎŽ,ØÔŒkâabwÛ~-¸´5\ûˇӋßz0 ³ äáu"ÞSÀÇ"ƒ¿Yà¸äÈþôÏ¡5õÏmà}>1ãyM>¯ö)g0– ®öñ¯HC¬ l®ôûê­ÂoRW’r-âôD8Â=Íg‰€85(M~jN™HÄ(‡Á8VXÅÚúI¸Œ•D1%r!P`:šl5#w U$T÷z±=4 ÙÍ|.õG2)vyµ?’é(Ì‘­\À› ©Gç—ôíáÏ’B‰”6ã€q½Úßû9W1¥‘’3y(=!Ó8‚c%þš¤BK¾Ê4ËÃ4S8™•ŠôV¢ø·øvÆ œIu!À¥£Ž)r{ßâÛ8᫚g…"ìý‘„Q<ôD§ë‚ïó¼|‘™Ãe&ø¯Á3…¹ðúJæÙíAŽ¥Š3ø)’-.Àu\Cº"¹UÚåJŒ0ºæ)5Ö@ÚȺ7uZÁÁ²*`ð¡Lµ8®çM%5% ÷Z6V “%2ïÞ‡É\fÌ2ûÌùá UæGŠyØ«Ù4‚è;²ísÅÎûÏÖ²EŒ’½qgp˜oqâÛűмŒ#§ã1ú’Õú­æEÛômË!ú¾÷«ëþÇKä^(¥v+ñ(F˜J˜r\./zp7xàâ©(×ÂyФ' à(ă.Ìð¤‹Ç¦ k'x`~€; Ê\/žrQŠ€”Ø”WΓ©ØÁ öïVàºÄ&œ—Ч#1Ón†Ø>Åù<Ôã'ùc¾ƒÝ–Ϲ[WίãçKDˆiŸKÍ ¥¤ÊÞá¸Ë3<Òï’nÍb·œÂêËâÜ\""ËÐåp¬÷Büª=GÃê!Öaжd½µ•—ÙÒK=[{Új õQÔDÛŽ®ñ­,QÛã:­Ûºΰ@E¶CÀ\j[Ü%<|¿Js<Ž’L.»íU³«›8Ç·eºã5w»¤õíVDÈØ»k©j¸^kàúæw»gMã™gЭëm«E¿ÞžÐ‡â²»‹¼t¹†Ë­x-(N,¦é¢žÉ“Ûk ™b ÷A3í›x‘fXÖÖûÓ“)ß endstream endobj 1089 0 obj [ 1088 0 R 1090 0 R 1091 0 R 1092 0 R 1093 0 R ] endobj 1087 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1089 0 R /Contents 1094 0 R >> endobj 1095 0 obj 1317 endobj 1097 0 obj << /Length 1098 0 R /Filter /FlateDecode >> stream xœÅX[OÛH~ϯ8 „]ßcWÚJ° ÝÒ@¹¤[!ÂÃ$žŽì Ýì¯ß3DZIˆÊŠ žžñ¹}ßwÆÏ- üÑÄ¥X0š¶ž › ] l¯0¹˜Žn¹0…bíB$îª,¬å /ò&\LàG+nð¹uÿ€›!èð³e4Ãåη­ëJ~±c¼{~['ýÖ‡3LúãDޝ[Ý ü®¾n[øXПÂ}çâøJ»þ~zswðýóÖi¿Ö‰mZÿC'×y yé9¿þëê9ɵ ×1ê;”ö•5OhKZdn±ŒWYˆ\Ê~äucƪ £ÚE]ïš|³ºÂÑ4t¿&Óñ7 àQ[#Rä.û ÖÅ-4íŠ^m%„«Â˜ÆøTêQ„0·áôVݘV ·KÆt^×;vN9þtsÙ„tL° ‰¤6NÒ)ᇰ_ÇW™ÌÝEùƒÎ(¡éˆnSéNÙ¼-|þšf7$ê6YGáî•Ê —Ú ¥·ßd¶˜Q-áÊÁ2š”åsrûåâªwªßÜßÁß¾ŸàÎzߎû¸g© ·¬&BKªÅ‰©ô°×Ž&¤œAuìbí|â:¯Ëú¿!Ë3ò…ïÚî¹D¶Ù<›äšŒ³<øöÃ$rJìºÖ®¹UФ¾³1é–R¯á…»üÒS<Ë ýNqT´ÿ$£'šÁ ‰C¬ü\oƒ^âxKû‚°#¸b4M©Ø*¦E]m7±«ñÅ ¿·ÏBsÆŠÎf à¾Àû>"×Üð1üž"àɂ憈ðpEl· —‚ÓIÒT.ªY”Íz LñO56uo©*ô<Éè¸]*gÕwEDʧ€ÓUqÎ'Iʲšð”/¨F“ •ôJ>K5í/åR¥]ØX¨æÜ5›䜗#¦™Ê Vƶ2Ì+Êù,µA_"³bBÆV–¼óÙo1º%Žg³öÕ ¿a{®î˜NÐõ [zÞâÃéxŒøeKÅÀ #v@zþ˜N_h TzŸP ÓÖÄ€o<Âp{ÝÉÛ„d€vaœÇÈN´OÛp2$=6/ô×›ðÌ ÑÄq^ a¸ØÖƒ'µ.“˜ê•/Ê×­{S endstream endobj 1096 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1097 0 R >> endobj 1098 0 obj 1224 endobj 1100 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 558.628 150.0 567.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1102 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 546.628 168.0 555.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1103 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 534.628 186.0 543.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1104 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 522.628 144.0 531.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1105 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 510.628 156.0 519.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1106 0 obj << /Length 1107 0 R /Filter /FlateDecode >> stream xœÅVÝ£6篘Ç;é ¶ù0²OÊ)òqÂúìEôá…YÌ‚˜¢æIį­P}wê;ßê¥O2_FˆM+¦q–QF¯a&ê‘nÔÄ01’­ÌÕ¡)¿ˆ]5µ¶ß5®]ÏÃK¥÷P•º{F€€Ü€b"ýÌ;Õšè–³)«…ÀfñR`CìËc\ÝΆՑCTÇ?gÕGÕWÅy»™'1uåˆz#ˆX œÛ™± ñb#LJhŒƒà fÔ1Ê})õhâq´ éë\ôЬd-›N_;™~!ÌÅ êò‹|®âVê¾ê@ËÎTcQî÷²E<Ø·ªF!´²ƒgo4´4Fa§ƒÀ)á®ÒêÜVÇ®fŒi¹ÖfÛZvé:r5©m¿YlÒ/ _ŠW(ÿ6$_ yj˦û jÊ_ŠZ)uZ…˲—ÂiL›¼›~e®°0Áña-X„_T'oÎ–à ±|¢px²5 ½ZnI@B/¼uijËm]*Å’¸˧Oª-@´‡ÞÉxqV)¹nQQSÿ”/À}÷'àª.,ÁÇÆç,YòŽÓN6Çi°îãÅ”]¼¬Åiš]Kn lá16Wu\ä­ÒÚ–ÿ¾oòáïéj÷æ…¯Ú݃ ÓÌk¨ESžúÊþu€J4‡^¤&Ù³ñþ(Fé¿ endstream endobj 1101 0 obj [ 1100 0 R 1102 0 R 1103 0 R 1104 0 R 1105 0 R ] endobj 1099 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1101 0 R /Contents 1106 0 R >> endobj 1107 0 obj 915 endobj 1110 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 168.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1113 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 282.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1114 0 obj << /Length 1115 0 R /Filter /FlateDecode >> stream xœÅTKoÂ0 ¾çWø¸’9IŸG{#PiÄ¡6Ðh+ Òöóç6ZÚva}(–Ïöç|íŽI@ºy¶¸¾‚EÄv…O‚«@;…Ëv@YBÙAaÛ°¥]eC-ZÌ&2ÖðÆb†ðÈfs . ðÍð2]ž²q©~Á«×GødÝ€Ý=Ø ‚óˆ,‚¢(ÑOhåg—‚ ‚ÙM§ßçÁ¤3œvzüvÁ˦¤Ð–E[5Ùx žGC> ÝNï•?F¯}TF¡¥ú‡QŒór¹@=®ÈUR ØV#%üg/½–ÐÆGS; m‹#/VÓˆ1 ³¶òÀ3 ,³¨JêªÅÛÕäf@‰Â«èA:ªUWžZí «§hyF‘'†þ%C¬}%ûd»}_)¡TÍ.—<݇ñ!\¤›$æ‹$Š6)_'I¹È)£Irô>â‹Ä–'\OSÀ·Mæa’®&GC'Ô¬«:eòüæ^ŽlKÝ4è@)UO›„pÄ85 ýŠIÍ¢#ëàÞ`:´×s3,MЖM…W?é*>Pû¢4¿1ûCÃLÕ endstream endobj 1111 0 obj [ 1110 0 R 1113 0 R ] endobj 1108 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1111 0 R /Contents 1114 0 R >> endobj 1115 0 obj 429 endobj 1117 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 709.5 295.65 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 1119 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.505 709.5 541.505 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 1120 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 697.5 342.86 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 1121 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.177 697.5 541.177 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 1122 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 685.5 345.64 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 1123 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.159 685.5 541.159 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 1124 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 673.5 332.32 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 1125 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.251 673.5 541.251 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 1126 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 661.5 317.31 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 1127 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.355 661.5 541.355 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 517 0 R /H /I >> endobj 1128 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 649.5 162.89 658.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 1129 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.427 649.5 542.427 658.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 1130 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 637.5 226.78 646.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 1131 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.984 637.5 541.984 646.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 1132 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 625.5 222.88 634.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 1133 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.012 625.5 542.012 634.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 1134 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 613.5 219.0 622.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 1135 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.038 613.5 542.038 622.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 1136 0 obj << /Type /Action /S /GoTo /D [904 0 R /XYZ 72.0 720.0 null] >> endobj 1137 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 601.5 323.05 610.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1136 0 R /H /I >> endobj 1138 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.231 601.5 541.231 610.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1136 0 R /H /I >> endobj 1139 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 589.5 218.44 598.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 1140 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.042 589.5 542.042 598.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 1141 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 577.5 206.22 586.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 1142 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.127 577.5 542.127 586.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 1143 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 565.5 206.22 574.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 1144 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.127 565.5 542.127 574.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 1145 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 553.5 222.33 562.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 1146 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.015 553.5 542.015 562.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 1147 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 541.5 212.32 550.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 1148 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.085 541.5 542.085 550.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 1149 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 529.5 200.1 538.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 1150 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.169 529.5 542.169 538.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 1151 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 517.5 200.1 526.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 1152 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.169 517.5 542.169 526.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 1153 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 505.5 216.21 514.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 1154 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.058 505.5 542.058 514.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 1155 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 493.5 217.32 502.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 1156 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.05 493.5 542.05 502.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 1157 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 481.5 205.1 490.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 1158 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.136 481.5 542.136 490.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 1159 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 469.5 211.21 478.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 1160 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.093 469.5 542.093 478.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 1161 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 457.5 221.21 466.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 1162 0 obj << /Type /Annot /Subtype /Link /Rect [ 532.023 457.5 542.023 466.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 1163 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 445.5 227.88 454.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 1164 0 obj << /Type /Annot /Subtype /Link /Rect [ 531.977 445.5 541.977 454.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 1165 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 433.5 257.88 442.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 1166 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.732 433.5 541.732 442.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 1167 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 421.5 229.55 430.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 792 0 R /H /I >> endobj 1168 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.932 421.5 541.932 430.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 792 0 R /H /I >> endobj 1169 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 409.5 238.44 418.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 1170 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.869 409.5 541.869 418.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 1171 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 397.5 226.22 406.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 1172 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.954 397.5 541.954 406.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 1173 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 385.5 226.22 394.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 1174 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.954 385.5 541.954 394.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 1175 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 373.5 242.33 382.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 1176 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.842 373.5 541.842 382.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 1177 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 361.5 224.55 370.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 1178 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.966 361.5 541.966 370.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 1179 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 349.5 226.21 358.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 1180 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.953 349.5 541.953 358.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 1181 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 337.5 266.21 346.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 1182 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.678 337.5 541.678 346.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 1183 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 325.5 253.99 334.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 950 0 R /H /I >> endobj 1184 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.761 325.5 541.761 334.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 950 0 R /H /I >> endobj 1185 0 obj << /Type /Action /S /GoTo /D [1021 0 R /XYZ 72.0 720.0 null] >> endobj 1186 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 313.5 337.74 322.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1185 0 R /H /I >> endobj 1187 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.104 313.5 541.104 322.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1185 0 R /H /I >> endobj 1188 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 301.5 317.87 310.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 1189 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.318 301.5 541.318 310.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 1190 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 289.5 258.99 298.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 964 0 R /H /I >> endobj 1191 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.728 289.5 541.728 298.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 964 0 R /H /I >> endobj 1192 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 277.5 228.45 286.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 1193 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.94 277.5 541.94 286.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 1194 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 265.5 232.89 274.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1195 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.908 265.5 541.908 274.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1196 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 253.5 231.22 262.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 1197 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.919 253.5 541.919 262.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 1198 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 241.5 246.21 250.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1199 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.815 241.5 541.815 250.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1200 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 229.5 178.44 238.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1201 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.286 229.5 542.286 238.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1202 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 217.5 210.66 226.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1203 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.062 217.5 542.062 226.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1204 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 205.5 180.67 214.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1205 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.271 205.5 542.271 214.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1206 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 193.5 196.21 202.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1207 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.163 193.5 542.163 202.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1208 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 181.5 170.11 190.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1209 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.343 181.5 542.343 190.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1210 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 169.5 203.44 178.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1211 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.111 169.5 542.111 178.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1213 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 157.5 221.017 166.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1212 0 R /H /I >> endobj 1214 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.864 157.5 541.864 166.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1212 0 R /H /I >> endobj 1216 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 145.5 249.55 154.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1217 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.792 145.5 541.792 154.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1219 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 133.5 185.11 142.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1220 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.24 133.5 542.24 142.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1221 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 121.5 197.89 130.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1222 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.152 121.5 542.152 130.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1224 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 109.5 237.32 118.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1225 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.876 109.5 541.876 118.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1226 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 97.5 316.19 106.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1227 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.33 97.5 541.33 106.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1229 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 85.5 328.97 94.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1230 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.242 85.5 541.242 94.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1232 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 73.5 233.99 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1233 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.9 73.5 541.9 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1234 0 obj << /Length 1235 0 R /Filter /FlateDecode >> stream xœÅÝ]“%×u ç{þ ÜYš”3s­ýu Íl €¦†ŠÑ\ $Ì òÌHößw®l€@ÕI繑EEl¼»ût?ÕU'Weîý?~µ´ÿù¸þk¬ã£¿ÿ—_ýïlÿhEÿþ‡ZÿhÏ—£}ô/}ÿÏí£®ê'ÿpüðOç}ˆÎø¿>ú/¿úîWÛGÿùWÿõ¿ÿò>ÚÎÿﯶ·?ݵø›_ýõO~ýú7Ûø¯¿}ôO¿úõû_ýï¿9xûèýÿñ(ÚËZÛ¶í}~4_âXõÇGïÿå£ÿúŸ~ñÍ_ñ—ÿí£÷ÿǹ²½]ÙûÂ~ÿ¿þñþ¯ÿí£ÿüïü‡ü°ðÝûW¿ýØÿ~û}½†ëU_ÇùÿãåúÈxõ/Zn¯ÿÍO>jþôã?þèõ Ƈ;äï]ÿꟿgþþ¿?¼ÿøá÷óá¿ö÷±ýøÛØ~ú»xýaôú‹ÿé#èáã`ä˾ŸA[?_Öö2_}DüñÿùÙƒÿà?»ÎúµÿÌïêxøèþìóo>ùõï>>ÿR|üõ»O>{÷õÇßüí—ï?ùÇß⟖G¼ô<×Åzüò—}<Úùÿ‹‡EýemÕÎÇ¿ˆ/ñ‚8‰›ÄâÜ%N‰Äm“8$.ÁØöv~’úåxA܉›Äâ±Kœˆç&qH,‚S—.\ xfƒ`l ;Æ‚±ƒ`ì Æ‚qˆ`ˆ`ˆ`ˆ`Š`Š`Š`Š`Á&‚M»vì"8DpˆàÁ!‚S§N\"¸Dp`n ˜æ‚¹`î ˜;æ‚y€` ˜‡††††¦¦¦6<ß™íØöÜof?wE–ç[ô¶µmË›7ÿ­¿©ÏëÅc{}ñÕ§Ÿ|ñÅß~üîËç®ÏOɳ×-ÚãOV¯³¾Î<^9Ö'ç\ÛÖöx\öøV»S½¤®ÏÏP7ª§Ôõ)ê¤z@õYj±ŒM,cËØÅ2v±Œ],ãË8Ä2² ² ² ² ²L²L²L²ldÙȲ‘e'ËN–,;Y²d9Èr’å$ËI–‹,Y.²\b™›Xæ&–¹‰eîb™»Xæ.–yˆeb™‡XæA–A–A–A–I–I–I–,ÏwéÛœÛ~ x÷[ïÒ÷1¶m_7ošÛx|›~B_ÈÏ3^¿Múû;£¾¿sþÙÛãÏöá•Þ¼Kï/ã¨ð¸y wﻡ>ßwKݨžRŸï»¥NªÔõ¾[ê Z,ë}7Ô»XÖûn©Å²ÞwK-–õ¾ê Ë Ë Ë Ë$Ë$Ë$ËF–,Yv²ìdÙɲ“å ËA–ƒ,'YN²œd¹Èr‘å"Ë%–õ¾[j±¬÷ÝPïbYﻥËzß-µXÖûn©É2È2È2È2É2É2ɲ‘e½ïkÛÏæé·³×Ûî6×êç¿|XÔÖãÛîó÷û:úúÝ7ï¿úúæíöÇß¼ÿäý»·ïþz½·?׸ù¹êUöã¥?¾í>¿€döó½z>®zx‡y~ý€xA|~õ€¸I¿t@œˆÏ¯‹àÁ‚±`l Æ‚±ƒ`ì xþM”ãÁóbâÁÁÁÁÁÁ&‚M›6ì"ØE°‹àÁ!‚C§Nœ"8Ep‰àÁ‚¹`n ˜æ‚¹ƒ`î ˜;æ‚y€`""""˜"˜"˜"˜"ØDðüd¾ ÞqוÁÑ΋‰±ÍÇe}¼28‰×Ño>ÿâÝÓ7Íd{‰m­5Zü™®W9^nÆñy~°Í¹m½­ÇeïÛNuR=¤>/ƒ¤ª;ÕK꺂ºQM–“,'YN²\d¹Èr‘åËëRj±¼.†ž¯w±¼.‡ Ëë‚j±¼.‰ &Ë Ë Ë Ë$Ë$Ë$ËF–,Y6²ìdÙɲ“å ËA–ƒ,'YN²œd9Ér‘å"Ë%–×µÔby]-=_ïby]/A-–×Óóõ!–×5Ôdddd™d™d™d™dÙȲ®ž~¸9éù‹“º„ŠÖ¶ý¼®y\Öãñêüìü:úÓÆ ªÎ7›sÖ­Q±óz)ûq~p<¼–•/}‹µú1—½ýý®ñy‰HuPÝ©^RïÕê)õ)&µPîYFYæv.ØŸ©ƒêNõ’:ªÕSê¶ST©;Yv²ìdÙÉrå ËA–“,'YN²\d¹Èr‘åËcËcËcËcËcËcËãËk¨Å²¶Ÿ:È2È2È2É2É2ɲ‘e#ËF–,;Yv²ìd9Èrå ËI–“,'YN²\d¹Èr‰emK#µXÖÆ4PïbY[ÓH-–µ9 Ô‡XÖö4R“eeee’e’e’e’e#ËF–,;Yv²ìd9Èrå ËA–“,'YN²\d¹Èr‰enb™›Xæ&–¹‰eîb™»Xæ.–yˆeb™YÒÜ'iî“4÷Išû$Í}’æ>IsŸ¤¹O ”Ç×3²0Äͺkäø~ý°®·Çòùžöa üñ»?üîëwß|óùW_ÞŒ£ÆXkÍ1—Öë:¯þ‡—µŸ_ŽzP!öñ¸ìq´ST©Ï¯FRÕê%õùÕHêF5Y.²\d¹Äòì¨ËcËcËcËcËcËãËãËã Ë Ë Ë Ë Ë$Ë$Ë$ËF–,Yv²ìdÙɲ“å ËA–ƒ,'YN²œd¹Èr‘å"Ë%–u££ÔbY7:B½‹eÝè(µXÖŽR‹eÝè(5YYYY&Y&Y&Y6²ldÙȲ‘e'ËN–,Y²d9Ér’å$ËI–‹,Y.±¬¥˺Ñê],ëFG©Å²nt„ú˺ÑQj² ² ² ²L²L²L²L²ldY·µ¯³Î:óæéPÝè¸fnÛ7ËúÍæmëíV5—úêwï¾þäýÝXªîyÜ>ìàü°ò—Õ,úf.•/çç¼³mëqÝüἮºö±€:¨îT/©Ïë©ÕSêóºFj²œd¹Èr‘å"Ë%–uw•ÔbYwWA½‹eÝ]%µXÖÝUR‹eÝ]%5YYYY&Y&Y&Y6²ldY÷ã϶fx¦^R÷ƒêFõ”zìT'ÕCêz[uPM–“,Y.²\bYwWI-–uwÔ»XÖÝUR‹eÝ]õ!–uw•Ôdddd™d™d™d™dÙȲ‘e#ËN–,;Y²d9Èrå$ËI–“,Y.²\bYwWI-–uw•ÔbYwWI-–uwÔ‡XÖÝUR“eeeee’e’e’e#Ëó½}Ûú¶Ÿß2/ªÛ«jÑŠÜ×õ›ÍP÷ííÆH?α¾úúíÅ}Ž›^Î~s$B½Ú>×ûºYø8¿ Ë»å‹òóˆòfù¤ü¼ ¢<-”OS¦:Mušê2Õeª‹TTTTTTTTƒTƒTÃTÃTÃTÃTÓTÓTÓTÓT›©6Sm¥º¶ýÈöLÞwËÓòAùØ,Ë»å‹òyXÞ,7ÕeªËT©žÿÒrR­£‚('Õ:,ˆrR­ã‚$?Hµ ¢ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©ÖQB”“j&$ùNªuœå¤Z QNªu¤å¦¦¦¦š¦š¦š¦ÚLµ™jû³ª??òº&p1Ö:ÿloŽ·»ŽçYío7ÖûüóÏ_®=ùö—ñÑ_üæß¿ûûûã¿~÷í?ÿøcŸ}ûoßþäýãÿãw¬æÇûâÛïþéß¿ý§üñGþî/~óÙg_üÝ_>\í/[;ùØÚÍkùqýú|Ùûض‘w믷ƙ÷µŽº<ûåüüs¤<,ï–/ÊÏ/°”7Ë'åçXÊÓrS]¦ºLu™ê"Õz‡rR­§p$ßIµžÃ¡œTëIÊIµžÅ¡ÜTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©ÖC:”“j=¦#ùNªõ å¤ZêH~j=¬C¹©†©†©†©¦©¦©¦©¦©6S­/ûùw*ú‹ëŒ§ØÖíî"dÜìP¾o·ùôëwŸ¼÷ñû:æéM¿_‡_ñ‘y³òÃuàù;}¼õáüãZ}[k¶»…oÿûùÇEy³|R~þQSž–ÊÇfyXÞ-7ÕiªÓT§©.S]¦ºHµ6»¡œTk»ÊIµ6¼¡œTkËÉR­Mo(7Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¦ºLu™ê2ÕEª5Š£œTk'ùNª5Š£œTkG9©Ö(ŽrS S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤Z£8ÊIµFq’ï¤Z£8ÊIµFq’¤Z£8ÊM5L5L5L5M5M5MÕfKi³¥ëÖ‡ó’¸–ÐÈëºõáüˆû0ò{X8òf—o·Úùìë¯~w?‰«­‘ŽJ»u^V¿Ùrz?¥Ç¬óãÚ¼Yø0È8 ÊÃònù¢ü”¦¼Y>)¯­äi¹©S¦:Lu˜ê4ÕiªÓT—©.S]¤ZSDÊIµ¦ˆ”“jM)'Õš"J~jM)7Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¦ºLu™ê2ÕEª5E¤œTkŠ(ùNª5E¤œTkŠH9©Ö‘rS S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤ZSDÊIµ¦ˆ’ï¤ZSDÊIµ¦ˆ’¤ZSDÊM5L5LÕfKi³¥´ÙRÚl)m¶”6[º¦ˆýXswùÏëjЏcÛÏÒ›…£ßLÛÛŽ¾øü›÷¦ˆßüÙ1âÃÂgLj ÿüñ‰<,ï–/Ê_Q?‘7Ë'坯ˆOäi¹©S¦:Lu˜ê4ÕiªÓT—©.S]¤úzŒøDNª¯ÇˆOä¤úzŒøDNª¯Çˆ¿œ¤úzŒøDnªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹T_ŸÈIõõñ—óT_ŸÈIõõñ‰œT_ŸÈM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘êë1â9©¾#þr¾“êë1â9©¾#þr~êë1⹩†©†©Úl)m¶”6[J›-¥Í–^ŸÈ:F„qÝë1âÃÂ1oƈýínM×ñãwøü›÷ß|ü»‡9ÖOf“kؤ}ÞìŠ/³¶ˆõLñÃÂÇyY·|Q~~E¤¼Y>)?¿"Rž–Êϯˆ”›ê4ÕiªËT—©.R­mÎ)'ÕÚæ\òTk›sÊIµ¶9—ü ÕÚæœrS S S SMSMSMSMSm¦ÚLµ•êÜί…ÏÔ}§:©Rê ºS½¤žÕj²\d¹Èr‰elbYûšK-–µ«9Ô»XÖžæR‹eíh.µXÖ~æPYYYY&Y&Y&Y6²ldÙȲ“e'ËN–,Y²d9Ér’å$ËE–‹,Y.±¬mË¥ËÚ´ê],kËr©Å²6,—Z,k»r©É2È2È2È2É2É2ɲ‘å‡sÿÖœÍfJþkÛž½Ý,œÛ͸k¼Ý-ïû}ðþæówÿåí݇Ww͸[øáu¿èÍ6xçg?ãÞÖ͇ÉB]iI¾(¯+-É›å“òºÔ’<-”×Õ–ä¦:Lu˜ê4ÕiªÓT—©.S]¤Z÷µQNªu_å¤Z÷µQNªu_›ä©Ö}m”›j˜j˜j˜j˜jšjšjšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕaªÓT§©NS]¦ºLu™ê"Õº¯rR­ûÚ$ßIµîk£œTë¾6ÊIµîk£ÜTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©Ö}m”“jÝ×&ùNªu_å¤Z÷µI~jÝ×F¹©†©†©†©¦©Úl)m¶”6[J›-]ƒ¾?핵kÐ7s­=ûÍÂyÜ úæÛ­ø®MöîÆ|uXÊn}¿YõáEÍ—vólìþÒëEÖo>Œ1Î"ÊåçGåay·|Q~~QÞ,Ÿ”wSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"ÕšPRNª5¡¤œTkBI9©Ö„RòƒTkBI¹©†©†©†©†©¦©¦©¦©6Sm¦ÚLµ›j7ÕnªÝT‡©S¦:Mušê4ÕeªËT—©.R­ %å¤ZJÉwR­ %å¤ZJÊIµ&””›j˜j˜j˜jšjšjšj3ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÓT§©NS¦ºLu™ê"ÕšPRNª5¡”|'ÕšPRNª5¡”ü ÕšPRnª6[J›-¥Í–ÒfKi³¥´ÙRÚl)m¶tM(çùw*ç¢aàõäm_ÛÖ£Ý,œ7Ç€ÔàuumàWʇýû~2¢|\öäˆòqáŸQ>“ÊúaôL–wËå?ý0z&o–OÊ»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘ê«å39©¾Q>““ê«å39©¾Q>‘¤újDùLnªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹T_(ŸÉIõÕˆò‰|'ÕW#ÊgrR}5¢|&'ÕW#ÊgrS S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤újDùLNª¯F”Oä;©¾Q>““ê«åùAª¯F”Ïä¦j³¥´ÙRÚl)m¶”6[J›-¥Í–ÒfK¯F”2 |5¢|\8oΩKé×UM'voÀó‹ìQcÊ>ö›¥?œ¡¼nž—/ãü ·fÞ-|—m–‡åÝòEyíÅ+y³|R^{ñJž–›ê4ÕiªÓT§©.S]¦ºHµv¤œTkçAÉwR­)'ÕÚyPòƒTkçAÊM5L5L5L5M5M5M5Mµ™j3Õ:ç)Ö¶GÏäuΓäiù ¼Îy’<,ï–/Êëœ'ɛ妺Lu™ê"ÕØHµ6"¤œTk+BÉwR­Í)'ÕÚŽrR­ %S S S SMSMSMSm¦ÚLµ™j7ÕnªÝT»©S¦:Lušê4ÕiªËT—©.S]¤Z;RNªµW¡ä;©Ön…”“jíWH9©ÖŽ…”›j˜j˜j˜jšjšjšj3ÕÆçÕÁ~WÿüÄëz ¹Íó—YwS¶ysPGÝòºú~çÂÏ¿üìÝ&jíÇ­ WþðÂnî¬Ý¤Î?„ë¤àÇ…Ó¯Ýò´|P^»II–wËåµ›”äÍrS¦:Mušê2ÕeªËT©©©©;©;©;©©©©‡©†©†©†©¦©¦©¦©6Sm¦ÚLµ™j7ÕnªÝT‡©S¦:Mušê4ÕiªËT—©.RTc#ÕØH5vRTc'ÕØI5RƒTã0Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"ÕÜH57RÍTs#ÕÜI5wRÍTó ÕÊIµ&}’ï¤Z“>ÊIµ&}’¤Z“>ÊM5L5L5L5M5M5M5Mµ™j3ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT§©.S]¦ºHµ&}”“jMú('ÕšôQNª5é“ü ÕšôQnªaªaªaªaªiªiªiªÍT¯£ˆÛšk-¨]· ®ó­ÜØúÍÂuwÐǹ$޵foãCu ù~~½ŸÎúÖ~xiûËñ8뫯ˆG=õ»ßý¢ó²fù¤¼¾"Jž–Êë+¢äay·|Q>Mušê4ÕeªËT©Ö–”“jRA9©Ö3ÿ”“jR!ùAªu“4妦¦¦¦š¦š¦š¦ÚLµ™j}·åØ×ÌÙŸÉë»-’‡åÝòEy}·Eòfù¤¼¾Û"yZnªËT—©.S]¤Z‡TPNªuH…ä;©Ö!”“jRA9©Ö!”›j˜j˜j˜jšjšjšj3ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÓT§©NS¦ºLu™ê"Õ:¤‚rR­C*$ßIµ© œTë ÉR­C*(7Õ0Õ0Õ0Õ4Õ4Õ4Õ4Õfª5^Û·ïÖ5^;/÷íh7 ×Ý!çÛó×Õ'ïßýù¯ÿþÝÇïÿöwïnÆ^sž—99çÍÚziçgŽ›C*Î/YQÇgÔïèaÙã€ê ºQ=¥>¿\IT©Ï¯URÕj²\d¹Èr‰eí µXÖÁPïbYÇ:H-–u¨Ô‡XÖ‘R“eeee’e’e’e’e#ËF–­,ç:¿Rä3yß-OËåc³<,ï–/Êçay³ÜT—©.S]¤©Ö9”“jã ùNªuŽå¤Zç8PNªuŽƒäaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹TëÊIµÎq|'Õ:ÇrR­s('Õ:ÇrS S S SMSMSMSm¦ÚLµõ—¬!RoKfHÙÖË}Í5ÚͺuwìC}J{U]‰¾q=<.::ãzøêõÕdÿqÆ5×ËyŶÖùéâfÝÝ`„òfù”¼f#”§åƒò}³<,ï–“jH('Õ’H¦¦¦š¦š¦š¦š¦ÚLµ™j+Õ±më¸û„s7.¡<-”Íò°¼[¾(Ÿ‡åÍrS]¦ºLu‘jK('Õ—PNª5.¡œTk\"ùAª5.¡ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©Ö¸„rR­q‰ä;©Ö¸„rR­q å¤ZãÊM5L5L5L5M5M5MõšžçZÛ20Èë8äý¼Lèwëöín÷ütþ™‰ÆÃ0ãübÒÚ¶m±µ›Å×°¥¿ôÇaÆy‘±í}ÛzŽ›uã†ó"ƒòAùy‘AyXÞ-_”Ÿ”7Ë'åËT—©.R­'Ð('ÕzrR­'Ð('ÕzMòƒTë 4ÊM5L5L5L5L5M5M5Mµ™j3ÕVªm­ýØŸÉëÎRÉÃònù¢|–7Ë'ås·<-7ÕeªËT—©.R­'Ð('ÕzMòTë 4ÊIµž@£œTë 4ÊM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘j=F9©Öh’ï¤ZO QNªõšä©Öh”›j˜j˜j˜jšjšjšêyuý|»y7úÙ¹NÍœÖùaë3oÖíÛÍfëõfèuöé×ï>yÿîãoÞýõïß}ùéÃCbçÛùókÛŽÌ›Å×k‹›Ã$kï9ÚÍ’ÇÌñtÙž.ç³åùþÙ2Ÿ.dzåù¦ýÙ2ž.ûÓå³Fµ!÷³å³Fµ ÷“åþ¬Qm¾ýlù¬Qm¹ýlù¬Qm´ýlù´Qm”Oµ§ÚÓFíi£ö´QÚ¨?mÔŸ6O§ÆÓFói£ù´Ñ|Úh>m´ž6ZO­gj¯ëgËgj‡ë'ËýY£Ú×úÙòY£ÚÍúÉòxÖ¨ö°~¶|Ú(ž6Чâi£|Ú(Ÿ6ʧòi£ö´Q{Ú¨=mÔŸ6êOõ§ÆÓFãi£ñ´ÑxÚh>m4Ÿ6šO­§ÖÓFëY£ÚFúÙòY£Ú<úÙòY£Ú2úÙòY£Ú(úÉòxÖ¨¶‡~¶|Ú(ž6Чâi£xÚ(Ÿ6ʧj*±Ö–S®¼k*0x‚çqݾÝlÌ\ßfx}öõW¿ûÙ™@ÝùaÌ»¥×+wÕ´ñÒר¶~Äͺ‡ËÓ¾Y–wËåã°¼Y>)Ÿ»åi¹©.S]¦ºLu‘jA('ÕˆH¾“jF('Õ’PNª5.¡ÜTÃTÃTÃTÓTÓTÓT›©6Sm¥ÚÏ/pk<•/Êûay³|R>vËÓòAùÜ,ËMušê2Õeª‹TkVC9©ÖÔFòTk~C9©Ö$GòƒTk¦C¹©†©†©†©¦©¦©¦©¦©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©Ö@‰rR­Ñå¤ZC&ÊIµÆM’¤Zƒ'ÊM5L5L5L5L5M5MµT?ìác ë¶•–Û¾mûͺ}»ÙÚ¸î%}]Jý0 z|Rꧪ‡µON¨Öýù ÕyXÞ-_”¿šP=‘7Ë'å¯&TOäi¹©.S]¦ºLu‘êë Õ9©¾žPýr¾“êë Õ9©¾žP=‘“êë Õ¹©†©†©†©¦©¦©¦©6Sm¦újBõD¾(5¡z"o–OÊ_M¨žÈÓòAù« ÕyXnªÓT—©.S]¤úzBõDNª¯'T¿œï¤úzBõDNª¯'T¿œ¤úzBõDnªaªaªaªiªiªiªiªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT‡©NS¦:Mu™ê2ÕEª¯'TOä¤úzBõDNª¯'TOä¤úzBõËùAª¯'TO䦦¦¦¦š¦š¦újBõüèõ„êaݾÝlO\O ¿Î~Nýìñöu:IÔjÆÍòëÕ/ûãªeoçkÛ¼Y÷8Šé–/ÊëPvÉ›å“ò:”]ò´|H~Ê.9©^‡²KNª×¡ì’“êu(;ä©^‡²KnªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹T¯CÙ%'ÕëPvÈwR½e—œT¯CÙ%'ÕëPvÉM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘êu(»ä¤zÊùNª×¡ì’“êu(;ä©^‡²Knªaªaªaªiªiªiª5¹9/ZçZKf#×ÃoçÂ}k7ËöýfæúÚð3ƒ›/>ùæýÛ!@;~܃ùqé÷^ÅÍEýe«iOŽ~³îaÖP›²A^›²IÞ,Ÿ”צl’§åƒòÚ”Mò°ÜT§©.S]¦ºHµN£œTëT1ÉwR­SÅ('Õ:ULòƒTëT1ÊM5L5L5L5M5M5M5Mµ™j3ÕVªÇùåðî‹Îãi§:©R×fÿPÕê%umôu£š,Y.²\bYçˆI-–uŠ˜ÔbYgˆI-–u‚Ô‡XÖùaR“eeeee’e’e’e#ËF–,;Yv²ìdÙÉrå ËA–“,'YN²\d¹Èr‘åË:%Lj±¬3 ÞŲN“Z,ë|0©Å²N“š,ƒ,ƒ,ƒ,“,“,“,k5Ïw@ûØeêsÝHôÃÎÎëöýn‡æþv˦?Í£¾|÷‡ÇyT¾œWÃÛÖÇ~³ôÏ?é6ûZ=ûͺÇÐfyXÞ-_”דn’7Ë'åõ¤›äi¹©.S]¦ºLu‘êõ¤›ä¤z=éùNª×“n’“êõ¤›ä¤z=é&¹©†©†©†©¦©¦©¦©6Sm¦ZOºÍ±íûíW Ç|Q^OºIÞ,Ÿ”דn’§åƒòzÒMò°ÜT§©.S]¦ºHõzÒMrR½žtƒ|'ÕëI7ÉIõzÒ òƒT¯'Ý$7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"ÕëI7ÉIõzÒMrR½žt“œT¯'Ý ?HõzÒMrS S S S SMSMSýð¤Û¶Ç>e ôáI·Ø¶cÅͺ}¿Û,|¾Ý²é›w?nÅôñï¾úæó÷ŸõåÃåýOU?E½ÂóÍízT¯»å\«Õ#ë/Ü7ËÃònù¢üü‹Oy³|R~þŧ<-7Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT[©®ó“Vm¯óËyß,Ë»å‹òqXÞ,Ÿ”ÏÝò´ÜT—©.S]¦ºHµžº¢œTë©+ÉwR­§®('ÕzêŠrR­§®(7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEªõÔå¤ZO]I¾“j=uE9©ÖSW’¤ZO]QnªaªaªaªiªiªiªçÕÁùålÍut¹F¯)BsÛÖv÷ËìûÝŽÎëí¶:ï¿þý—ŸÖQäŸ}òþ“_òÍñcç»Üµ¶m;G7˯W7ïöË™íåüü¼mÇݯúöÏ ¶œzíT'Õê|HTwª—ÔûAµXÖÈêC,kà!5YYYYY&Y&Y&Y6²ldÙȲ“e'ËN–,Y²d9Ér’å$ËE–‹,Y.±¬±†Ôby0ú|½‹e4¤Ëëà ¨Å²ÆR“eeee’e’e’e#ËF–,Yv²ìdÙÉrå ËA–“,'YN²œd¹Èr‘åËšZH-–5³€zËšXH-–5¯€úËšVHM–A–A–A–I–I–I–õÞ~nÛ–sÊ ¦£ogq³nßßîê›óÃߎWÙçóR¿Bkõ¸Ïoþý»¿ÿ·?þëwßþó?öÙ·ÿöíÿë·ß~÷ÇÿûßÿùÛª~üÑ/¾ýîŸþýÛúÇäïþâ7Ÿýö‹¿ûˇ÷ìíeÄZk;âæÅü¸þaÝ|ël×1nÖ=¾!ß-OËåµi˜äay·|Q^›†IÞ,'Õº'šrR­{¢%ßIµî‰¦œTëžhÉR­{¢)7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"Õº'šrR­{¢)'Õº'šrR­{¢%?Hµî‰¦ÜTÃTÃTÃTÃTÓTÓTk‹–¶­•ó.ÿÙ÷Îu°oçß–óoïͺý¸ÙDòº}•ý§O?ùô¯Þ}üþ“_ñîã¿þý»¯?÷ÍÇŸ½ûÍ'¿ÿâýzû¾îüÕ³š«íw?U½Òó:àñû®×eÇÚ¶¾úͺÇo\–7Ëç™ÏµöñL]{”AT©k2¨ƒêNõ’ºö(ƒºQM–‹,Y.±¼ö(ƒZ,¯=Ê Ëk2¨ÅòÚ£ìùúËk2¨É2È2È2È2È2É2É2ɲ‘e#ËF–,;Yv²ìd9Èrå ËI–“,'Y.²\d¹Èr‰åµGÔbyíQö|½‹åµGÔbyíQµX^{”AM–A–A–A–I–I–I–çgû½uoS."êr'ö±Vìwoó÷c¿¹Ü9Þ>)zsµófYí•þ§Û7‚ëÛ6ý%oÝ^ίMß_Ž=¬{ûÇP›TQÞ-_’×&U”7Ë'åuïäiù ü ÕÚ¤ŠrR­Mª$S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤ZߥœTë²’ï¤ZߥœTë²’¤ZߥÜTÃTÃTÃTÓTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹Të²”“j}C–rR­oÈRNªõ YÉR­oÈRnªaªaªaªaªiªiªiªuŸgÏm??YÊÀàºÏókõ7ëöãfÓõëîÖWÙç_~óîë÷ýîÓ¯¾þìa–q^‰d®ó—Xífí‡í¶nö\_/k?WÍè<¬z˜5œ$”7Ë'åç åiù ü¼ ¡<,ï–›ê2Õeª‹TëP?ÊIµõ“|'Õ:ÔrR­Cý$?Hµõ£ÜTÃTÃTÃTÓTÓTÓTÓT›©6S=/HÖ±_ß2žÉÏ ÊÓòAùyAByXÞ-_”Ÿ$”7ËMu™ê2ÕEªuû å¤Z7ÐPNªu å¤Z7ÑH~jÝFC¹©†©†©†©†©¦©¦©¦©6Sm¦ÚLµ›j7ÕnªÝT‡©S¦:Mušê4ÕeªËT—©.R­l('ÕºÅFòTë&ÊIµn³¡œTëFÊM5L5L5L5M5M5MõÚs};ûãn€ô3C kÇõ«Ò~f:u~i˜ó¼Y±nÖ^/¬ÝÝiSßÃÈóoýù·áfÝãiP^ßÃ<,ï–/Êë{’7Ë'åõ= ÉMu‘êµíœä¤zm<'9©^[ÏINª×æs¤zm?'¹©†©†©†©†©¦©¦©¦©6Sm¦ÚLµ›j7ÕnªÝT‡©S¦:Mušê4ÕeªËT—©.R½6¦“œT¯­é ßIõÚœNrR½¶§“œT¯ ê$7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª×Îu’“êµwä;©^»×INª×þu¤zí`'¹©†©†©†©¦©¦©¦©Ö©õÛ¶Ë æš!mcͺûèaÙ~Ül·Ÿýí>Ÿ½ûâÝÏί ÇñÃlëaíõÊúÍéxé£öçèófÕã©Y>)¯s¾%OËåuηäay·|Q¾Lu™ê"Õºc‰rR­;–$ßIµîX¢œTëŽ%ÉR­;–(7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªÃT§©NS¦ºLu™ê"Õºc‰rR­;–('Õºc‰rR­;–$?HµîX¢ÜTÃTÃTÃTÃTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕnªÃT‡©S¦:Mušê2ÕeªËT©ÖK”“jݱ$ùNªuÇå¤Zw,QNªuÇ妦¦¦š¦š¦š¦zֶ͛ç\ÏOu®iÓ^û€F»YµoÏM¨qÓx»Ð»?¼ûô÷ïß}üéW¿ýí'_~v3}9¯¦Ï_cì7‹¯W¶½ÌljSajó¢~Üý¢·cÉÃònù¢¼Æ0’7˧ä×Fò´œT¯1Œä¤za$'Õk #9©^cÈÃTÃTÃTÓTÓTÓTÓT›©6S­1Ìù©lßs<“×Fò´|P^cÉÃònù¢¼Æ0’7ËMu™ê2ÕEª×FrR½Æ0’“ê5†‘œT¯1 ä©^cÉM5L5L5L5L5M5M5Mµ™j3ÕfªÝT»©vSí¦:Lu˜ê0ÕiªÓT§©.S]¦ºLu‘ê5†‘œT¯1 ä;©^cÉIõÃHNª×FrS S S SMSMSMS­1Ì6¶ý|S&ÃŽÄ̽}ÿèØÃº=o÷?ªÝ™ÿöíÕÿVûýðPÚÃ’zE{Ýîü89/½·u£Ð¼Yø0e8/½)ï–/ÊÏKoÊ›åóÌÏ伸{&?/½)OËå¹Y–wËåuÈ‘äÍrSí¦ÚMµ›ê0ÕaªÃT‡©NS¦:Mu™ê2ÕEªõ&å¤Z`RNªõ&å¤Z`J~j=€I¹©†©†©†©†©¦©¦©¦©6Sm¦Z§ Õ{‚1÷gò¾Y–wËåã°¼Y>)¯Ó$OËMu™ê2Õeª‹TëLÊIµÀ”|'Õz“rR­0)'Õz“rS S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤Z`RNªõ¦ä;©æNª¹“j©æAªy˜j˜j˜j˜jšjšjšj}c.ϼйg¶ör̾íÛ¸˜îq³Ç|ÛÞnöõ»¯?ÿòýÇ·Ùo÷mÛ¢÷›…× ;¯ä÷Çìyñµ¯:ôü¸[ø8\k–OÊëHBÉÓòAùyñEyXÞ-_”S¦:Lušê4ÕiªËT—©.S]¤Z§CRNªu:¤ä;©Ö锓jI9©Öé”›j˜j˜j˜jšjšjšj3Õfª­T÷m[íîkíc¾(ï‡åÍòIùØ-OËås³<,7ÕiªËT—©.R­Ó!)'Õ:RòTëtHÊIµN‡”ü Õ:’rS S S SMSMSMSMSm¦ÚLµ™j7ÕnªÝT‡©S¦:Lušê4ÕiªËT—©.R­Ó!)'Õ:’rR­Ó!)'Õ:RòƒTëtHÊM5L5L5L5L5M5M5Mµí/í|—²µi²ÝmýØöýv&·G»ÝÕNá±mûØÖ‡ì›w_¼ûôýÛëÿºÕ¸ØãšãÄx¹Ù8­Ú­+G¿Yø0g¨È%Ÿ”×Nä’§åƒòÚ‰\ò°¼[¾(OSMSMSm¦ÚLµ™j7ÕnªÝT»©S¦:Lušê4ÕiªËT—©.S]¤Z³XÊIµf±’ï¤Z³XÊIµf±”“jÍb)7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT§©NS¦:Mu™ê2ÕEª5‹¥œTk+ùNª5‹¥œTk+ùAª5‹¥ÜTÃTÃTÃTÓTÓTÓTÓT›©6Sm¦ÚMµ›j7ÕaªÃT‡©S¦:Mušê2Õeª‹TkK9©Ö,–rRM›-¥Í–ÒfKi³¥´ÙRÚl)m¶”6[J›-¥Í–ÒfKi³¥´ÙÒue´m[Ãæž×m”g·úÙ>.ÜcÜÌbëcâUöÙW÷÷PžáqþÜkmófÕ‡ ñ|9§±ç‡ÑX{Íqï~¹»å¨scG¶§ò°¼[¾(??Œ(o–OÊÏ#ÊÓòAy7ÕnªÝT»©S¦:Lušê4ÕiªËT—©.S]¤Z#JÊIµF”’ï¤Z#JÊIµF””“j()7Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT[ÿðEþØ×Sù¢¼–7Ë'åc·<-”ÏÍò°ÜT§©.S]¦ºHµF””“j(%ßIµF””“j(%?HµF””›j˜j˜j˜jšjšjšjšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕaªÓT§©NS]¦ºLu‘j()'ÕQRNª5¢¤œTkD)ùAª5¢¤ÜTÃTÃTÃTÃTÓTÓTëþϹ­ýîíþÏO÷jæ¸÷c­Œ»±àžwn×,÷UöÅW_ýîMWOûÔ&[ßo|‚Ž»qc½‘›{ÍZç͇©A½‘“|P^oä$Ë»å‹òz#'y³|R¦¦¦š¦š¦š¦š¦ÚLµ™j3ÕnªÝT»©S¦:Lu˜ê4ÕiªÓT—©.S]¤ZzRNªµ¡'å¤ZzRNªµ¡§ä©Ö†ž”›j˜j˜j˜j˜jšjšjšj3ÕfªõMÂy|Øšý‰¼¾I(yXÞ-_”×7 %o–OÊ뛄’§å¦ºLu™ê2ÕEªµ¡'å¤ZzJ¾“jmèI9©Ö†ž”“jmèI¹©†©†©†©¦©¦©¦©6Sm¦ÚLµ™j7ÕnªÝT‡©S¦:Mušê4ÕiªËT—©.RÍTs#ÕÜH5wRÍTs'ÕÜI5R̓Tó0Õ0Õ0Õ0Õ4Õ4Õ4Õºõü·s­ECØš GkŽ­ß,Ü3o¦Âu—ì«ì·Ÿüîg¶óÜ<_éqÙ‡au»Ûफ»c·ãî—»› B}ÂITwª—Ôí ºQ=¥î;ÕdÙÉrå ËA–ƒ,'YN²œd¹Èr‘åËJ-–5þ“Z,kø'µXÖèêC,kð'5YYYYY&Y&Y&Y6²ldÙȲ“e'ËN–,Y²d9Ér’å$ËE–‹,Y.±¬ñžÔbYÃ=¨w±¬ÑžÔbYƒ=©Å²ÆzR“eeee’e’e’e#ËF–,Yv²ìdÙÉrå ËA–“,'YN²œd¹Èr‘åËšÞI-–5»ƒzËšÜI-–5·ƒúËšÚIM–A–4÷Išû$Í}’æ>IsŸëΖkõÍy‹]÷pîÛ¹0ãfážoŸÏóç¯=_eórµu¾ÏûÿùíwÿëÛ¿ÿ·?þëw?þà_}ûÝ?üó¿û§›qÕ¶÷z<|Ýü´?®¿\åù»]}µ›uw“+Ê'å}·<-”Íò°¼[¾(Ÿ¦:Mušê2Õeª‹TkE9©Ö(‹rR­aå¤Zã,ÉR­å¦¦¦¦¦š¦š¦š¦ÚLµ™j;UÛYœ<ÏägAyXÞ-_”Ãòfù¤|妺Lu™ê2ÕEª5ꢜTkØ%ùNª5TkàE9©ÖÈ‹rS S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤Z³0ÊIµ¦a’ï¤Zó0ÊIµ&b’¤Z31ÊM5L5L5L5M5M5Mµ®bû~ Æç‡Ly^&Ì~þm‰>nÖím{³ ndow^üæý'_¿ÿøýן|ùÍ'Ÿ¾ÿü«/f$㥵:Ÿzk7ËëÕŸknîg«ï dm,¹ß­{œ~„åÝòEy}_@òfù”ü¨o Hž–ÊwR=vR=vR=vR=R=R=S S S SMSMSMSMSm¦ÚLµî;íu7ï/×u—(ÔIõºî…:¨îT/©ë.Q¨Õd¹Èr‘åËØÄ26±ŒM,cËØÅ2v±Œ],ãË8Ä2² ² ² ² ²L²L²L²ldÙȲ‘e'ËN–,;Y²d9Èr’å$ËI–‹,Y.²\b™›Xæ&–¹‰eîb™»Xæ.–yˆeb™‡XæA–A–A–A–I–I–I–u–éjëñÏO²ýt¯¾‡u{Ûof#óíqŸ~õÛß~þpôïyMûãîok>)¯ Ñ$OËMu™ê2Õeª‹T¯ Ñ$'ÕkC4ÈwR½6D“œT¯ Ñ$'ÕkC4ÉM5L5L5L5M5M5Mµ™j3ÕfªÍT»©vSí¦:Lu˜ê0ÕiªÓT§©NS]¦ºLu‘êµ!šä¤zmˆùNª×†h’“j©æAª×†h‡©†©†©¦©¦©¦©Ö†hu”mÛïf™?7—¼æ::÷¸»JØ[ÜLJ×Û]Ó¾þê‹/~ýɧÿçÍœqÖm+Öͪ}Ž»»Çê^óÞ·-òî—{œ –7Ë'åu¯¹äiù ¼î5—<,ï–›j7ÕnªÝT‡©S¦:Mušê4ÕiªËT—©.R­›+)'Õº¹RòTëæJÊIµn®”ü Õº¹’rS S S SMSMSMSMSm¦ÚLµ™j7ÕnªÝT‡©S¦:Lušê4ÕiªËT—©.RTë^KÊIµî¶”|'պߒrR­;.)'ÕºçRò0Õ0Õ0Õ0Õ4Õ4Õ4ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªÃT§©NS¦ºLu™ê2ÕEªu3&å¤Z·cJ¾“jÝI9©Ö-™”“jÝ”I¹©Úl)m¶”6[J›-¥Í–ÒfKצn£­9Ç éÞµ©[;¶mÖ  ÷ÖgŽ}{»÷Ûç_þô±ÕßÒ[ã 8mÄÝêï«]£ÇúæQ[Ûvôu³în.DyZ>(¯oI–wËåõÍ#É›å¤Zs!ÊIµæB’ï¤Zs!ÊIµæB’¤Zs!ÊM5L5L5L5M5M5M5Mµ™j3ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT§©.S]¦ºHµæB”“jÍ…('Õš QNª5’ü Õš QnªaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹Tk.D9©Ö\HòTk.D9©Ö\ˆrR­¹å¦¦¦¦š¦š¦š¦zmh6¶}¿ÛüìäåÚÐlômÛ¼Y···{ý×O¼Ý÷ì“Ï>{5úðïÇõÕWoïN;Î?…}}VçãOT¯óülß^çqþqDfPÖ<®{¼œÙ,Ëû™·w >“/Êûay³|R>vËÓòAùÜ,ËMušê2Õeª‹Tc#ÕØH56RTc'ÕØI5vRƒTã Õ8L5L5L5L5M5M5M5Mµ™j3ÕfªÝT»©vS¦:Lu˜ê0ÕiªÓT§©.S]¦ºH57RÍTs#ÕÜH5wRÍTs'Õ)Ÿ»åiù |™ê2Õeª‹Tk§ÊIµv |'ÕÚ)€rR­('ÕÚ)€rS S S SMSMSMSm¦ÚLµ™j3ÕnªÝT»©S¦:Lušê4ÕiªÓT—©.S]¤Z;PNªµS€ä;©ÖN”“jí ùAªµS妦¦¦š¦š¦š¦Z—Ç~Ý ïãëŠãÈcÛÎë§›u{¿ÙSµçÛ ¾y÷þãO~ÿþ«û½Uë…úŽLËu³öúÎÑã¥Ðõàwþð}œ‡Uoû׃ß׃ߒ§åƒòzð[ò°¼[¾(¯¿%7ÕEª×ƒß’“êõà7ä;©^~KNª×ƒß¤z=ø-¹©†©†©†©¦©¦©¦©¦©6Sm¦ÚLµ›j7ÕnªÃT‡©S¦:Mušê4ÕeªËT©ÆFª×ƒß’“êõà7ä;©^~KNª×ƒß’“êõà7äaªaªaªaªiªiªiªÍT›©6Sí¦ÚMµ›j7ÕaªÃT‡©NS¦:Mu™ê2Õeª‹T¯¿%'ÕëÁoÈwR½ü–œT¯¿%'ÕëÁoÉM5L5L5L5M5M5Mµýä,ç§Ç4×í½ßïù¸hïßo4ùîý¯þúüÏÿ–ð{ endstream endobj 1118 0 obj [ 1117 0 R 1119 0 R 1120 0 R 1121 0 R 1122 0 R 1123 0 R 1124 0 R 1125 0 R 1126 0 R 1127 0 R 1128 0 R 1129 0 R 1130 0 R 1131 0 R 1132 0 R 1133 0 R 1134 0 R 1135 0 R 1137 0 R 1138 0 R 1139 0 R 1140 0 R 1141 0 R 1142 0 R 1143 0 R 1144 0 R 1145 0 R 1146 0 R 1147 0 R 1148 0 R 1149 0 R 1150 0 R 1151 0 R 1152 0 R 1153 0 R 1154 0 R 1155 0 R 1156 0 R 1157 0 R 1158 0 R 1159 0 R 1160 0 R 1161 0 R 1162 0 R 1163 0 R 1164 0 R 1165 0 R 1166 0 R 1167 0 R 1168 0 R 1169 0 R 1170 0 R 1171 0 R 1172 0 R 1173 0 R 1174 0 R 1175 0 R 1176 0 R 1177 0 R 1178 0 R 1179 0 R 1180 0 R 1181 0 R 1182 0 R 1183 0 R 1184 0 R 1186 0 R 1187 0 R 1188 0 R 1189 0 R 1190 0 R 1191 0 R 1192 0 R 1193 0 R 1194 0 R 1195 0 R 1196 0 R 1197 0 R 1198 0 R 1199 0 R 1200 0 R 1201 0 R 1202 0 R 1203 0 R 1204 0 R 1205 0 R 1206 0 R 1207 0 R 1208 0 R 1209 0 R 1210 0 R 1211 0 R 1213 0 R 1214 0 R 1216 0 R 1217 0 R 1219 0 R 1220 0 R 1221 0 R 1222 0 R 1224 0 R 1225 0 R 1226 0 R 1227 0 R 1229 0 R 1230 0 R 1232 0 R 1233 0 R ] endobj 1116 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1118 0 R /Contents 1234 0 R >> endobj 1235 0 obj 16406 endobj 1237 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 156.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1239 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 168.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1240 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 204.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1241 0 obj << /Length 1242 0 R /Filter /FlateDecode >> stream xœÅTMSƒ0½çWìQÄ$޵£NŠeÆC§DTF>lÁÑŸoBh ¥z©´3ÙÙå½Ý—}íQ êcéÃõÄ9Z·9 .[´).€:˜qÈ¡9dú­NÀ¶‘:ÌK*ø€gT wh¹RÅW ðƒÈ!]^  Ó_WÈÙûxG×!ººå@ „oû+²)¶¢ÊAb›yúaæ°¼˜ùVø4ñ“i8{ð­ÇË„÷è&ì ²)ûAA3C£ Y3S_7»î¸Cú•Žvù}¶ih›œÊ˜Þº”µ‹kO3ˆ sŽê {¤«¢oŒ³6÷„«”`ÙsårÔg¾µÁ"û[t¤qäN¡w¨ ¼—yžÖG*:ÊNåÛ”YöÅŸcŒÌ9•±Jj+ú®ËÁ¤;¨r´Ô?æ.A°+mUð¸!óË:© Ç‘æj>É1B1IÏ Òª7QQEq–…õµÜCgˆ†´‚¶1À†ÕC‚ÁÓù"˜÷ó4VÝW[6N~뤨ÔȸseúPG¥ endstream endobj 1238 0 obj [ 1237 0 R 1239 0 R 1240 0 R ] endobj 1236 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1238 0 R /Contents 1241 0 R >> endobj 1242 0 obj 410 endobj 1244 0 obj << /Length 1245 0 R /Filter /FlateDecode >> stream xœÅRMoÂ0 ½çWø¸NÒ¤íqC0m‚¡ŠL; ˆu¥Bí´ýüå hézeM%[v^žŸía€æ ¬‰S›‚BŒAÌA¨’ XD¹„‚/ago5~ôŒñ—Œó ¯dOÈre’o€ðMðò9^¬Áo3xu~„r¯Ép"!è÷s‹„ ˆ‘a <µ]Àòf1Öƒ»=Íg³G}»ýDƺ%G0þr2Wƒ«ß ™›?¦nÒ­„Œ°ilÁ)~Ž:Bác&â¹mjƬ/Ä»^·½:ð,›*ÚkqUòþˆ-!MZ»ÀTÔ»WîZg–û¤G3ƒMЬtK–nDyMÏeW^Õp’^ö!J@¤•2/%Qåõ`ýU—›²(¶õÚi!¼‹…mk8bT#‘*fÊFźàÑt‘Mûù‹5º$û‹8ÿ©ó}µ-÷´1ÂŒü5U endstream endobj 1243 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1244 0 R >> endobj 1245 0 obj 356 endobj 1212 0 obj << /Type /Action /S /GoTo /D [1246 0 R /XYZ 72.0 720.0 null] >> endobj 1247 0 obj << /Type /Annot /Subtype /Link /Rect [ 138.0 585.441 222.0 593.841 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1249 0 obj << /Type /Annot /Subtype /Link /Rect [ 404.792 585.441 506.792 593.841 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1250 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 505.545 225.55 514.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1251 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.836 505.545 541.836 514.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1252 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 493.545 161.11 502.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1253 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.255 493.545 542.255 502.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1254 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 481.545 173.89 490.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1255 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.171 481.545 542.171 490.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1256 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 469.545 213.32 478.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1257 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.916 469.545 541.916 478.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1258 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 457.545 292.19 466.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1259 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.402 457.545 541.402 466.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1260 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 445.545 304.97 454.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1261 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.317 445.545 541.317 454.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1262 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 433.545 209.99 442.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1263 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.938 433.545 541.938 442.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1265 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 421.545 219.98 430.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1266 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.871 421.545 541.871 430.545 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1267 0 obj << /Length 1268 0 R /Filter /FlateDecode >> stream xœÅÝKsÛF†á½~–IUÄéîsúr–Ž“™xƱÇ1§²H² $ÚVE‰¹ýûé^$‘PÆï&c¹J ø5Ñ$ˆÐúù$¡ÿœú¯ji8¿>ùy;/5 R¶³r¢ÎR®‡ít®<õ`"í¦ú¯M¨O|¾=¹9 Ã?N¾û¡?y1„^à·“pørcá·'o,ߟ ùòÖ@bú¿ÔÀë0ªŒ.©ÿ¯³çÑYÃãgÀíçßÏ(›y}ÎfÙþÔÕvMoo*²™Ü´góûÉv„ûf„éõ¸má_·ð0¼?ù|~ò·¿ç!†aþî~;¯^0†YKæÿÒ0¿¾û$æðéÃüŸ'_Î6€¿x­Aú²÷í‘!鬕Ô¬(½IAC-)ÎR«}º”Móæ·‹›»Åùúru3|µ¸¹¸º¼y¿iïÄÒÖÿÏbk}±m_àÃåÝðé ³2|r·Ü¼ÐöáÅòîüöòl¹~ýa¹›¼¼Y/oß-Î÷3~º]ýzy±¼Ø=>ûc7µ«N9¬NÒ8“Ø[E+öüåÛ7/ŸlJª½l*f¹¯•£²»E¿[Ýî&?lWξq‹õâlq·¯ÿú~EÞÍv3ç ÞTéá:-á`ñ‹««ÕoãZkû:ô©ÕOË›m Ú£nçœ]­Î¼ûlûè|u}}¹^ߨ¿Îíêêê~öÙâüÇ]‘ÞÈ÷ËÝ‚¯ËídoûþUoÖË/~Y¯ú²NÛUSo—…|‹ôvõú gË‹_/W¿ÜÎv6Õ? ÚômÓê,çÜWIÝn§¯Vë哘½@Laf¾›ÆM‰¾Z4Ív•^Ü­÷3Ö«ýäó¾šV7}Sùl?ëÉ .¶0+Õ78ËKü[\ÿh)­oqE§ª{¿øqËßL^,ß-~¹Zß?w·^Ü®ïö/ïÛøxsØÌ{öŸùë篿þúÅ|?ëz5¢n|ßß±ûµjSkUÒA5ï–ëÓ­x×|²±ýSs¢ð÷Ÿú;£ôÍ¢¿5Vûɳåû±!›G‹ýÔã&mæ= Ÿå­ûlÿèÉ–I¯YµØ?ã£MµÑWò郥?ý(úg/´¯É‡ÅÝÁÛÃW®êA¾o–gËἿýûçàò÷Ÿ®.Ï/×Wìß)2ľïnýã;>ªF_×ÍfRzE,o_k¾8»Z«wÃó¾ñ/oÖwö©žbꯛCÝ~áíüÙ7óÓù7Ï^½}ö|þâõ«ƒúÇ,ýÚk"!Oï-?µxÿfzP®Ì¬ô&$IåfGqCñ¾ºQ<³xCñ¾‹AqeñŠâý£ Å…Å™jcªÆT©RM©¦€TS@ª¾OAq¤š"RíŸ(žjJH5%¦*LU˜ª0UeªÊT•©*SÍL53ÕìªÕú!Lù˜x‰,®,^Q¼/,n(Þ‹ggªÆT©R•€T% U HUR•ˆT%"U‰HUR•„T%1UaªÂT…© SU¦ªLU™jfª™©f¦Z˜jaª…©¦Z™jeª•©6¦Ú˜jcªÆT©S5¤ª©j@ªªF¤ª©jDªšª&¤ª ©jbªÂT…© SU¦ªLU™jßô ÁÏ®TÒk¤}¿Ð$›µ¬åbŽÇ½Ï©CxÛt…$›Íb ~F$NñŘ&ªdiV¥·¤Y™(wØpË(ÝH:†ÈâÊâÅc`qañÂâ†â ™Æ„PcrÕ~¨[²}L\"‹+‹W×ÀâÂâ…Å ÅsbñÌâLµ0ÕÂT S­Lµ2ÕÊT+SmLµ1ÕÆT©S5¤šRM©¦€TS@ª¾kGq¤š"RM ©zÅ™ª0UaªÂT…©*SU¦ªL53ÕÌT3S-Lµ0ÕÂT S­Lµ2ÕÊTSmLµ1UcªÆT©R•€T% U HU"R•ˆT%"UIHUR•„T%1UaªÂT…©*SU¦ªL53ÕÌT3SÍLµ0ÕÂT S­Lµ2ÕÊTSmLµ1ÕÆT©S5¤ª©j@ªªF¤ª©jDª‘ª&¤ª ©*ë[RÖ·¤¬oIYß’²¾%e}KÊú–¼ƒº¤bßPw°æ‰ ‹7÷KñI<³8S5¦jLÕª÷Ç¡8Rõþ8GªÞ‡âHÕûãH ¡ÿ©Ÿ˜ÒÄKyMýϦvØ¿¡ZªÁñ‘ž‘t·!éŒÒ¤»#I+JW’ö?ÿÒ‚ÒȲ ËŠ,+²¬È²!ˆ,²4diÈÒ¥Kõ…¤‰¥ùÒ‘Xúˆ/$M,}¼’&–>Ú I#KA–‚,Y*²Td©È2#ËŒ,3²ÌȲ Ë‚, ²¬È²"ËŠ,²lȲ!ˆ, Y²4b郺4±ô!]@:KÐ…¤‰¥çÒ‰Xú`.$,Y ²d©ÈR‘¥"KÿnŸ«5ËäÀÇÑ$k%L-%–©AÆÛáH/o¿œŸÞÿÝŃ>ì²ù©Ã¬6Qv<ÅY&ª6ŽÉ‘ý~ƒ"åWÀ8&‰W÷19H\X¼°¸¡¸ÉAâ™ÅŠW¦Z™jeª©6¦Ú˜jcªÆT©RÇä q¤:ŽÉ⩎cr8RÇäñ„TÇ19Hœ© S¦*LU™ª2UeªÊT3SÍLÕÇäÈ¢¶©ìqWdqeñŠâ>&‰ ‹7÷19H<³8S5¦jLÕê8&‰#ÕqLGªã˜$ŽTÇ19@"n(îçOH<³xCq?BâÊâÅýü ‰ ‹3ÕÆT©S5¤ê7¡8RõŒH<"U¿ÁÅ‘ªß`Dâ ©ú F(ÎT…© S¦ªLU™ª2Ueª™©f¦š™jaª…©¦Z™jeª•©V¦Ú˜jcª©S5¦jHÕo0Bq¤ê7¡8RõŒP©ú F$žªß`„âLU˜ª0UaªÂT•©*SU¦ê}K}b5Ò'åf­Æüæ £b±l‡°ýr~ò¦ÿü]Qª endstream endobj 1248 0 obj [ 1247 0 R 1249 0 R 1250 0 R 1251 0 R 1252 0 R 1253 0 R 1254 0 R 1255 0 R 1256 0 R 1257 0 R 1258 0 R 1259 0 R 1260 0 R 1261 0 R 1262 0 R 1263 0 R 1265 0 R 1266 0 R ] endobj 1246 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1248 0 R /Contents 1267 0 R >> endobj 1268 0 obj 3415 endobj 1270 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 156.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1272 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 168.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1273 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 602.628 216.0 611.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1274 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 590.628 204.0 599.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1275 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 578.628 216.0 587.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1276 0 obj << /Length 1277 0 R /Filter /FlateDecode >> stream xœÅUMo›@½ó+æØ ûÁîÂÑÒªUäÊ1RQk‚Z 6l”ôßw–ÓÊ—Ô¶´£æÍ¼™·xçQ øõí¡béÆÛu> Š—KH aÀl ³ö©Áz ÷Ïp畯Þý`«GNáÚ䥷Ô·òîõ Œˆ‰€1AáDg±ý0H6pÿa™Ìn?¹Í—³«äÛùÇH¾{×É#NÙ`´h{h)´{føSA»ì£€Éqd „½ÿàm rçC«mCE·¹ît8Óñqç$r A†,Ž•ñ®Å§E¡l"%At$*ؤÞyj£EÚÚ{>(.6BQÓ#ZírUGÊqº~K³­É«R#tn^´µGóÌ`Âx):ê –ùf7 KÈ꺪¡Zƒù½Í Ùþ£6z¥›Ìw¡| =6"Ÿ^E”£”ØZDÕ¸L4ÙS" 3xÈÇé7PV4ô@P­~f© zÀé©IŠí)gÌŠ¦ÚËá° œPăÐm¤ÝF|Ú(½hÒj³ÉÍYq!^,.Å««¢Xéô×"%êRȼôM­ËF§V!þvšÆ—B7™ñõ‹©þ>Êé¥À¯¹yv=€þ×=‘^7ü[£ÈaÍ+“íïŨ¶í/fà*ŽCÞ¥4F×f\ÿŒt© gò­dõþ¾ÈQö()6O$=“}u³\ÜLWŒm2ŽJؗ׸töf²²ÁžƒÁÐÞžˆÓÔ endstream endobj 1271 0 obj [ 1270 0 R 1272 0 R 1273 0 R 1274 0 R 1275 0 R ] endobj 1269 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1271 0 R /Contents 1276 0 R >> endobj 1277 0 obj 578 endobj 1279 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 222.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1281 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 602.628 168.0 611.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1282 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 590.628 216.0 599.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1283 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 578.628 282.0 587.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1284 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 566.628 204.0 575.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1285 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 554.628 216.0 563.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1286 0 obj << /Length 1287 0 R /Filter /FlateDecode >> stream xœÅTÁŽ›0½ósÜ=àÚc|ÜVÛª•¶Õj‘zXíÁ!NBKp^¥ýûÚ$K«\Ò$’_Æö›÷föl¿¡[¸ oƒ}#À)DIb Q[è0ƒÒÚ#»øClà{P>Ï/vs Ø^8ø”®½ü<Žò»|õüÖÁû,x÷‘Á­Ž%bÅq,„H¤(¢Â}(d[x¾ùðíáásvûÙ—à>›Øˆý6[ ­î¶¹Ôþ8j;<Ù`1žîŒº?ÄÑ6aäc6âs»­²kW·z!z?~õ6ðØÅt®š|~¸»H0J'3@X<;W®ÚY#]îÁOÄ66Å“‰­¶¹¼3å=ÝÿÊÕκ’–º0¯ÒáÆÛ|£0q ‘@8I,uÚQ<k{»[ÜȪª®uÝa½ê€ù½Slöe¸”F.d£Âñá¢?Ü«°NdPjŸOkG˜ êYg]Pž W„”sq~ÝeO‘Ò °ÒfÀr@}¢! ?TnÐðÿn@YWEµ>ž\ °¯IûÇUÅëל‘=•Ø´å/ÕláÌFÕÊE+ ¦–U#s×P(*ØÕz]«¦A}Yæ§„ Äl*ÁIßb¥à®lô0þÇé³êC±ŸÀvúÄi¹ñÙÛ´1²6áHà›Ï•¥&˜_Ê]ë²\Èüç,%—RÕXk¸›¥ŽÈ¥Ôr¹œpçz»-L¸ÑzÞ@]\oeBùj´gŸ%f7òP˜ÍLÿõ&Ô¾ÐÆqšz®¯Ú¨¿¾y(I‹¸q4\©å| þrzûð endstream endobj 1280 0 obj [ 1279 0 R 1281 0 R 1282 0 R 1283 0 R 1284 0 R 1285 0 R ] endobj 1278 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1280 0 R /Contents 1286 0 R >> endobj 1287 0 obj 607 endobj 1289 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 222.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1291 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 602.628 156.0 611.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1292 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 590.628 216.0 599.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1293 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 578.628 294.0 587.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1294 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 566.628 204.0 575.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1295 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 554.628 216.0 563.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1296 0 obj << /Length 1297 0 R /Filter /FlateDecode >> stream xœÅUÏoÚ0¾ç¯xÇöÏvâ8>Ò©›´U›X‘v¨z0` kˆ!qÅößÏŽ“@³Š $yöûÞ÷~ÄìØ~C·pAa± ö§%‰%@bDl¡Á rwªh‹ìâY°ŸA`ø<=ÛÍ%`ëpð)]íüL{ñݾz| ëàn|øÄ€`˜­Ž%baÆ0ÆET¸…Ùžn~|x¸›|üzû ³/ÁýlHDèHdZk¨•×í¥öÇQÝãÁ‹ñp§×ÿÎ~´Ö#o³ÛmåMÃšÕ ñÐçã×Ñ<ð1 ÜÏb8W >> Ü9ŒÒÁX÷ѸrÕÎébwùD@lcS;ËdVÝ\Þ$åsºÿ½P;“éBZê̼J‡+Ÿæ…‰SˆÂIb©Ó†â1[[ï n!p#‹¨²ÔeƒõªæÏN5°ÚçáR9—• û‡³öp«Âj8‘A©}C±{W1;Ô²ŽfAy‚\RÎŹ»‹ž"'¤ê`¡M‡e‡Ú@AÏ©…AÝó¤CYY±>ž\u°­Iýàªâu÷kîî¦Æ–ÎJ¬êòçj ¶pf£J嬅SÊ¢’ ×PÈ Ø•z]ªªBmYƧ„ Äl(ÁIÛb¥`’WºÿãôYu‚¡ØO`=}â´Üøì>­Œ,MØøæ{e© æ—r/ôv›™QB".%ÌŠ¾Òp7J‘K©år9à.užÏåâ%Ühý2'Ž.®·2¡|5úÚ°‹yÈÌf¤ïÝD‚Ú Íþ߯iê¹¾i£þyóP’ q!â¨s)êÅœF§üE endstream endobj 1290 0 obj [ 1289 0 R 1291 0 R 1292 0 R 1293 0 R 1294 0 R 1295 0 R ] endobj 1288 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1290 0 R /Contents 1296 0 R >> endobj 1297 0 obj 611 endobj 1299 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 294.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1301 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 216.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1302 0 obj << /Length 1303 0 R /Filter /FlateDecode >> stream xœÅTMs‚0½çWì±=n!p´Ú[«ce¦ÇE[EFeÆþü.D½XÑɲËÛ—·y¸f.+_´/!JØºÌ Ðl·L)¤Ã¥‚ÊXÁ’žªrÑb¢`lÅžØxBÅ) v OÛàVøó ^á›ÝìîQ@¾Ž#rŠ Q ÛÒÏ?‚Æ7­NÇ Þ[ýQ«mÝN x9¤æÚ&ºã .èúV{ðöÖ ¬çÁàÕ`‚Ú l!ÿaÃb…„Â’¾š©”ƒõJÅ?‡ü1K?‡Û&G×–å—«Ùˆ ³^ÔGXUQ7ÔUÉ/{Iç@Ü«¹A¸xÑWžZã ë§èxÆ‘…þ©Bl¼#átje›pµ £,NWÖ&].?ÃhaÍÓtqV7±ùWš]œÍ«<•·662¦G/¥8éæx\{6|eÚõÓl¶5=ÎÐÓµÍÑu©“çŸ×¥Ig•gü é¾Ñâ-„°Ç¸ Œô¸+Ðü³4ÀíÞhػ̧r, MÑ€›Ä³Ÿl¶ÚÒæyezCö “ÛO’ endstream endobj 1300 0 obj [ 1299 0 R 1301 0 R ] endobj 1298 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1300 0 R /Contents 1302 0 R >> endobj 1303 0 obj 432 endobj 1305 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 222.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1307 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 156.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1308 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 168.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1309 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 643.364 282.0 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1310 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 631.364 294.0 639.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1311 0 obj << /Length 1312 0 R /Filter /FlateDecode >> stream xœÅTÉnƒ0½û+æØp½`lŽiÕõ*¥¢(¡MT% õ÷kl ª¢J) ÍhÆ~ožgÌQ æõj#Cq†6MŒ‚dÀƒ&$ >f2h|i½ªã°gŒ[dœÌPŽ<¢ùÂ$—@̆oDáìæ)štøë ¹8?Ot«Ñ̓J@´GÄ&”˜‡qP˜³°~è æW³gýäé·Ñx:ºÓϯãëèt¯{‚8eÿ hbk° l›™ù$¶½î%„Oú™ÎìãmÔr3Ç]§Ò¦qu…8×éqvPie®Šþ`\”|x&d½‘¬zÓ@ƒ`p.|jG¬¹÷z8PÓXefšödÙæÊF”Ó4M¥e±Öâú 8ÁÒý,,nxxNäèÆ”U´­¼jåeWë"?ybÚgçBÇE–­«!<់·-Òô=Š¿†ƒà\Äh¹ìJ÷\ÅÞª(I¤ú+ÉNÆ!Ío“@T…¡¤Í(Œ‹*)À‰+aj¥<ÄŠ0ƒŠÝ–<ÁÎ ú¨Þ`  endstream endobj 1306 0 obj [ 1305 0 R 1307 0 R 1308 0 R 1309 0 R 1310 0 R ] endobj 1304 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1306 0 R /Contents 1311 0 R >> endobj 1312 0 obj 406 endobj 1314 0 obj << /Length 1315 0 R /Filter /FlateDecode >> stream xœÅTMsÚ0½ûWìfjU¶d!ÐN3LÒ79Ä98¶(îH°;™þû¬°± 8ä–bf$­ôvßî“öÅa@ñsí 4‡då¼Ô6ŠƒµÉ—À<Â}XA=÷!·§:¾ŸáPÂÉîµCá»óðˆ›)P¼:ôØÝ¹j'BÚØM> PJÙAZ;qUT•ÓU¼2UR=eðàšPéÛóA˜‡£«ÉèvâNÆîõørzB…oPLrÂ$Ržâ#ÎÕ1@Àüï³Ù&y\°Øl!ÎsØ3–ÇŒ¹'‰ X ïÔÕÅl~3{7[®$±,¨d=,î2ó –…)Èއ꩘ÇÕÔR¨ƒZÌð¾2RŸ!sÅt?·&1©Y'fYQž“J PŽžµ_y(ÊxÆÛÔMŸÜÍÓ“”_ ±í åÇÔçx÷<äÆkÏS$Ûì¹Ì6ësŒ˜UC(­=Q—1\fTZâ¤\(Zu7‹óâ²K+°²‚ëߨËìÛKFýp¿¾gj¢<¢­ÌJ°®^©)ã,oôÖ}UÑšê¡Ó .g4HÍ¢ªAÏóŠÑ0Bp~Ì ßÁÆNií|žoÊ¢é[mÛ°ÛD¶uô·A -°@g0Wi"ap÷czïNFáh<šO[3*ÛÌQÓf^þ{6í*\ß¶««_³Y»ÚûŒ†­íu™%ËvY”›­é²w©Y`%7I—&mmi\ÆOqÑ9…Ýä¨aõèQÆÖo¶¶Ï&1¤Óþí÷DU endstream endobj 1313 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1314 0 R >> endobj 1315 0 obj 694 endobj 1317 0 obj << /Length 1318 0 R /Filter /FlateDecode >> stream xœÅVËnã6Ýû+.ÐE“`¤ò¥‹ÎŽãɤ‚&V§‹8 Ù¦c¡²ä‘'AÑï¥H¿%'«Ô6,ŠÔ¹s¯ø£Cà×Ñ—@2Ï;?ì…€÷í”ç.ó`vìAªŸÚ°Õ/æ!Ìà¯NÖ!pÙ¹ÀÅ ,'ÜõJÜ'M°[£å\Cob,ÞŠÇ\ t<Ÿ6[ÆÅxí±Hq ¾)y¶)ë$W"³-‰Ìâ¥Úk º Qºg5^5‚r¡ÆÉ4Q“O€UÈô,ëmŠõ©fX¯¥Ýï€ã§µ—uï0Ü·÷C²ñMIˆÝ”ý—x¾HUÙ*Hqà»&¡'lË;IUC¼žML/sL‘È„dx:79 ÷“žTZƒŽzIʪtp=Ȇt£Ãç9T…þkÚ‚#12 &Âíò¥‚q>Á¿wH q½AꈡÊa„ 5MxNpÏé=¦çó9áØ>Þ>_½»~7êCÔ=¿î£ ºð½{×ûÖ½žhÆ?Á9lßõv—W„Û®¨WøœPfsìN§j¬ƒ?=FŽGðl$|l2ö¸7Èç&ÏQ<þ[e“&9èfU>-yQA{K¥Ø}4E¸ï~«£2T|;Ú6®ëšXŽ8|Û¿£•yœ»xÐ’hоîJA7-ó£Ìx+BlíH«=5æ™z»Ðs%æLg•j £/OÝŒ†„^¸’(6îD‹²w­«¡^*••x<ÑÒÔRì¡ óL/uÿ¸r·Nè·ÿT{WV endstream endobj 1316 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1317 0 R >> endobj 1318 0 obj 1144 endobj 418 0 obj << /Type /Action /S /GoTo /D [1319 0 R /XYZ 72.0 684.0 null] >> endobj 1321 0 obj << /Type /Annot /Subtype /Link /Rect [ 135.27 685.5 221.77 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1323 0 obj << /Length 1324 0 R /Filter /FlateDecode >> stream xœÅXëoÛ8 ÿž¿Bè—kÆ“åw‡aØõһݣkpŰ'V­~´¶³ ÷×õ°%ÇJ¶O»´@HI$ÅI‰ÊÓÄEþ¦ü+JZ“'5梈 /TCAˆ\ß!*¢”óUA: ¾ä" ÖèvRN0úsòå+LfƒÀv‚wÕ á›ÉµaŸÏà_n£ûÉïóÉ‹‹¹ÍW"8AŒ1vcÅŽGþ!h^ /ÇçUQTåÍõšoÚªfi~òÍßNfóKžKþ—®Å„"Ðþ#GD{0øx8cdB?®G…AOŽÁˆ´Í§r:õ-7"IéüÞëÖn`Ó‹ajüRãû³" >æÄƒ|ˆ÷†ÿc6 #·½ß?¥ö²Ê7EÙ ä»NˆŽYÙV=Ó®iO/×,Ï4—§Mãôì|Í´Šê±eU©•Ð<ד¹áîÞ‰GIâ{ã]ž_Añu¢#·H¢ ¯ï#Q½íWYÕEš³©ÕÓf¹¦Ezªy´í™´§¾ULûk ‘U¥VkB²¦Ò32ïìü±fEZ?ƒÔÔu?ÐçFsÕJÓrûŠYVå’Ö%ÍŒùt‘SCV`¡è{Új&5Õ9mŠy®h¾1%WU½o?¾yÿÙÖy'ø¥¹•…¡øiCkF U*CAÖ+©¹+VÞ7ãI’rö@¥7>¯¼£Ûu¥9Öhúï<ÍXÁêߌ±"-Ó{Z¿>jH[Íò*IËg=UÔÐð¶jèJ³Ûª~Ðdú@u‡¥Í…b¬ž©©›+#àB !à•yË2¨ó]–KçÈA⼆q@-ž?ÀP¤âµeíA¨x²ðÈ<;;ßv“$ˆi‡CË÷Ô ]‹¯÷VW•',¡èfv5;Ÿ£«›öŸ2- €P ’DŸ>¼C§HáoÙ_í¨Eòsû×ìÓ¬×à(,C¯:ezÌ¢6N¬jß¼ÿcW\î÷:€¨Š ĸ“8Ö˜BœŒäìrò¤Ä‡þà$ñ°?€T ƒ³-—Q‚ãþà´‚§CÄýìvydÑÆ6}µ^™Ž1躢‡Á‚HxÐÔb/q;° bº‚u(ËOT/¶C˜y>Ü¦á š65rz?Ïów´ý €b»ôŠU÷½d*P\sm[³Å¦5¤e£Þ‰jºÃÌXi(2 5¹øF—­£.KS23w!»'Ig m“ ,詆`óÐòòŽ«©à@ï›&¯ZyµóÄ Ûuö•^èÄ><Ê"‡3l„ \#ºa":d Ñm‘=“"/WÝt·.Í2E©®UäyµåÍä¹eî"SÕiWãCñýÿÀ]?ÞqöÄ“V$kÚˆë±îï®Gûà%Äß_Ü´ßuo¾r§¦Í&oC÷•{!vqäëƒüåKè2„º~ãÂPΚֲíÄ·è¸;ÞÛT8´ t&ë|ìÌN÷ëpc»Žl1}`ÈO7‹œ‡÷ÊñW#ì[HÊ7ÚþÆ0ðmÀIUkÈö)<³Ñ0Æ Ax)»/(Žñ;ãÏè’åw'w'‡îÖÞxn}è 7¤¥—ˆ—»|EKFå¯dO9$$%¨É{ö]œ­ŠU޼Ö#oä E2[Ó£$¯.h5)2¬ãä=(é­¡!-MÍšáÇAGË»OÒâxè˜î¥}Ó¨ƒklSþ€3v¡f÷k=óGJȲáI—®YúPéP9p¦„ðö°)¹Óyhüzz=ùË“í endstream endobj 1322 0 obj [ 1321 0 R ] endobj 1319 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1322 0 R /Contents 1323 0 R >> endobj 1324 0 obj 1803 endobj 421 0 obj << /Type /Action /S /GoTo /D [1325 0 R /XYZ 72.0 674.262 null] >> endobj 1326 0 obj << /Type /Annot /Subtype /Link /Rect [ 136.94 676.362 220.94 684.762 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1328 0 obj << /Length 1329 0 R /Filter /FlateDecode >> stream xœÅËrÛ6ð®¯Àø{&b@|éÔÔ±3é¸q©Í!Î&!‹ H($Õýú.„$mÒ™ÔÉŒvì{Øå—™‹0ü›ËŸ(ñPZ̾tk.Š<ä‡ÝR"—8^€ ÔÁâò”x=?êô~VÎ0z=ûð63„`?ÃÇìZâåìÎ/wð—ÑãìçÕìÅu€\ŒVëÁE¾ç1ÆØ};¾—È?­ ôáüR…(—w7hµkD•S~ñ­~™]­Lò]ï0é®Õ¡µ¡ ´ÿ#§öÁF@ð᎑ z}Xmúj V”l¹Å»Ðu¿J*{Ôï¨x0›V¦Æ>ž‘+N| .þvÙI¥ìqcH|’ÙbÛä¢DÈó/JQ”ç±l«S:x`ÜÕ,ÓH#4˜å5}àùf3À[Óo vú5»J¯Ðr` {©òù‹ëð¤p ””®ëƒQ'•{UÛ“žÖ|¤a”$¾žjÉÚ'v“hChÍ”Ó×>âX§VЉ5ÊË «ò<˜rZ׬vNé‰çàP^IQ¢è— Äv¶$Ƕ„ÄIö9¥¿Ï¿æl?o¥úÃ%ñ´*DÅ@ûµô‰L§gæK{#xRL†pãøŽç’$ }¢¸Ü>|biƒ.+ÖÒêHb‡x\ÉI hߊ=ø$PÚhdÏ4Ø%BTf)¸ãã4ÏŒcÍs¯z#v|8–J]Q’Z³ß°A»]­AðþΠúWFP çš ·Ô¡¯RQ–ÒÑ5(²Û"ÊAùìÉAïZçUÝ ’AöAÝvVIW5²pk/’ÞK[XÄÁké†VHð>4 [€¢s'ð”t%Òc뜛èh»8t$Iz!ìOZlAÃ)¯¿ðyÓ=ÆÏëíh"y²Èg …hái¨.kh^ÖÆ’,ó„,‡ºÊË\æ±¹ºßäéÆÀŸÄÎäAK‹Cá;Ô‹ šA$ @O24`bƒ YšM^£­€ &Qe¬’AÜrú1å£<´ÌtF,ÅE‘#E%q*q÷ç­O*Ôe±®D¡n ôŒãÅc÷åãä¹¥¢ØÒò©gf/Ïu¸‡$RlWV"(“}ι™·ªøê6¹»eÈ¿}ÚÓxþ™I¢}[Ì  Ø­ÐåÍí²#]L9Ë#C0¤OĽyø¯´B.º?/èg6‡äih™2m¡åU¢#n¨ÿ[tDp3¹Â0%ÜV¬Î3V6#¤±;JZR¸ÎÞçÙ#kjô¦L³û [”½ÄcrzØÇ£>ë3Éâ´~ËÂÏõZH2»á”ãdí58WöÿÁi–yufáAF‡Î=‹Væ¥>õ›TæqIûS- PGT66á±G 6FâØƒçÇÇŽ8‰‡÷-ñ xÂ)]<< ™;á 3¿ˆš­-^ Þ„Œ`,èØlÑ þd"µÑ¨[âép2‘Y“uL ×´¤ÐÒ~=’Øw\ž|âwOÆÙ§ÇÐuB;Ò> =Övç „à²ªÑ(5HÔ%jœ4ÈÔs®à¾/Ð ûÜË&Íèýêɾ5òámƞŤß{õru5wuyûîÕr~ýîö×ù›·ËÕË·—WãÎG~‚§Vj½+Ó¡=ðmAÛ¾œ‹}=ùV^ìÄq€qE‡Oán›É§°b)ĦV¯¡®4}'Új÷ÿÂÓ³ò ¼ïáÙ¿wәȎ+ñ±õþrÝ´éè‡rdRý‚å£ù6÷pº¡å#«5Þ&cLƒ*iŸ[YwMô y½ei¾ÎSÊù ®aœkd|ÖôˆCN$Ä%3ÿaÚ €‚‰ýĵÛTUÁv6,¿Fõp_‘–!2ˆÃ#9+ÅDÎãÃdè`9µ%þ§¾«(=ŸLñìU*X³Yµ^Ëy¹Gè°Ót5ƒeFöH´K c´RÂh¦aåõŽÅ0Œj¬ROµèæ¸d B(?øL»él™Ërj‡‚©|ƒé9ŠÀeqdc2n.âæwœxb-|¸÷N«A±¶îõD£mû|Ää¹^ØLÔ÷#Ãû–ow\%µZß啯j. ]ä·¼Ö²½*:á²·xžC›‡!}NB'Aç×¢þ–{>,qÖ<«´¦OÒÍîÖv:ä_· Ç6¨>C£,¥êáìðž„У79ÌxƒB H±Scg§ì–&ïq‹‹`ì> endobj 1329 0 obj 1758 endobj 1331 0 obj << /Type /Action /S /GoTo /D [1316 0 R /XYZ 72.0 720.0 null] >> endobj 1332 0 obj << /Type /Annot /Subtype /Link /Rect [ 326.23 675.5 418.44 684.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1334 0 obj << /Type /Annot /Subtype /Link /Rect [ 332.23 651.5 424.44 660.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1335 0 obj << /Length 1336 0 R /Filter /FlateDecode >> stream xœÅZ[wÛ6~÷¯ÀcÜc±¼‹ò[ÚMºÞãfOÖîö!Î$Q6¨ðbWýõ;€E´¹ÍÉ&9Ñ ˆß ƒ!¿^ć¿ üY®B²9\|UmY†$JUS’’ ö„ˆ¢R`¯vüÈN@ìÉïüÂ'¿\|ú ·Äç 8œ¾»øØ›Ÿøß}~Ÿ<^ütñãû„>¹ßˆ¢ÔKƒÄ÷ƒ4#™…+ü’ûùôæoïÞ/þ}óî÷ÅÏ·oïî.?“û\¼»?[N„ÿ‡å|:ý…‘Cø·ô„¥Ï$±þ¤çºÝ´Š #Ù-rn|T(³©_©ˆ$åzä¯s¾Y†ß_Ź[|×ÉݱDÁÀ÷²3_–‘Ó¾3j#CâÜîõ$cÇnNǼ&—$FÏ|³++M7û\Ó›²h\³%oJÍ<ïÙfo•ª‹²ÑÌkOs÷{ff]ç{úÄʶêu>õžšyŸòªbÛmnTikÆ­³Kýø0À‡þ‡ëízXtR6ìB $XVrÜÃÜO´`[ü¿Pi•_kG1v‚¢í$l4Ön¬[ÝT°H§fćdA(¨Q1º.rRäü±Ù“ÍžVtÓäÙ±¼Ø’öHÐŒbX=X°J½ÇJ–Ñhضù޶E³-äÀ? †³Ì‹cß÷Ã8k¦µ¨=ë.xât< Â. ¥c9ÒŽý‘o]¹](Èo™ÁX0äh`îÔ"Xn±4¤(ù£ø7ðÙ©T~Cÿ ýð/ûÏ*þkþ³ôgúBhÚ¾Á.³é†ÎíIa4sß“Wš9áÊÂYpMúRh±¢„Q0€ãÒh5/>2Þäù\¯Ù#‡­¯„ m'Z7$ kÖÔä™ms—‚?7DuÓh³ ÌÛ×»¢¤s°hî&ÃMêÏsŒa‹i%“y†æíaÝÙÙ2Z:×(r¼É5/çÙÄŒIŽ£®æ§aü4ÓÁßríÜ*ËŒg{ä‡ä¥nDzj`¬O„ÙÒ†®i“5Ý|Éù¶þìZDúyYÌÆŸ\Å8;µ®"H¿é2‚y>¸fS‹°'cãE¤ñ7]D8Ïõ[Î •®i±hØÁóf–h~I±ïäÍ”º[§nP©TÇÖínÇ6,çMq2­ƒáÄí¢ëß”Uï5äù"<óàŸ=ueÝ®C´¾äþ8¹‡CK¤÷;Òàe/„ÖêÔ äîã­lƒyb Wër™tŒ§øéæ—›÷N£&ó¢Ä3øÌ´=»=!ß •=%I ©îpŠëîzÝC´Mm•¤óÞ¾5 ªh8Æ­òï™DÝÐÃÑ4Ém䙆nÑéhGFð°ôÓ`´úŸoaž‰½ ’Q¼Ê’(™îX•Oà¾}^ö.uL w!ÊÙ±-(^%É®å$jÌUT åú?ùJ Ûik;óºp9/²¡Éf%v¸­L$0»Sl[å7‚Ñnë]kVÞÙ%Ýy` *4û²5ãP~2bÊ‹ƒ{PaúÀ4à&åÃ¥n”7P·çN‚w{Sy¾¿„¼{¾;-A4È|?‰–n0;ozM€z¥í)V)ò Á…'dY£pûÎj^Þ³m+1í¬Ãý’^$ÝGÚ1G;¢Ût«ÚMÓV"ä‹§µØÁY€µ,þ;m­¶r–„`-§â½/ø |•qÃËjš õnÕ«Ѻ>v“×õâe`E‚(œ—ž­Ëî?´_¢¤É¨>W£œe²xìô÷îÌcå–"«kºÀ½8‚ׯûóÃÍ„½]§ Ü.n¬gôs»±`æÛÅK¸5òÆiy%U³+h¥yY M»('©é<% C\üð—T ý•[XO.â®R#RÇääójBÛ‘Ãtå-ý؇¼jl*·O…ËÄ-¦g-«W(e^€ƒ†ñ¸ø2åd‘Ÿºõ¼ÂÙ nµ12î¶­Q# £ÚTèè2aqä… Ìÿ^>çP_™uÞJæ–ÕGÃÉtÄðyŒ(Ù+Zë¬xÖë§Ž~÷ø=íÞºzvhu‚;C; ŧ­bÈ !³a3iÁ4œì-³vC@k§b>Äm/Â0d‘óýÛÛ»w5–ÀšBÛÙøŠ !K±Ív2PQiFkw@ CðSá$Muÿ¯ßܺ…I8!ꎦ3ë·_òÓsYmÿדëLÜ¢ÍÌòh}:¬Ëbf}@+Ó—¶è2³0Z°Ú]©°—jµ&(‹…ˆçŠ5ør…5x Eé^¾îbM~¨;o‡¥à¢Œqèd•Ó­`q¤&çî×>3‹ªO JwÕ÷¤¥4Qçfqš®ÒàÊ++´|``¶,jfQ—V=Míö©5 áW/)†L .2Ö7ƒ%Ù_'CNÇR2K“¥ª€Â]Û=ib¹–·/w äû)Œ§{KuUt}Ì7lÇäSµ©sFqœú¬<0¬=UBqú%x× ¯µVáî¬X|ÿÝŸ•7åUg}-ÜøE«È‹“XÂ`Ar»^|a|"ÆÁ”|_¡¾¶¼l¦mšúCMžXÕ´ÔñÊX !IS2’´zmXë‘Ý*R€.i¹dÐÌžænv¯“Ð 3³µunt‘—ºñHÒW$­=ÅŒÛ_ØIÓûÓ1çë>â¹ À¨ +ôzÒ*'›’C†c¤åÛ¼ª7X-½#=Û²p±»eG"×O%Û.D1q£Š-’°ö$À,h¡©þ–•-XIwùzR1U–œÈ+ÇÒ*WìúÔ å›žÐÎ*$mi›ž?üvkzIo•tç­c³&þŸ£ËlÓb¥Ó.È—‚¥¿z¥•Æ"ÀGàȦŒ7µÛRÖ ÑK£®2,)¹)¢®V+)•@i^æ0š­ò#œN9oä‡:JškRmœè|ã(¶Ó]7åàhµ,—È&¹!J™ì ¢Ø,RD ŠøfB~Ç$±ùÅ’h¸—7,AïÊ¢(ŸÕ‡G¢Å| ¥X ºn£UÞ›J½ê¹ÖM×c¼-Š+Ót¬ØV§ Ükm9ûÚæg ÃZ.5 KU¯.ÞüzBÌÕ®Û<\^‘ë?óªÜ±¢°<%èÛ×´mÊã›*?€)-Ýl>¼ŒgûðHäųð ‹ánì‚L"#1£’fKt,ÑèÔ5ËH`â@ÿ8ÑÔñ-Ε¤ĶWz,†³ªØòúÅé,FÍÒÁ:Õk)8 ÇO‚]UÄQ1]ì bHö¢•eÄëi´WS²ò|êËúþú³cÚXý¯ß{à‡cALgâÈK»÷‚¼ÙšRìÊ4 ÜpÏgj#Í«Ô÷š&éesE·?מÓÍŒ{Tsë^O•¤tS–UoacGJÃa ‰•ì dñELGwE› “XùiS†ÉP1¥õ@à¬SË Ïye*ë"¯ !ôÃÉÚÛà#Õ”èH: ‘±  ã#VAHÔK$­RÄÈdžf…ûH’jª{óÒÍ0Ì ¦ÔUè3gÉ M«Çcî•U»Q5µ„tÜ­ïgQ/c‘t•7mu¦¯¯xb»©ƒ@º­ðÉÔû²/ý%»6ÝŽ­éÅägļé„{š K’š.â|¾ê‹sûX¢ã¢gÙ^î&ºkV™h´ ô©~!ããÅʳ—3 endstream endobj 1333 0 obj [ 1332 0 R 1334 0 R ] endobj 1330 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1333 0 R /Contents 1335 0 R >> endobj 1336 0 obj 2811 endobj 1338 0 obj << /Length 1339 0 R /Filter /FlateDecode >> stream xœÅWmSã6þž_±C?ìZ–í8¹;fî tÒË@9ÌÝt.7'àâØÁvàhÓÿÞµüYrÔÉŒ¤•vµûh÷±|Ó! áOÉš^_‡Ù¼sSÈôt V!2- †ª›0‡¢oB­jtô²‡M¾;Wð¥v4ø¥óõNz ¡Â]GÍqå³ÎicÿlF{õý5¸ì|p:?™@4p.jˆ¨¥ZÄÔ4bÙ`«Tïgξv‡GÊçÑð‹r0~v¶ó œ_;Cg-Jôÿ!œSî÷Ÿ²ŽÿžÊOzmÂ4´õ™FTòZÊ7¤¹ %ùÞÙTP[ÑæŽäÝ<ž¼Ý‡V‡¡5£XO‹WÝ|sFô2E¢©öZ.ž¹1^µÖAf{WñôÅx žØf‹eåÁ¬À9ã!¬àÖgWn<éê†6ÙAÁïóL|öø|<Î{ù³ÊAh×5•Z>É­ï*åS÷šÃ]a®ìí¶mS]°{‘/”œª˜T¥5ˆMs•óÄ/aFñÜ ü¿˜·g¦Qz·>»Sf›$,1\XÄþÜïášÝCÁŸ‘BzÅæ…ƒr_)Æ–àê¤ë± ¥ÞÂÈc0éNvÚqöíVœ¸°›i(¾w6cIÅPIüÐOݘÇÅ%m›„ˆgÞ/øaÊ.Y oª\û!ÚŰ%¦tù9¦Py…I»h/AÏÑ©T —A0Ù‘EK¨Ñ67é¦~°F¬Å¸Š´sÇ'Ý"o§mþ“ìdŠÀžŽ!u§hèøäp8¨ô^0Ÿ‰-¹‚#Ÿ/1'‹¬|°ö@l>b"®à]¸Ë ÅÞð;-+DÒa}FÏuMÌïGðÑ!ú„ç>é‚üQú~›ß>*êx˜DˆxPÏËQôU7EÜ[¥¿L°Èòz–¥©nYœ¡m“šÍúÏÔÖë¿’TUQH$F{vËèªÿ§´Þ×Ú[a¸þìºÉ]|X Õl›J™jº£5ZO7hê"º5 œŸ ?IH€R»Mùòï4Sk<¨%‚ôŒ~÷Œ–ß|2x:P[<$´1:øëåÇÔ?í¿ÜyD’ü\R Jø·†m™½\gÂXDíC7½ò“j0¬D¯ÎÜ„íU#³£ZDi­]4̱ªß ¤R´Í¯%•ŸÑ’¨ܺ~ÀK¦”øáƒf3^jxºC­9­í¡B½ÆM$@T- 3uÒW{н‹–WØ÷›¥j5>Bþ©çÜù"à0ª>ÞËAWÞw§Ñm=ª©¦­] Ka‰ha#¬—W ´§2Jª\ˆÝÞY%˜¦€@ºŒCôç‘»©a‹é0Æ ÷‘@–Þ@Ê’T)ÞQs÷ï“Hþn8cÀ=®.™øÁ‘ÓöV¥±Õö¿¦xñ<ö×¼-'«ü»Ü;þâÛ’ó»IDÒûémFLð7Ñ4úöõ!ùg_¢GEÊ©PY.<7eJŒÅ{‰rGó“­®r§X’àM¥žY"oÞ€ªÂ»}£‡6Î ¿Gá¦Åujß{æ>¿Ÿ#Ï!­îmKÐØ–îØ±Èw|ûÉj[¤t©ÌI· û½Œ–÷*HäNõE rÊÒÄd%’E†èyuve®V>•.ñ/÷ÓοÖêj\ endstream endobj 1337 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1338 0 R >> endobj 1339 0 obj 1251 endobj 1341 0 obj << /Length 1342 0 R /Filter /FlateDecode >> stream xœÅXÝoÛ6÷_AìÉ)*Mß¶ü0`kÓ¢C1 H°b¨û@K´ÍE‰Šëýõ;’I[tPt@gðuŸ?§<ÍBÀ×?‹µ¸ÃS~™’%è(P a[ÔâÅP0pnP´ôh¾mY­¬©–lqÁY«ØV“\ 22+‰¯¹‡=i‰1gÑ5nNæA×õõSÖt–UÌ5ÓRš'L“Ë 1â[+Іµ5®è?–¢‡¤›âFÙ8Ò—çÐTæGÖ>î•!!KÃ\ì 'ahn‹ 1˜…nÏúª4ü?[â”[¢ìØXz´ÙU–ä#9Y^XÕ×–ðú, lÈ’n·°U 7K ®ÉúÆ[O´ªÆKNeä À‚5SB(ZÀ[4-Á#-pe–žqÕËøÛ÷+Ã4P\†ÛãÎ2{.åÑòµYéç“Y8î©Ú¥!Žë†¾Ùaé¢YpipÜbš ݺï¸fdÕ+’<õ¸ò5ûë5]à¦aF Zˆ¦MÈŠ—™)R©¢-­q{Ò¼*-E³Æ„ø ”ãMEŒ¹µmûƒ¦ŽC­+n(õ!£¯RpR®o|LYtÓpö"?ª‘]D¯¨ã«HÕ¥ÓRw.©±F·š<±¾ÕŒ<¹šªBÒ±ÓUŒ›êà(²ª^[1‘Æv¢é’5Feh~“XÇ¡ì׺!H6Íã"™œSÑ)Dh‘Ÿ ¬*F²’ó— ÕÔ¶¯ªÓÈ´äÐ’·êºR²)Ub’,7Ú¡ÖU­N’,ZÒzÞÉ>$—^DÍZb,bm5ä\Ý÷´T–Ù*g—Gnï¾dtÏÎuí(!¸È ·µFMT5œ&G6;¹¦ú„$ûF\óF| }ð„-s#ù–2†ä^ÄxÏ*»9[r4ÖJâÈ=¿ìÜÌ÷’]ÿoÑ}dM𠉛s.Z7i¡4^kd·B%©'^K Ö–—²G›Žã¦ ã„C%úÑ&˜ðlP PWq&y//*žÛ¯¸>Tãµížn"h£i˜Á"]˜þ°eUÅŽâ ƒ $0’£Ž,ÆÁbvi1Ìs?Ñ-c‡m9×] 'Š„²˜OãÄ¡¬FÈ®§œø£ ×”-9ç.Ó8UšëyI¶Þ3%GOU#”V;±=®Ù¹ÆÊ(Ï.Œ _Ï÷„îö­Ê÷H¡W ‡~…‹‚t Qãs~:^ÃÜ1cˉmýYцrÜîÐJ™rGÁÔÀ&Ķ¥PRWƒÓ2º cÁüx ¸Ÿà`Îar¹2 mù¾„¡"(ªî©Z¡Ã{ŽºeztÚN§[#l—^¯¬X¶û†>Ã^㩃AÚé sìl=Û@Ï5à>CŒ0KØ;¦$g·F ­Ö7âëð‘_b<)Rת^¯\ÁhQ§BÙ56%¡<+)çå—D®‚J¢oóÆU¸‚V0> endobj 1342 0 obj 1584 endobj 1344 0 obj << /Length 1345 0 R /Filter /FlateDecode >> stream xœÅWËr›0Ýówé,p%f×GÒi§›L<Í"ÎB1²CÂ’Œÿ¾âa‚Í'îLŠ=ƒFÒ¹s®ìG‹1»|y3ËÄzlæ(x ÑLqÔ2 4cq¹«3`»‘yÕ›Ìà®-mønÝܚň¼XäÐ\¾².;þËòáþ ¬­/sëÓJ`¾z¥ÈSA9!TøàO6+ón&ßÎ/ìß?Î¯í¯¿>_]ÝÂü§u>ßKÇ¡ì?¤sYÅPÅ_™™¯7­*½·À]²¿ÒQA;ÿ:[9tê93Sû.—â¦lÍ»¤ÖùÔïÁ<Èk¤›Å¾,>Ôù°"¼HÉÔßÓõ¼A|0k½B–¾Û|f‡ù¸•°y™‹u2`ž ÒQ!³5*‘Q¼8«Óë™:‚˜Gз˜¨ešl¤ÞFaá°>‚b»QéB­UÖǸ.†i£k½arEØ@úÛ…¹’Ë¥Êó4•lât«”=hÀG ¼³"Bð't4CI1 H¯Rn³—±ÌsôL F÷i¢ìµ…±²PŠðdÀ«4SÑZWø18Ãxƒ WèR:Xi¨‹ª'‘Z nø ê¡b\>­?4FÕOƒAöûoРFNQ£ïÐ.Ä ;¢¡‘â0縄JÏ(Ö=A?LªkùÜáÚÈ0Ì Ù*Gë#°êŒÙð]ÌÆ±úÌÄj¤>»0.J|Ä\÷¬í0„³ƒ"ÉA°ƒÑgΟ9Gª°ó8-`8dã­.qQ+±Ãû´®îd®ìBÞŪåj僚˜„je?Gêe¿Ÿ³¨Y?e³s2Ò ]2.C1¢CúX¦:/2iÚ[N [?Å1b€aŠ8z±bjxãÍêrD ‹É:KŸ6(/â^¼åÅ?NÆyirDoP”-¤Ýr†RR·˜<Ëly/3s±Ô“ƒRÓYºDq.ÂÈb²1Ç6 •.°Úq¬Õeï¶m€hœX£íĉ ð&›)ª F€m§Çzº@{é»ï\1ÐUÛ^>Z1ÐV‡nÝêÏÉ¥õzfÇ endstream endobj 1343 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1344 0 R >> endobj 1345 0 obj 813 endobj 1347 0 obj << /Length 1348 0 R /Filter /FlateDecode >> stream xœÅW[oÚ0~ϯ8â‰>„9vìú´K;mÚKU´>”ª2ÄP¯¹Ð$P±_?çrȘ*u)ÁÎw.Ÿ?Ÿc^,ˆùØÅÍR˜EÖK=æ€G‰zˆ pÜåAýÌ!,Þj<Ð퓹U/™‡'¸³b‹ÀWëþÁL@ àÕ"ÇæJð­uÓð_Ìw÷O`a}[®98Æó=EL „à q„þ€ÑaqQGpßÿrumÿüvugþññööâÆß­«ñA:Ì¡ÿ!›2†2þr‘©ùzƒr¥&¸Kg*ØïGK‡¬3#•ïb*¬—­¾WTU>ÕýddŸifq(‹wu~Z^tÈÀ?Ђãù'ðάµ²ð½Ëgxœ[ ›¹Q%Å5ÊT±'“‹*µ&„’Ä\ÂÙa&}-Ãd£TÖ0ÚÀ(U2P)Ì’h)ãÝw] Líg0ú•è¸ ââHÇóÄÄ[ÂìY(³ ¶¾ÛV„XÑS)ûYmŒ:~À"MVK`”ùeÆÌѽKvö±ÊÙ”¡ä”‘Núk™Îžd Œ þ\lÖ‰ìµ W z=%HY–|ÎxWš&\Ô©GÛp³SuŽŽú.æk–„«(†^zœkXœCa›ÙÅ &0#>>‹VF» *\¢8†2³L²\†f‡Èò3·‹ ßz‰@8ÊK·¶™@ùhIßMD#3¼0²a›Ó¦2Sv.§¡*ë"Žuã4//!2|×P2˜ÉLéÐ1”W“u11_Ä$=&¡U§·¶íî‚íºmfÊ‚]àM‹9XcÕ4j‘£â‘»âxÒfgùt¢/³TªÍ¾Û&I¨ —{£ÛP›"À]³úëÙÁõ1)ž:=ÔV‘#ÁÄÙ<>ÈŽöÉ„îãSCžbû¶> endobj 1348 0 obj 933 endobj 1351 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 240.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1353 0 obj << /Length 1354 0 R /Filter /FlateDecode >> stream xœÅTMo£0½ó+æØJ…(_Çn•®v•în´=T=8à4H€©MšÍ¿ß1&|%ÑÞ²!’Ç3öÌ{o> >¦Z‚Ȥ0>ZŸ ®ßº<ì;Ëñ €Öö W§†s°pÑ‡ÐØÀ‹Q¾¯oLà…A¦éšËKc1¨¯"äâõ ¼_bãöÑ›@¼î%²‰þBËu”‰šÅ¼^=<Ïîã™ùûÛìÅ||þùd>Ìï—Ëë7ˆ¿³xD˵ÿ@kÑ`Ð> endobj 1354 0 obj 639 endobj 1357 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 463.156 252.0 471.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1359 0 obj << /Type /Action /S /GoTo /D [1313 0 R /XYZ 72.0 720.0 null] >> endobj 1360 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 451.156 228.0 459.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1359 0 R /H /I >> endobj 1361 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 439.156 240.0 447.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1362 0 obj << /Length 1363 0 R /Filter /FlateDecode >> stream xœÅW[s›8~çWhòä̬U]¡¼y³Énw²í¤ö´M§ƒAŽé`pÇõ¿ß#ǘ´/©ít$ëw.ø»CïT?„d(Ú8ß›=ŠCÜo¶<Q3mP³öPªoõ¬]ÁÃ\‚Å}r2‡ ¿Ï_à0Föy.®fž;÷=ýú„¼º~‚?Λ[Q‚+"îcŸz„P?@æLêC‹ ú<ùëævúñíͧéõÝl>¿ü‚ÿ:7‹#w8e¿ÁûÚ†Úþd?k¤<—Ÿô² Û·»µBnö`ÇèÖGi[ó4†˜¥ñÇ<ÏúA¬¤ïÅqZ¼ªòó!4#%88Ê*äÙx娩uwþÈçþ¸ub{Úß7ΠúsU¨ªHÔS˜¢«X­TQ¨ØøØçesŸÀǧGÌ¥ªP–¤—ú{ÊÆÙ ÛÃäj–jZ…ËT¡ ~ý–'ÙÅ0¿ëª5ßÜrD!}8§GÎê|ÇBC'(7Œó$VèfµRQU¶ì' ƒF)0ñA% ¤a¼.TX©…(S{t}÷~Ž¢4,Kü²”yØA`E#lV b´<ŒA]‰Â@¢ô 㻼Z'ÙãÏ(¤ ô27 ïÍHm«$ÏâyRíB½ # {\Héò ÕŸ©ŸPÎ8ÁRð˜7€Í•B³´Ì»²±Y«¹>–®«Sw8mÉI;Žj<¦O‰ÚOWE¾™Öh V¥VàG @ü‹Ê*Ìâ°ˆ§ñrš/¿`g¥C—øEóã"ߎ_‹9_NÌ—61Ô(–jP%…0,‹µB—h é1 #H‡´¥æ÷wí²:l»K«¼èî·‹(Ow›¬¥bµUY\¶änÛ‰±ªâ* HCÒIÚ¯“h=ÀÝ7­n-g§´¬rè\¸%gå@7‚vrаVì{˜¢‰ún¶©úÃî4ú ¡1³T[ïf㌡Z8N“êà Ā9“§°ˆÖaoèøØE¸ÐvÆ€™OàÍÅ…šc|@ µ©Üª(Y%ªgth—Mxß:lÍ9x¦wJ ØòqöáúŸÙ‡‡Û“;“‹n¿m4í¥èž/ô°ö=Ljˆ?³]šZÊDa¬­@Óð´> endobj 1363 0 obj 1190 endobj 1365 0 obj << /Type /Annot /Subtype /Link /Rect [ 453.5 594.382 537.5 602.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1367 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.727 582.382 364.727 590.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1368 0 obj << /Type /Annot /Subtype /Link /Rect [ 510.001 582.382 540.001 590.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1369 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 570.382 210.0 578.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1370 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 441.686 231.66 450.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1359 0 R /H /I >> endobj 1371 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.796 441.686 541.796 450.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1359 0 R /H /I >> endobj 1372 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 429.686 258.31 438.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1373 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.621 429.686 541.621 438.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1374 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 417.686 254.44 426.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1375 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.648 417.686 541.648 426.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1376 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 405.686 202.77 414.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1377 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.983 405.686 541.983 414.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1378 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 393.686 242.22 402.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1379 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.728 393.686 541.728 402.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1381 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 381.686 187.23 390.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1380 0 R /H /I >> endobj 1382 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.086 381.686 542.086 390.686 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1380 0 R /H /I >> endobj 1383 0 obj << /Length 1384 0 R /Filter /FlateDecode >> stream xœÅÝKsÛF†á½~–Iª„éîsú¶t,9“”ÆšXœÉ"ÉBÊÖ”D:¢Wþýô!Á‹DÈÑ;‹L’*à×@7„NHè·ß¹öï¡ýÈ5t—w¿ Ë|—C'iXSçµ±»ë†éØÝZjg"¬§ÚU¨M|è~:˜¸î»ƒŸm/^u®5ø|àž®nÙøìàÇíÛ+î/ßþnćÿK¬K•¥Khÿå~‰óè…¨îñ+;p›åÛ¥Ë ÊjY[²Ú¶½t;ìéáçª#«ÉÕxV?Ÿ‡ÛÃïÇa„ÝÆ]÷þàÛÉÁßÞÄλnr½=γ5ô®/¡Ú?¡›Üu?åSþú×nòÃÁñdïø‹÷Ú¤m{3é‚öeÙùGÃò²<€‚ïCÉι”V;½øÏôò¡;½¿™Î¦WÝÑùÃùj¤›¦Å÷Y‹sÞwÑ÷^£í¿j~4½¾™Ý<ÜÌgÝÉùìý§ó÷Óî—¯NOŽN~ùzµž‘}¬¥Ë¥wškMqØÃ“ÓîëÎ÷Ú­û´ž[wm˜·n¦·›–lz1Ìo:³^ðñ~þûÍÕt±ž?¿¼œ.6sóõÔýôöÜV|~»^röãÉ&v~q»]ŧÅÍìý“Ö†XÝ“!¾žßÝ-{z˜s_Z_o·s›Qóg,¦wÛù_¾z}rz¶Ȱd¾l±èwÚ,»8Ìl:9ÌŸßO·3wç?.÷é:<ßNÛvö¶²]ðùæáÃNÃÓGÛßßÞ…';âr~ûén¶è.¦mÇuCWZ·ó¶¡ùug+]öbµñ~d¥í0;€};‡ñÙÊ·K.¦Ÿ§ÓÙÎ’ao sÛÝ5,8Ÿ]íÌ­wÊ0»³W†%7»3Wv`NwÛ¯÷ÚzkOz{y?ß™_Ÿ9õé™#ídŒ#ƒoÛ;üýfúùðòö|±xþÄKq´ùØ–ÔBí´WW¡áøÏ»‡^V6uy?=NÔ¼°M>;Ÿ\ßÞ‰œ‹#Û[­n5¬ëûùÝŸŒ-ÔÐÖ•j©ylmëÞÎÖý{f8—ç³aêb=®«éí”K¥]Þœw.»±=yu?ÿx8²Ëµ< ¾tì^ÆZ÷ë|¶Ý|»úû,½z­UB]ÅßΦÏnÁZÔÔÛ@~tƵ3ßöëÅü÷íÜõ§Ù¥]<›%÷Óëéýfnyµ&wV2\W3뮤=hï{‰É¹Pü~§l—=Œ„Ú§ÒšjÒý¦›M·+ÐX÷VG̰܎™~3;ùp³†õg3³ø0ÿt{µ™Í6ÓÛí\ÎgןÓ«'GH#®<îòò`\öëÙSÌå>¥öŽ]Ú»×þßßÿô…£Ê¡i·xh§ç]{oÞgÒŽªvÑn/ü£¹.DéCpíhs:<¶íZÿzÞÞÝg_¸h•.äÔn<Ôµ+×úb4yõöèÕ»£Ã£oO¿ýáøõäÉÞò±Q7i'¶ßöÚÛŶÔíµvç’$½‹íâXFÛ=½Rú”X¼¢x,Y¼ x{ïAqeñŒâvwEâLµ2ÕŠTƒCªÁ!U;QIÜ#Õà‘jðHµ]"X©†€Tí͂ą© S¦ªLU™ª2ÕÈT#S¦Zœ—öËúKâÅS`ñÈâųgqeñŒâű¸°8S-Lµ2ÕÊT+R‡TÛ‹#UñHUØmÖãØëwǯ&LJö™Ã7ïNÿqøúäÕÙÙ^ !ô­UÛ’êÈ:–= ö©Õ½v±Ï©5Ì1´Û+´Ax»{EqeñLâ¡%P\X<±xEñv‹âH5x¤R ©†ÀT…© S¦*LU™ª2Ueª‘©F¦™jbª‰©&¦š˜jfª™©f¦Z˜jaª…©V¦Z™jeª©ŠCªâª8¤*©ŠGªâ‘ª¤*©J@ª˜ª0UaªÂT•©*SU¦™jdª‘©F¦š˜jbª‰©f¦š™jfª…©¦Z˜jaª•©V¦Z‘j{Å‘ª:¤ª©ªGªê‘ªz¤ª©j@ª˜ª0UaªÂT•©*SU¦jÐâÑ ©/,+ :|nc¿Ïn¤Ò~Ù};:~³ªŒ–>ì7@ûr³†<ÒÖºÖnõÂ~éþ|­í}w¤Ý^µ¡é‘xÓCqañÄâÅc`ñÈâÅ“gq¦š˜jfª™©f¦š™jaª…©¦Z™jeª©ZeÅ‘ªUQ©ZeÅ‘ªUI< U« ¢8S¦*LU˜ª0UeªÊT•©F¦™jdª‰©&¦š˜jbª™©f¦š™jaª…©¦Z™jeª•©V¤j•AGªV$qT­2ˆâHÕ*ƒ(ŽT­2ˆâLU˜ª0UaªÊT•©*SL52ÕÈT#SML51ÕÄT3SÍL53ÕÂT S-Lµ0ÕÊT+S­HÕ*ƒ(ŽT­2Hâ©ZeÅ‘ªUI< U« ¢8S¦ÊjKÊjKÊjKÊjKÊjKVÔêjÍ2¶üf•ÁZÄ9ŸÇÚùF*ƒíÆ'•Áw§ÿü³FYÍ&ØÓ‰BYòt™Æ>•¥Ej­IFÚoP¼¢x ,Y¼ xõ,®,žIÜŠ7(ŽT­xƒâHÕŠ7(ŽT­xCâ©ZñÅ™ª0UaªÂT…©*SU¦ªL52ÕÈT£©¶„–ú’xr,.,žX¼¢x,Y¼ ¸=”ĕřjeª•©V¦Z‘ªoP©Zñ†Ä=Rµâ Š#U+Þ 8Rµâ Š3UaªÂT…©*SU¦ªL52ÕÈT#SL51ÕÄTSÍL53ÕÌT S-Lµ0ÕÂT+S­Lµ"Õö‹#U+Þ¸GªV¼Aq¤jÅHÕŠ7(ÎT…© S¦ªLU™ª2UûXWj I™ÔF–Õ ö,ù2ök‚/cë’§Oß9ùþl²*Ùïmìs bÏq–4ÒrùÐ|gc¯jcßeÊ­eHa¤á^±Á¾ËDâÊâÅ—Ÿdkw°ñEa!áD„í;L/G. lß^zyXI8ƒp"‚‰&"˜ˆ`&‚™f"Xˆ`!‚…V"X‰`%‚Ú“ÅAÚSÅ_ö@О(Â@О&Â@О$ÂDPˆ A!‚J•*ŒD0AûÞQ{C^}ýñŠâö½#,^P<{WÏ(nß;"qaq¦Z˜jeª•©V¤jO Gq¤jO 'qTí©á(ŽTí©á$ª=5Å™ª0UaªÂT•©*SU¦ªL52ÕÈT#SML51ÕÄT3SÍL53ÕÌT S-Lµ0ÕÊT+S­HÕžŽâHÕžŽâHÕžŽâHU=RÕ€T5 U LU˜ª0UaªÂT•©*SµO3¨ý™[û®'( ªý}ˆk-QGúâW –è÷ǃÿv ÌK endstream endobj 1366 0 obj [ 1365 0 R 1367 0 R 1368 0 R 1369 0 R 1370 0 R 1371 0 R 1372 0 R 1373 0 R 1374 0 R 1375 0 R 1376 0 R 1377 0 R 1378 0 R 1379 0 R 1381 0 R 1382 0 R ] endobj 1364 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1366 0 R /Contents 1383 0 R >> endobj 1384 0 obj 2936 endobj 1386 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 204.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1388 0 obj << /Length 1389 0 R /Filter /FlateDecode >> stream xœÅTKkÃ0 ¾ûWè¸âÉvÛÇntc£ J;”F›nƒ¤¥d¬~5>Ø-K’¥OŸ$gO }'”á°ªÉ>Ú("‹&™K)—PCÔ%TîTOáGÍŠpÈ*ŸðF¶á‰,–Ö¹´‚§é|pNæ=|çÁÑñ>È}Aî%0„bÓµ(M©Ð©1ZpÐTpãE ‹›Ùs^$³IžOóÛ%/dZ ÈÆÿÌÜ×à«÷#æöSÔÏyà)=½híÕŠ`³–€í\UZ”¡ >A^å ì³.Ũà×÷A¹@†T6i~uFîÚÙ vËG³ƒÕˆÈ´üpU$8åe “ªÙµÄº¼©T……ÏkNû„g·e]n’Ÿ¯ò¬ª÷¦éµëÂ2E%ÓÆ( {Ý}—1þÒ…Õ`ÕÈm&#Û’öçä Äv endstream endobj 1387 0 obj [ 1386 0 R ] endobj 1385 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1387 0 R /Contents 1388 0 R >> endobj 1389 0 obj 345 endobj 1391 0 obj << /Type /Annot /Subtype /Link /Rect [ 406.39 519.156 442.39 527.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1393 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 276.948 156.0 285.348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1394 0 obj << /Length 1395 0 R /Filter /FlateDecode >> stream xœÅVKsÚ0¾ûWì­If¢êeËjN„<šN&ÓLÜörp@Om+ÁÎëßwe0` §{ôíî·/ñä1 øºAiÃÌ{jÖ("h–ü˜$܇ š¹©;ÕšðÙ ‡úN&ðÇË= çÞínŽ€"àÕ£«â*ðwÝÒïvè§ëo[ ÿ/8ª¨Tqáø*Rgi×ty§¸ùúbµR(ê5\©u»­´ñt3Ö†ÔÓšO=näA4h·†Ÿ§œÂƒwy_Ï|`¢ñ"Ï•2JB®Ý‡C”Áí ƒý;ˆ~x§ÑZ|²×ÖétÏù`ØRÊ–hUÁU ©šÓUœ™šT‡d\øî|XNNÏz¿.£Ã~¯ÿýâêüjøÄ|I´SÁƒø€sµ ¶ oórjÓʉ‘ÇÏi Ãx8Iò¸7“ø%±S2ã :8HF¨¦(2¨EþާI|ŸÎyovW ‰ÏB­Ó3húl zÜê4-HH9ŠÓ~ ;¶65q¾[!ãÃ,Q#o yR&q •æ™Ý¡”É€øBi-EãºèúúÞùF VƒNL1œ&ebóm™Ö„+I‘æLÛ$)à¥q-¥šå˜½T¾³ãjq#ÎñÑwTrÕ¡¥Éº¦ñÀÇaöh亇¿æýÕNG0¶Óív­Ñc2ð;&5Ãr£;È4Ù¬‚ý™Ò&Nßâì15ŶàXIõÐЗ ßÁ^jJüì4q8ljçò$ì»g¥ $¬J”R³†/ck»q‚ÒUÜÑ`b˜§çÀä%”¶Ç;,oiƒo³Š¯Œî : ÆÏnG tš e˜o°7£Z3‚ã÷m Â(`T›ëáÊææ•¸e¢Þ½´°óËeÑÛ]÷‚0¿jðUs_ <…ˆ¥‹ªœÕ]µãVØç´p]Çf\ÊEªu±—ÿ‹0¥CEƒVýãCÿòæúÌ[iòÛ¼*µ¾Í2›»­ÞÏ Òú9‰‹yCÇãq qšB™d¦ -×Þ?ÄJZ= endstream endobj 1392 0 obj [ 1391 0 R 1393 0 R ] endobj 1390 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1392 0 R /Contents 1394 0 R >> endobj 1395 0 obj 806 endobj 1397 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 198.9 150.0 207.3 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1399 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 186.9 186.0 195.3 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1047 0 R /H /I >> endobj 1400 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 174.9 168.0 183.3 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1401 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 162.9 174.0 171.3 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1402 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 150.9 144.0 159.3 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1404 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 138.9 228.0 147.3 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1403 0 R /H /I >> endobj 1405 0 obj << /Length 1406 0 R /Filter /FlateDecode >> stream xœÅWÛnÛ8}÷W ü°›µJê®»@[¤Å¶Ùbƒ[q‹ŠˆÈ’CQMݯߡ¨›m*M^ºJQCÏ™ë¡F3 ÿêD6¬7³‡VF!°Áñ[‘çu-Ûƒ ´krõ«ÑÂîVxÓ?ÂE_fÅŒÀ‡Ùõ n&@PáqFáå«ÙåȾÚ!¿Ü>»ÙÛåìõ{(e:¤È‹,ß÷!˜¨ÐrìH]6,7p}ru~qþnyz˳óå^µÿ‡0.¿›âÚøXM…÷6<—ìßËicÐÑ2”hÛj+oËÕÞµ#z©ãÑ÷É8ÈG±ß¿Ôøt'J‘+Üëê’ÉøÅY;*¤²ÝÇÆã†ª¡=‹ïë`V'ËÙZÂ5ÛlsžÜÀY*Ê~,wŒÝ€v bËñ‘ ħÚë¬ ‹Û]w¬ìØSÊ9ßp žÁ ëNLÓŠIpŽu<J'å,OE¼aó{.cÔÿ$êªUWòó8Áö¸óO-ûGâ V4bƒ±ÀToÔþZ ŽšoŠD”ÛR™2©Ûä°C>ÕxÇ—›N±½¿Î¿‹rËD,yYÀu]47]0س§NŠg^£lˆýÆdÉ™"Ù€ÕžewŠdƒ²`UË…Üm'¹jû¤9ÎCÏñ&}Øg¼±û¦¡âÐ7Ðs²§Ã˜nc2@OÔ7 &C×àù@Š®Ý¡£gOÈ=•4aú£Á`-òMÖ:ÊØfÝ©š=¦|9$4¦]ÿòõ{iÙ!V—î½~ 8Ø4!ÅÙÒvÝv ä ƒó4Å^¯:ý£9DÙô©E„tÃPk~Ébɾ1LkƒÌ°ïl]7<*ÓFpuy5;Èâ P®„u=žïxqI,ãÛ¸b¯€§;ëA„8 S7ŠˆíhWÞ4°nwOÅàRÇŠÔ(eûm ŸË‚=âëÚ–«ÒzmÚο¯ÙVÅã(ÄeÝœO&Ðõ}+ÀREã¯ôg)ËYœ`^K•`B”¢z…k½l~Žä„ê!_ti\è-^AÅïйœ%ω/ò,[eÔwº¶` ÞäUٚܧFJõÀnóÈÑgKŽqhUh¶ó2´­à…\<éx/ÃLÊŸºÁË7ñö'ˆø÷"ļ,·“`Á +›ÃqÍ‚¥xÒg,A7 ÓíâãùCÔõ½ŽG’=Ùý¾šºU÷¤íþ%vú),|üÂ8é4üFÎPÕ—Aè ô+zÒ,%öSÚ½õ´.Ö ÿ:²§[Ækävžï†=|÷³ +ÔiÓËŠ£HüCgl7²¨¸žÁ™wÈúÉHì•T¦‘I¹·þÈe6¸Þ¯ður—Ùþ ë-û§m,ðÝ,ñï$«“ÇŒ¯3S:ªúÏËú@Úó [¿:o®£Tq—¢Æt –àlÙËqìÊ´qý,³¸?±áážíq<½ïÕH†ÑõåÑ"Ä¡¤¥˜ÀßÖb‹Ãà Ø~;ã&Wb¨r9û¢!t¼ endstream endobj 1398 0 obj [ 1397 0 R 1399 0 R 1400 0 R 1401 0 R 1402 0 R 1404 0 R ] endobj 1396 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1398 0 R /Contents 1405 0 R >> endobj 1406 0 obj 1331 endobj 1408 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 156.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1410 0 obj << /Length 1411 0 R /Filter /FlateDecode >> stream xœÅ“MoÂ0 †ïù>n2'i›äȶ²´Òˆêº ©À¶Ÿ¿|A[X·£H±ì:¯ÛÝhž=¤æP¬È6øH" ®8Qà ‚Ceßj|o™Ã¿dŒ7x"k‚pGfs|4 Ÿ¯sÉ™´ômÏ®ðJ®sr5Š!ä/M‹¸E×öÇ!_ÁìâaœåÃñM:˜¦£išÝ§·—sÈIšwHãÿ@2q5¸ÒÝ|¹ùKê†Ü Äv#­8ø¯Þg<^Û†ª0±púB¼éyüÙË ¶)ºqVñþe6‘!U}`J÷.À™»v2H«}àÀÌ`"²–® Pž)ý*Ê÷z¹Y/ÌÕËúcaíÇü¡1‘¡)&‰¹Z…+Æ›uI÷ýÒ‰¤±ÉÑ’…¼¬,aXí6‡ž6HFF y,‡¤+Á“ÏuWVeQ·&ôW/¸mid*2 $uù+;‹Ìw,¤Ö‘P'ðNsB¾í!½ endstream endobj 1409 0 obj [ 1408 0 R ] endobj 1407 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1409 0 R /Contents 1410 0 R >> endobj 1411 0 obj 380 endobj 1413 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 204.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1415 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 204.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 1417 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 288.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1418 0 obj << /Length 1419 0 R /Filter /FlateDecode >> stream xœÅTßoÚ0~Ï_qTZ2Û!$yìÚlbš˜(‘úPõÁ3¢™dÓ¡þ÷sb7¶!M“ ù~ø¾»ïîÌ‹‡ɯßqJ`³÷^´ CL œiS4< H{Ðr¼»e ä]’‡º$…¡“‡óú« -ó¶©›BŒ¶KâNÉß⌳˸Ñôßêõ·M½÷ËJ´´Ú0+Ë…¶¦8ˆp’¦1Öm]Ô-ÓUެ—¬ã(H‘Pi¤Bæ:«€ X¾Ë mØ 7lË&ÝÅ`*«Alwæ¦äC×TÃúmSþj%mÝ\üÉ €àu+‚AoñìIÏÃQ¶î> endobj 1419 0 obj 575 endobj 1422 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 258.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1425 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 264.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1426 0 obj << /Length 1427 0 R /Filter /FlateDecode >> stream xœÅSMoÂ0 ½çWø¸!5s’¦MÀ>´ ±Udš&ÄAH´´Óöó—6´ nk+Ù²ãg¿øuC }½Ò„‡YJ6uŒAÈAuHÀ|Ê%¤PûÖ婆Ã-o›ÌÌvî-¶&õòµ)Ž2¶øŒÿQƒ¼Ña'€Yi*´?媯h¨„MDÒÁM‘ÔG6i' Å °H*rz¹ÊÁ~SèFñ’¯"Éò•É 0P,è›45Y™ê>ÝÓÆ|1ù‹O!· endstream endobj 1423 0 obj [ 1422 0 R 1425 0 R ] endobj 1420 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1423 0 R /Contents 1426 0 R >> endobj 1427 0 obj 377 endobj 1429 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 258.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1431 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 264.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1432 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 204.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1433 0 obj << /Length 1434 0 R /Filter /FlateDecode >> stream xœÅTMoÂ0 ½çWø¸š9iBš#ƒ2mÒ`ÐN; ”íÐÒñ1íï/mmj‡M¬Ù²c??Ûéš0@óó ¡4‡yFÖÎÆ@qð;Î$;Àå2pº„Ôœª+|¯aå^ÈŠ Ü‘éÌ8€&à‹àqº28"ã~áÁ‹ã#¼‘Û˜Ü $0„xYµÈGʹDD?€€ú\‡8ƒéÕóS¿‡Þ$ì&ýÈ»žAüP‹TTaNw4p< LFÞý0Š»Ã^høÑŸñhĸ¬¡¬¿\n^EËi8¤À¦§¶?{e5A}k3‹]¸R7p'm!Vµ|¬lå ¬³h.ÔEÁÛwI iÐX¦ýÖ¸p×NY`øøÀÌ`sXƒV9\åHYNQ’@7ÝæbU^wJÙL™W÷ OnÚçÇâu—x›džoÞr“gÞ6Íwgûfÿ#€m‚¿B¨çý¡·šQÉ­s½æ»ÄÅŸÙ1Sc’ÈM*-÷!«„Ö Ç䪸D^ endstream endobj 1430 0 obj [ 1429 0 R 1431 0 R 1432 0 R ] endobj 1428 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1430 0 R /Contents 1433 0 R >> endobj 1434 0 obj 401 endobj 1436 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 264.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1438 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 288.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1439 0 obj << /Length 1440 0 R /Filter /FlateDecode >> stream xœÅTKOÃ0 ¾çWø‡'i–æ8؆„€±­ˆÚaÚ:@ꃭCü}Ò$[Û=Äi¤•lÙ±?¶Ûa€æ *¡4‡yFVÞÆ@qo’`!å2𺄴ºÕPøV3Â]2Ê;¼œ ܒשq.MÀ7Áýt6xBF üʃgÇGx#×1¹H`ñ²nQ‡ !Ñœ"*¸®‡8ƒ×‹ç§^7îãþÍpÜ ãáC0¹Æ—SˆïH?nÑŒÿ­‘­Áò°ÃææUÔN¼å!¶=mØÙk«Îf,»r¥~|^ºBœêø8y’Ö4°É¢½g?½ª dH£ÖR0-O.À™»v0È {ÇG3ƒÌf³-;\åI9N“$nZ;buÞ0T¹_†Í«÷û„Î×çb¶I‚u2/Ö‹`¹.² L‹My´q!äB(ÄG^nfù> endobj 1440 0 obj 384 endobj 1442 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 258.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1444 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 288.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1445 0 obj << /Length 1446 0 R /Filter /FlateDecode >> stream xœÅTMOÃ0 ½çWø‡†|4Msl !`l+â€8”-À¤­em'øù¸M·µû€ÒH+Ųc¿Ž ~x4t™È [SÁ>8GîÚŽ%öšŽÂ†8Ú¼E«Wפ§Þר~Ó4‰±ô´XÆ¥;š{㇠eA€¥ÃºD7.â—8·`³,ÍrºJ>|‹@S…éFóºÄÈZèÌòtÝÞ ;D %õÊپÛù~—“¸°^fÇi6ñ^³tîå³´Ø«õ'€Ü!L“¼ˆ“±m ü¦†(*þƒü0tuïÒÂþØ}œª¤6Æ—ë”ÄÒæ€|ÂIŸ endstream endobj 1443 0 obj [ 1442 0 R 1444 0 R ] endobj 1441 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1443 0 R /Contents 1445 0 R >> endobj 1446 0 obj 436 endobj 1448 0 obj << /Type /Action /S /GoTo /D [1364 0 R /XYZ 72.0 720.0 null] >> endobj 1449 0 obj << /Type /Annot /Subtype /Link /Rect [ 368.663 627.782 403.653 636.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1448 0 R /H /I >> endobj 1451 0 obj << /Type /Annot /Subtype /Link /Rect [ 360.414 594.382 396.414 602.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1453 0 obj << /Type /Annot /Subtype /Link /Rect [ 521.999 548.382 539.999 556.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1454 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 536.382 246.0 544.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1456 0 obj << /Type /Annot /Subtype /Link /Rect [ 265.44 536.382 433.44 544.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1457 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 502.382 288.0 510.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1458 0 obj << /Type /Annot /Subtype /Link /Rect [ 294.019 502.382 432.019 510.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1459 0 obj << /Type /Annot /Subtype /Link /Rect [ 455.998 502.382 539.998 510.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1460 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 490.382 180.0 498.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1462 0 obj << /Type /Annot /Subtype /Link /Rect [ 172.929 468.382 310.929 476.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1461 0 R /H /I >> endobj 1464 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 388.486 204.99 397.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1463 0 R /H /I >> endobj 1465 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.97 388.486 541.97 397.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1463 0 R /H /I >> endobj 1466 0 obj << /Type /Action /S /GoTo /D [1390 0 R /XYZ 72.0 720.0 null] >> endobj 1467 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 376.486 224.43 385.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1466 0 R /H /I >> endobj 1468 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.844 376.486 541.844 385.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1466 0 R /H /I >> endobj 1470 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 364.486 313.31 373.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1471 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.263 364.486 541.263 373.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1472 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 352.486 230.0 361.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1403 0 R /H /I >> endobj 1473 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.806 352.486 541.806 361.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1403 0 R /H /I >> endobj 1474 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 340.486 259.99 349.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1461 0 R /H /I >> endobj 1475 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.612 340.486 541.612 349.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1461 0 R /H /I >> endobj 1476 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 328.486 293.33 337.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1477 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.394 328.486 541.394 337.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1478 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 316.486 263.33 325.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1479 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.589 316.486 541.589 325.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1480 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 304.486 268.89 313.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1481 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.553 304.486 541.553 313.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1482 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 292.486 293.33 301.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1483 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.394 292.486 541.394 301.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1484 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 280.486 263.33 289.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1485 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.589 280.486 541.589 289.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1487 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 268.486 235.55 277.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1488 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.769 268.486 541.769 277.486 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1489 0 obj << /Length 1490 0 R /Filter /FlateDecode >> stream xœÅÝ]sÛF–Æñ{} ^&S#nwŸÓo—Ž-O’r¬I¤ÌìÖÌ\0mkK/IŽk¾ývƒ$ÌH:ÿ›lœ*ÐÓ@?D7šÔ¿ü̵ÇýG®aöîúèßëy~–ÃLÒzVL3¯óg׳õë8»ê©­aóªýX…Ú‹³¿Ý¹Ù_Žþñ¯öË‹™k¾¹ýÅ …ÏŽ~ÞZÿûÃ׿]ñáÿ¥½ƒÊàÚÿy>àìü"ªÛýÍÜ8ÿëÜa…²š×æ¬ÖÝuµÞÓëŸ«Š¬^®¶gõóÑíp_7ÃMïÇõþq+w³Gßý×ë8ónvþþëqž{Aïæ%Ôþ_˜_Ïþñ/òí¿fç?œð^;€ìë·GfAçe¨üÎfy àç¡dç\J« ;ýí—ïf§w—Ë›‡åÅìÕâa±ÚÒ±hòsçJ­¥äYôs¯±ï¿*ÿÓâæòÓç«ÅÃåíÍìÍâæÃçŇåìŸßœž¾úéÍ?¿]-jb7k™å2wškM1ìÔåÛþ›0ûf¬ÓfF¯Û8±³âÍ̱›cEÆ9Ÿîn¿¼XÞ3¾.òåíõõöÂ.ï?}­ÌnÝÎþsÿ°¼ÞZÍË7§g›ÍÝÞÈêö6ò²mÒÝûÅ»^Ç~à|óp»yuöó›ÍË‹¶©¿-î—÷óÍœ¿].¿l^¿»ZÜß›0L.îÆ…],ß_Þ »l˜ürùðq\ÏÇ1µWÍPÓ<¥vȨLT¸íÀWoöJˆøyŠâ|lW°ƒ›Õlêâf¬Ùí°?§6án¹¸Ø*p¸K½ {+ürwùð°¼™ ›Û·s@ŸOm'ÇnÑóa¯ûvÒ}s½¸¼'Þ¾y·>¶Ö3nïÆ×½Ž—7Æé‹Õ‘¹šXïôÕÄÃÖò‡ZS—÷“¡ÍS÷ϘPÊ\½:ç5MlÈýòªíÐGÏ7iž(}°Ùóqι¥rRd.ê ¼rêëS¥§vÙâêþvœø|¿œ:N$µçÔÇ͹׋Èx2 /_÷Ce3ñýí—åïË»?o¦¿|\ŽeÝxŸe4´IXë3\}ªôfí«mï¯>\þþµR‹Í‹ßWׇáõp}ØLÜ,®—ãö\>l^Ý->ßÝÜ,çêò~ÌܾËÝÜ?,nÞ-ïÕW<±óµìmÈú¢5uVf·—]_ìŽ}ó¼µ=ëéÚl2‹›­©ß–[Ÿ?µós¸(næ<ÜnMÜ-ß_­®í›9‹›ÿl/ùc{WYî®{Y·×µ¹poͯSùÍù¶½øG4Õ:oïÃí®¤Ý—îµÏŸŽ'vn {±¾3Žï¯nŽßßÝ^ß-ßÝÞ]Šú}õû(ê÷QÔߧh-Q"éÓ¨óÚ‡Eø&Êù¢‡=…ÒÚ?ûv'¯_üúæüøå‹—ßÿðö/}vý½¨Ìh7çŇڅÞyP.ÎK ÎʼnR‡ÝS„Û{+ gnoH ,$œH¸‚p{3a"Xˆ`%‚•V Øb$ ƒ‚ýYº=ì`ð@0x  †@… "(DP‰ A%‚‘F"» ¯¥fS<9O,^Q<,^P¼xWgª•©V¦Z™jEªâª8¤*©ŠGªâ‘ªx¤*©J@ªj¿å%qaªÂT…©*SU¦ªL52ÕÈT#SL51ÕÄTSÍL53ÕÌT S-Lµ0ÕÂT+S­Lµ"UuHURU‡TÕ#UõHU=RíC I< U HUS¦*LU˜ª2UeªÊT{Tðµf—IOï*›èa9_ÒDT”Çú£~ýë«ç'ǧßýxòòüìø§ÿ}üæäí~÷T /®¶ÊÆ4±´^ÙÖ`8¬ìðh¿`÷¢å›VÅûÃ}O-Þ<“›Úƒ‡ñŠâý?‰G/(ÞŸñ“¸²xFñþ˜ŸÄ…Å™jaª•©V¦Z‘êð´ŸÄ‘êð¼Ä=Ržø“8Ržùƒx@ªÃSgªÂT…© SU¦ªLU™ª2ÕÈT#SL51ÕÄTSÍL53ÕÌT3S-Lµ0ÕÂT+S­Lµ"Õa8‰#Õa@‰#ÕaH‰#ÕaPˆ¤: q¦*LU˜ª0UaªÊT•©ö/$h·ÞWÔfé ¬Ä9×?>sPΗ<ÑÀj·ç»±Þž¿xûòäø—“׿œœ}òj¯”SņfŸ›ø ~¯®(Såö7¾?GñŒâý ‚Ä…Å‹Wïo$Y¼ xeª•©V¤ÚÔ£8RíëQ©öö(ŽTûC{Hµ?¸Gq¦*LU˜ª0UaªÊT•©*SL52ÕþÑA·þÚC¼vÄ…Å‹WïŸ$ñÈâÅûGI\Yœ©V¦Z™jeª©öÇù(ŽTûã|÷Hµ?ÎGq¤Úç£8RíóQœ© S¦*LU™ª2Ueª‘©F¦™jdª‰©&¦š˜jfª™©f¦Z˜jaª…©¦Z™jeª©öÇù(ŽTûã|÷Hµ?ÎGq¤Úç“x@ªýq>Š3UaªÂT…©*SU¦ªL5>¹gí×ç»þµ™9M”ó¥Lô6µkÚnìÕÉ›“ó“ã­N§—§¿¼:;èœÈ[_ s°^ÇvùK‡}OÕÏÛÍc+âD¹©^ Ï$Þ{)P\X<±xEqX<²xAñ€T{/Š3UaªÂT…© SU¦ªLU™jdª‘©Æ®W_deˆ'ÇâÂâ‰Å+ŠçÀâ‘Å ŠÏâÊâLµ2ÕÊT+S­Hµ÷R 8Rí½$î‘jï¥@q¤Ú{)P©ö^ gªÂT…© SU¦ªLU™jdª‘©F¦™jbª‰©&¦š™jfª™©¦Z˜jaª…©V¦Z™jEª½—Å‘jï¥ qT{/Š#ÕÞKAâ©ö^ gªÂT…© SU¦ªLU™jìãø7½ ö€ÞK‘¼o墟(ç«›è¥(ûß•±þ¬Áºsâøõ/§?]Sécp|‘‰% ƒwê×/Dßi¥Æv§_ÃT¦© ÝÚ¨$-(Pº’tkŸ’tDéBÒíð#id»ev®¸d‰'ÇâÂâ‰Å+ŠçÀâ‘Å ŠÏâÊâLµ2ÕÊT+S­Hµ7MQ©ö¦)‰{¤Ú›¦(ŽT{ÓÅ‘još¢8S¦*LU˜ª2UeªÊT#SL52ÕÈTSML51ÕÌT3SÍLµ0ÕÂT S-Lµ2ÕÊT+RíMSGª½iJâ©ö¦)Š#ÕÞ4%ñ€T{ÓÅ™ª0UaªÂT•©*SU¦Ú?®QÛݾ«™´øzÓTª®þ®Ïa9_ÃaÓ´Ÿ[O4MW-Ó³7§ç{Eûƒð±Uz¸^Ç\§þ²JmÍç'Šìï…þ0Ü–ìÏÁ­I1'“9Y­IÌÉhNk2xsÒjÔ{ ŒI1‰ÙHÌFb6R³‘šÔlÍFÑlÍFÉl”ÌFÉl”ÌFÙl”ÍFÙlTÌFÅlTÌFÕlTÍFÕlT­F½ oMZzÃݘôV£Þ\·&­F½‘nMZzÓÜš4‰ÙHÌFb6R³‘šÔlÍFÑlÍFÑl”ÌFÉl”ÌFÙl”ÍFÙlTÌFÅlTÌFÅlTÍFÕlT­F=aMZz›Ø˜ôV£Þ¶&­F½ýkL«QoõZ“f#1‰ÙHÌFj6R³‘š†a˜ê\’©ø£-ÅÞš¥ÔRCš(×’­Y¿ÿ´fƃ÷ï÷íOŽ«Ô‰¥ •ÌSY[ÓӧֲϭÉ}Xnªý‰â‰Å+Š·æ(ŠG/(ÞZ§(®,žQ\˜ª0UaªÂT•©*SU¦™jdª±«ö§â~ê¤jÞ¢¸°xbñŠâ9°xdñ‚âų¸²8S­Lµ2ÕÊT+RídGª½¹Lâ©ö†3Š#ÕÞ„Fq¤ÚÓ(ÎT…© S¦ªLU™ª2ÕÈT#SL52ÕÄTSML53ÕÌT3S-Lµ0ÕÂT S­Lµ2ÕŠT{#Å‘joÓ“¸Gª=âHµ·óI< ÕÞâGq¦*LU˜ª0UeªÊT•©öžœœsuªéþh£{èˆÒŠ9™(×Úò=aÿóäëžñƒâCßÀô§Åw†`.É4û°ØT#¤·†`[Ò‚Ò ¥+Io Á¶¤#J’Þ‚mI#Ëí!؆øölK\X<±xEñí!Ø–xdñ‚âÛC°-qeq¦Z™jeª•©V¤º3ÛGª;C° qTw†`[âHug¶%ŽTw†`[âLU˜ª0UaªÊT•©*SL52ÕÈT#SML51ÕÄT3SÍL53ÕÂT S-Lµ0ÕÊT+S­Hug¶%ŽTw†`â©î Á¶Ä‘êÎlC< Õ!Ø–8S¦*LU˜ª2UeªÊT·‡`ƒßÎìÃr¾N|‡YßO“MÓþ z»YºWtwöÁBž‚}Pd/ŒC°ŸMŽC° I1'“9Y­ÉÍlC2š“ÅšÜ Á6$­Fãìç“b6³‘˜Äl¤f#5©Ù(š¢Ù(š’Ù(™’Ù(™²Ù(›²Ù¨˜ŠÙ¨˜ªÙ¨šªÙ¨ZÆ!؆¤Õh‚ý|Ò[Æ!؆¤Õh‚mHZÆ!؆¤ÙHÌFb6³‘šÔl¤f£h6Šf£h6Šf£d6Jf£d6Êf£l6Êf£b6*f£b6*f£j6ªf£j5‡`’V£qöóIo5‡`’V£qöóÉ`5‡`’f#1‰ÙHÌFj6R³‘šv†`Û[Š»C°ʵFßDkVù®«ÍßÕþñô‡·ïû­Øš²íNdb ×q•©¦l»µ­¢«?Æ}Xî =ÛîoI¼Ýä¢xdñ‚âížÅ•Å3Š·[`gª©‡TƒCªÁ!Õà‘jðH5x¤R ©†€TC`ªÂT…© SU¦ªLU™jdª‘©F¦™jbª‰©&¦š™jfª™©¦Z˜jaª…©V¦Z™jEªâª8¤*©ŠGªâ‘ªx¤*©J@ªª¦*LU˜ª0UeªÊT•©*SL52ÕÈTSML51ÕÌT3SÍL53ÕÂT S-Lµ2ÕÊT+RmdGªêª:¤ª©ªGªê‘ª¤ª©j`ªÂT…© S¦ªLU™jÿôÒŽú*éyé]C9Õõ@‡ƒr­‘½*pr~ôsû÷}º ‰ endstream endobj 1450 0 obj [ 1449 0 R 1451 0 R 1453 0 R 1454 0 R 1456 0 R 1457 0 R 1458 0 R 1459 0 R 1460 0 R 1462 0 R 1464 0 R 1465 0 R 1467 0 R 1468 0 R 1470 0 R 1471 0 R 1472 0 R 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R 1481 0 R 1482 0 R 1483 0 R 1484 0 R 1485 0 R 1487 0 R 1488 0 R ] endobj 1447 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1450 0 R /Contents 1489 0 R >> endobj 1490 0 obj 4525 endobj 1469 0 obj << /Type /Action /S /GoTo /D [1491 0 R /XYZ 72.0 720.0 null] >> endobj 1492 0 obj << /Type /Annot /Subtype /Link /Rect [ 480.001 507.156 540.001 515.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1494 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 495.156 180.0 503.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1495 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 312.948 234.0 321.348 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1496 0 obj << /Length 1497 0 R /Filter /FlateDecode >> stream xœÅUKSÛ0¾ûW蘱º’,Ë>†:e(m÷1S8˜D!îø›Â¿ïÊ–ã$NBOÔÉŒ¤•öõ}+í£ÃàÏ5ƒ 9™fΣ•1¢8¾IŸ0rI2bç’¤æÔÆ„w3ÚC8YNîùàüºÃÍTøãÀ®¹FùÆùºáßìÀ›ûߌ@0þ_"014¬4¼pü+Ú³µ!=ØÞÙ n-ï¥CÑÊPÒú6[©EÚŽm í´Í§æ}°G›áÛ9òàœEλ IhÞ×¹2Š hÀCóqeä׈êäŽD—Î$À£6 Òø^ç#Cb`[i5ä*›T›Óuœé6©=0xá!_šóA«pz>¹»ŠÜo_ÎÇÑÄý|v9yݸŸÆ?Ý«Éõ)9!.çƨ5»6Æ=‚žò‡fo9W» ò˜Bï'Zè~1Óó¸N«^ÅÏIVg½ ¯³{]öëb¾1¿ÿ­§ÕªèxºèWµ._v¢DŒ<†±ùv`A­ ²Ôå¼(3“ßE’w«=KA!LÌo•¿Çeß§kV“0*Ñg¨XØ©¦µ&ÑËò(¥ $ €£½PZðGEIò:MI’WúA—·'¯{g¼Fé ,%ó¤Jâ”4atÂ}È€J¡ÂÐVõúãÕ?x |¨”`­Ú¹^MËdY%E~´ˆ£\y€I[Ñ"1,{ïÙhµÔSw·~² ¬˲xJfº×¨ýf_q¶!¡[aìÕêÂÅ`wâå¾G7´î ËÙMõáløG´×îãò¡ÎtÞGÝÜ‚a˜ó:Ÿtqi…€"e öy®—³¸Ònqïïçbç´¹…®¹8«ƒ‰2اH_¯".ÅÆ`‹ògËT¯Ž,09ôô,’·£•®É©¥ß]'ؼ ®åéAw›6-â³¶k±ù^_ð€z¾ÆU«8žÏÑ¥ž‘³—c—@HN•‡Ï·íìºÈõ?à%ð™axí@2Ñ*ÞhMÆéªX7þ?¡¢L6 ©iF<ñá¢b«±na·É{Óh_iiž4V¼ô»Ä*}¸p̃ïg* ø,Ÿ_¿—gÖ endstream endobj 1493 0 obj [ 1492 0 R 1494 0 R 1495 0 R ] endobj 1491 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1493 0 R /Contents 1496 0 R >> endobj 1497 0 obj 837 endobj 1499 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 258.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1501 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 240.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1502 0 obj << /Length 1503 0 R /Filter /FlateDecode >> stream xœÅTKOÃ0 ¾çWø‡'M›æ8¶Ä`k‡iØ:`jW¶ñ÷I›nm÷‡Ñ‡lÙ±¿|¶“á€æ¥…PZÀ4%«ÊÆA p¼Êäz $.¤Pé.$fUS[Í»È(ïðL–ᆌ'Æ94ß÷Ó•Á!6ð žá\GäªïGˆæu‰¤Ç|í"¢ôÀgŽÐÅ# Ja|ñôØëD½„ôrÑ]%)%ÍJOz;,ê ºíîé(è>Œz¡¢V%.þ¡Ãr%‰r>„ù+‡¤åp%¶=ÚÙk«ù%s¬ÍX,váJªŽWÒnĪ–•'y`M›,ÚuVðÓäŠ@ŽÌoÍ×ú䜹j,°w|঱¾9 ¼E«l®ªHYNaC'ɳ±:¯ôÁ1ÇÃÞ2e^½_'<8j_Ÿ³—MLó$ÛÐù:Ké:žfëÙѺ)þ½.âé&§‹ìc™7²ÿÂ_iær_kÅ+þƒlWñÇ.ßXæ£0©´» YƬ9$?sÄ.ž endstream endobj 1500 0 obj [ 1499 0 R 1501 0 R ] endobj 1498 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1500 0 R /Contents 1502 0 R >> endobj 1503 0 obj 406 endobj 1505 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 288.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1507 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 240.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1508 0 obj << /Length 1509 0 R /Filter /FlateDecode >> stream xœÅTMOÃ0 ½çWø‡'iÖö8؆„€±­ˆÃ´Ãè2`ZW¶ñ÷I“lm÷!$#­dËŽýül·kÂõã•"ˆ8$)Y;ƒ€ƒh9“ló)—‚Ó%,Ë[5…o5-ì%­¼Ã Y„[2žhç P|ÜOg‚GdPÃ/=xv|„7r“«ž†Ï«µ¨õñ!¤‚Gåá§0¾x~ê´ã®7ºïÇ^oØð†Ý›þ°s9øŽtã-Áø?И 3l®ß€š‰7ÒǦ§¶ ;{e5€ÂÚ´Åb—®¥Ÿ“¶«Z>Vžä ¬³h®ÇYÁOoFP2¤ac)8²“ pæ® ²ÄÞñÀô`C½Ù¬AË 7p¤,§‘RÐ^æÙŽX•×A ì/Ãäöû„Î×çlZ(ïc•ÓU¢¼ù&K½J²Í,?Ú<âó?¢d¯ •¹·È4^-û/M"*YEsMxÌ åâ,ƒ®¡ !r*’Û•¢5Èù,%º endstream endobj 1506 0 obj [ 1505 0 R 1507 0 R ] endobj 1504 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1506 0 R /Contents 1508 0 R >> endobj 1509 0 obj 389 endobj 1511 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 312.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1513 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 521.156 312.0 529.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1514 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 509.156 288.0 517.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1515 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 497.156 258.0 505.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1516 0 obj << /Length 1517 0 R /Filter /FlateDecode >> stream xœÅTMo›@½ó+æØFb;û»Æ­êCÒÈD=D9`³4T|$€Ûôßwµ þjZ©.FÚÑ,3oß{ã}v( ù¹í"ËÜy¶9 ’÷mÊó Â<ÈÁÆdíWƒ€­#³ô™à¾8…ƒðѹ0›1 )øáàn»®xîÜðÛ<;>ÂWç2tÞ}ð€"„ÉV"†„1¹E8 Ú‡A˜Ãý›»ÏW“pêÞ\Φïù;»ùt=ûáÌ™†#Rœ²ÿ@ê¶;CÇ¢³š™W’Îïц'p¼3˜…M~›íyŸ3™»ÝʬyvíÒ‡=Ÿ~=Ê·4pÈb<g?>²-¤HÔh"ò£pfÕöŒl±7|8Pc¬2sMG´:s¥%Õs𧱆i’èeS÷äÈ!ð€ ï›†Ê†ê¬là{”­t eëzS½Ó€2J”4 ÒpØkU.¾„§>'ªe#Ôƒ@TiÈË8MR“u“ãø’x¦8Ô6˜tìu ‹Ÿ{·êîŠÑ+Ü©ìž÷X'Ñ*kÜÕS5Úµ Ý> endobj 1517 0 obj 573 endobj 1520 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 626.628 234.0 635.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1523 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 210.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1524 0 obj << /Length 1525 0 R /Filter /FlateDecode >> stream xœÅSMOÃ0 ½çWø‡'iÚäÈǘ@h°µ‡i‡i+cR÷Ù"øù¤I·¶Û â2ÚJ¶ìØ/ÏÏÝh^¯0¡æ0YMcrA’0Ÿr (} iqªæðgŒ;dœwx%K‚Ð%ÑINMÁ'ÁÃv¶8"ý~‘Á³ã#ÌÈML®î%0„ø­T _k \‡xË(~~ñ¢þ“7èÜ>îzÝËĤ7( ÆÿRßÞÁr°Bsó…ÔªÝHH›™Ú&ìãUÔ 3‡]¤ÒRºÒº‹8×ñq¶•V4°Î¢¹goߊ°(dHUc8ªÖ8óÔŽ„,°÷|0#¬BDÖ eÅ KRŽSçk’¬óùj96­çùǸð3GóÄ`|BS ÓZ•-z«eBwíÐAH¥©Ñ!+ë¢$ë4[ígZQ20JPßѲ”ôáMðèwÍòñ6÷²Mêm“Éj;/g'å2͵üsóz[o]küÛÄ7ÂID_©Ý¼òäÇ µ©¡Ö¾PG#¶˜}ò ‘w=g endstream endobj 1521 0 obj [ 1520 0 R 1523 0 R ] endobj 1518 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1521 0 R /Contents 1524 0 R >> endobj 1525 0 obj 410 endobj 1527 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 234.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1530 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 228.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1531 0 obj << /Length 1532 0 R /Filter /FlateDecode >> stream xœÅTQs›0 ~÷¯Ðãö€'Ûã¾m]×Û®×--w}èõ!kÜ$7 Ðuý÷¶ Ûí%î$$ôIŸ$¼aî¨ÚH¸_³M° ÐÔ$˜’ ˆ˜ËÖôòö«ž"_5þ#R–pà †pÎnïÈ9¤€g†»p.øšM{ù[=?‚}ÈØ»O „ì¡k‘R\jcLªSH¹’¦½$dk¸}s=½ˆ®ÎN¿^}ü|y}{{Ùv– ø(!ÿŸ©«ÁpS–ôhîF=p$1=½5ØÚ;«K¨¼,>wëÊÃÜ‚ô…xÕóñr”v4°Ïb¸GM>¾º ÈÓÁ2H£ pä®í ²Í½å£@Ð`SDZn¸: n-¼ÏërK¬ÃSPȵ?+®Ùíîý0u3«š¨ÞäQeïËj¾*{Fà±üwðòqû/̵á‰HÑ"0¿,[ûø@õ T> endobj 1532 0 obj 470 endobj 1534 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 544.345 235.55 553.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1536 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.769 544.345 541.769 553.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1537 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 532.345 228.33 541.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1538 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.817 532.345 541.817 541.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1539 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 520.345 209.44 529.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1540 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.94 520.345 541.94 529.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1542 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 508.345 182.78 517.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1543 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.113 508.345 542.113 517.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1545 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 496.345 207.77 505.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1546 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.952 496.345 541.952 505.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1548 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 484.345 223.88 493.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1549 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.846 484.345 541.846 493.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1551 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 472.345 212.78 481.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1552 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.92 472.345 541.92 481.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1553 0 obj << /Length 1554 0 R /Filter /FlateDecode >> stream xœÅÝIo[džá½~ÅY: ÑÝUÕC-“X ráÜĶ€,‚,‰¶ hp4$È¿¿]4T w“kÐ!ù5Ïð´HžR÷ÑyJãë0¾5—éôâàõ}yj2i]ßUê”m&eº˜ÖËe:Ô£Ù,o«ÐXø<ýrpy¦ï~ýmžœ.ηßß¾ºÞ,^o6vsGìÅzñôêââäòìþùnæ—·›åÛ«ûµ\ž½~ü|7wç·77oï®/çg÷k¾¾º¸ŠÏóÍâÝåÙüúüïÃÕþ?>N5míìjSÅgmzõþÍ7?~x¸¹Ü¨õòÝÍüúáÖÍ—±£‹‹å–lžŸ\ÜÌî9þ¼¸y¸õxy<ÛÇ»ó‡Û«#¸¾qqu¹¸½º~²eÏÚ«ô™.”Óè\;{÷Ͻ@K´ñ$ºÛöaå'§·‹?WÞ›{.ÏžÙø³ùïwŸ>Ý÷ÖÇǾÉXƒN?±†“/_Χ'·‹«Ë›ÙnÞm+¿9žÅ¢óœF»Íͳ«Ó»‹ÑŸî_õ†åâÇ»Ëeöþ±uÇ>»¬v ç—'¿Ÿ¯|Ü^ïèr‹›§­ºörñq·_µ»_Ù_óóóÝ{Ç*ww8§ºµÇãçeñåî|¢ñÔ±KëN6=½ó¯Ï‹ÓÏSlÇýÏVlðæ‡æäz>­¶l~6Ûôòx—‰ü¤3Œ—®2^æjv¯¶~ :;<Ÿ®>Nß^]ÞÆÑ}¶+ÅÖ7½©Ä+X^¿‚ýþøplÞáû£ozÿæ‡ÿ~¿µÓ¹ê¬DMeÏÄÑê}¼ö¾ÚiWg®æÞâMj§ÝvgÊÕQ|ôT/,ÞQ¼g7o(î‰Å•Å™ª#UIHUR•„T%#Õñ>ÍâHU©Š U¤*ÂT•©*SU¦jLÕ˜ª1ÕÂT S-Lµ0ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT;Su¦êLÕ‘ª&¤ª ©jBªš‘ªf¤ª©jFª*HU©Æù ‰+SU¦ªLÕ˜ª1UcªÆT S-Lµ0ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;Su¦êLÕ‘ª%¤j ©ZBª–ªe¤j©ZFª&HÕ©š0UeªÊT•©*S5¦jLµä™öÑë¥:©¼X±Y«ž²Ø¾ŠÍ8kÞS×/#Û•¡Ÿ~þçÂÐ8½P"U×=ícó¢±[çM»{·¼§ÝnaHX¼°xGñqžâÆâ ÅÇyŠ+‹WgªÎT©:R•„T%!UIHU2R•ŒT%#UÉHU©Š U¦ªLU™ª2UcªÆT©S-Lµ0ÕªãÝj|ÆI¼f7o(Þ‹+‹WwïÂâ…Å™ª3UgªŽTÇgGªšª&¤ª©jFªš‘ª RUAª*LU™ª2UeªÊT©S5¦Z˜jaª…©V¦Z™jeª•©6¦Ú˜jcª©v¦Ú™ª3UgªÎT©ZBª–ª%¤j©ZFª–‘ª R5Aª&HÕ„©*SU¦ªLÕ˜ª1UcªãíÀRóî…T¢HÕsõ^Ó¾êÓ8iÞS¤Ÿã¶ŠTëS‡?o—Æ9šÙˆ‹ÙžÆËmk»õ©ø•PŒ¼¯þ{ZíÔâWB$^YÜQ<~%Dâ…Å;ŠÇ¯„HÜX¼¡xcª©6¦Ú˜jgª©v¦êLÕ™ª#UIHUR•„T%!UÉHU2R•ŒTEªRaªÊT•©*SU¦jLÕ˜ª1ÕÂT S-Lµ2ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT©:Su¦êHURÕ„T5!UÍHU3RÕŒTUª RUAª*LU™ª2UeªÆT©S-Lµ0ÕÂT S­Lµ2ÕÊTSmLµ1ÕÎT;SíLµ3UgªÎT©ZBª–ª%¤j©ZFª–‘ªe¤j‚TMª SU¦ªLU™*«-«-«--+w19‹¼¼<…;¾¨6N‚w wqf¼[¸ûpüþèë· 1ü¥¹{oûÚÅFå(™ï–íb>¹V÷ÑxOÃBÃø@DâãŠ+‹W÷r¥ÊKâãŠï(>>¡¸±xCñ’X\Y¼²8S­Lµ2ÕÊTSmLµ1ÕÎT;SíLµ3UgªÎT©Æ¸HGª1.’Ä3Rq‘(ŽTc\$‰ Rq‘(ÎT•©*SU¦jLÕ˜ª1Ucª…©¦Z˜jeª•©V¦Ú˜jcª©6¦Ú™jgª©:Su¦êH5ÆE¢8Rq‘(ŽTc\$Š#ÕIâ‚Tc\$Š3UeªÊT•©*S5¦jLÕ˜jaª…©¦Z™jeª•©V¦Ú˜jcª©v¦Ú™jgªÎT©:Su¤ã"Q©Æ¸HÏHÕ2RµŒTMª R5AªÆjKÆjKÆjKÆjKÆjKÆjKÆjKQ]-¥¸{«¨iãI˸:H ±Œkã‘4²Td©ÈR‘%ªûªûªûªû¬F8Ö”5ï«‘=[çZŽq,㬺ô²§dÝS‚Óí í½9z{t|ôU¸±u«?-Ó÷5_nÌtÏôÊLãPhk{Úí¨:ŠÇ@7o( H\Y¼²¸£x $ q¦Ú™ª3UgªŽTcÖ.Š#Õ˜µ‹âH5fí¢8RY»$.H5fí¢8SU¦ªLU™ª2UcªÆT©¦Z˜j $Hš’'}I<¸²xeqGñH@â…Å;ŠÇ@7gªÎT©:Su¤³vQ©Æ¬]ÏH5fí¢8RY»(ŽTcÖ.Š3UeªÊT•©S5¦jLµ0ÕÂT S-Lµ2ÕÊT+SmLµ1ÕÆT;SíLµ3ÕÎT©:Su¤³vQ©Æ¬]ÏH5fí¢8RY»$.H5fí¢8SU¦ªLU™ª1UcªÆT£¦5ε’åBªFË îEå¬ï[Ë8OÝSÒ²íËò½ýáÃñ£‚Ö‡í:€=ž¼»Óz¹m{F•-ÇŒ\‰¿±¼Ój§Ø° ðòør4ˆ+‹Ww_ŽñÂâÅ—ƒ@œ©6¦Ú™jgª©v¦êLÕ™ª#UIHUR•„T%#UÉHU2R•ŒTEªRaªÊT•©*S5¦jLÕ˜ª1ÕÂT Sºþëî/ˆÇ7o(£H\Y¼²¸£xŒ ñÂâLÕ™ª3UGª1ÇÅ‘jÌñDq¤s> endobj 1554 0 obj 3048 endobj 1556 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 228.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1558 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 210.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1559 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 180.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1560 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 643.364 204.0 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1561 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 631.364 222.0 639.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1562 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 619.364 216.0 627.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1563 0 obj << /Length 1564 0 R /Filter /FlateDecode >> stream xœÅTMoƒ0 ½çWø¸Èœ@ø8v[Wmš:Ñ"íPõ0•¬«¥-Hûû –ÐuìÐ’-;~΋_ب^«4^Àa‘’­Ž1ð8Ø® ˜C¹€´/ )Wß{ÊÔ‹”óïdMFd6WÉP|<†«Š§$4ú—¼z„%¹ÈÝ“†}6GÄ‘r.ÑöÁ§6ʇC”Âìf &‘5 _­Éðámòø<ÝÎ!z!èÅÉfü8…Õ*Õ¤¹ú> endobj 1564 0 obj 413 endobj 1566 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 710.1 204.0 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1568 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 698.1 222.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1569 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 686.1 216.0 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1570 0 obj << /Length 1571 0 R /Filter /FlateDecode >> stream xœÅTMk„0½çW̱=˜N¢‰ñØÂ¶PÚ‚UèaÙÃRíè«Ð¿ßѸwWè^lf˜É¼ÉË<­˜¤ÇkMIx-YÕÇ„|݇”p© „ÞWP´»Gî=2v9ðÂv Ꭽ7”Ì©à‡á!\Wœ°Øéßfpñþïì&eW· Bú6^Q ¹HK 0Ü—Q»$¤%¬/’øÁKÒçÕõãåÒ{¶J'T|!ÿJÜ¡;{7`IoÈ»)O*ÀiÆQÀ£]C߯(b{·©¢YoíA¬kùX;ËG貘JbÑæójÛBÜLt …œÀ·v4Èéc90Œâ‘Ê·YæÕUáÕÍw¾-O%X!ÏÅÍò"oò?@Ëà\èâ³nàÚA`|$rC_¶8@ÓÈCãS"Rîé«É{ŒSFqÔšL´¯ØåÜé³_Y!² endstream endobj 1567 0 obj [ 1566 0 R 1568 0 R 1569 0 R ] endobj 1565 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1567 0 R /Contents 1570 0 R >> endobj 1571 0 obj 346 endobj 1573 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 521.156 234.0 529.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1575 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 509.156 180.0 517.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1576 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 497.156 222.0 505.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1577 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 485.156 216.0 493.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1578 0 obj << /Length 1579 0 R /Filter /FlateDecode >> stream xœÅTMÚ0½çWÌq÷×vœØ>R-­Tµ•(‘zØÝƒ71K¤@ìjÛßÉÀ†.J<²=ïÍ›yÉ&`@ñ ëEjÙ*Øt{ $‡(é¶â˜ <†tq e}«ð]„K{ ƒ%ü Ö…ÏÁý#æ@1á5 ÇpMò<˜õøëzu~ ÏÁÇ4øð)F!]Z ÂXL)K(q]ÿ8¤+¸¿™ÜÝ…óÙ×pžþ˜N¾Ý>Bú%˜¦9ãÿAά©¡©¿2Ç¿$ͤ± Ã“ž öû‡Ý†0j÷p§å®ÊnlÝÚÒ†­žvÕA2h_ÅÐW%w„¬%jàÎĨ®Üµ“AÖÜ{=0¬¢hé¬f¸²Õjš¹…éba3ïZqo´C(ˆ4¡I‚€ªKL—܋͊EasxÚV&ÏŒóàüÖšÕÃ{¸ã\•Æã…×Â/aG€ðG \ ~ŒUITz•ožŒ³£r-ϤƒÙZXUyS*ÙŒ7)‘$Æd-Y0iúSËüs®GšE9âé¸Íû^­í;ø¯g+w‰Óß™}ñEµ68ðÂÿ2u|v>Là&’Z‹H]F.9Ñš"yÄ:KX “ÒU{¯¬V)E´µß¯éãbèÉ7Ôy³õ¡Û”áÖfÕ6/ÖÏo¾GˆŽÝ»q[Ó‚2~)hnKëmøl..Å. ç{È®ý·—'ŒHžh…>ß ÙÛ³¾à*!”!––òÄ ç,ø /úÈ× endstream endobj 1574 0 obj [ 1573 0 R 1575 0 R 1576 0 R 1577 0 R ] endobj 1572 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1574 0 R /Contents 1578 0 R >> endobj 1579 0 obj 570 endobj 1581 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 234.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1583 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 228.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1584 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 210.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1585 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 643.364 180.0 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1586 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 631.364 204.0 639.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1587 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 619.364 222.0 627.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1588 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 607.364 216.0 615.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1589 0 obj << /Length 1590 0 R /Filter /FlateDecode >> stream xœÅ”Moƒ0 †ïù>n2'ÇNc“¦nRÒUUɺJô¤ýý’h‹Zvè)–Mçµ [Âõ픋 9Ì–dk} $×·.áó(°k ÈÊ·ß[z1/iã>ÉŠ ¼ñDS@½á‡à1®Ú“Q#Á›çG˜“Ç„<< `ÉW]"îS¡¾< uyiêš%Kß=EÃ(‰œx4tâä#¼ÝO y%QÒRä2þŠFÕ* UŸ¹~$­šÝ Û‘Æ üµ·JèŸö˜Üe(³³«9ˆ1³vêÀZ6U´'ã¦É»‡B–Ò 5œùpãª4²Ì}ÐãÓ ‘µdUÍ•V”Ñ+ƒ,_„Õ\/©4‹Š× O>™¼˜î 'ßfÎNÍÖ»t±šŸ­™†{¼?|½¹Ž-¼Þì&ÖÙt}ÿ/à¼Ø©é²‹)ƒ¾Ìiš:—¹aïî¥*S…ºͰwó²E^4Èy}ihÝ „¡dvjß×…²€3_oy>ߥrÍ Å~ËJÑFÎù¨k‡ endstream endobj 1582 0 obj [ 1581 0 R 1583 0 R 1584 0 R 1585 0 R 1586 0 R 1587 0 R 1588 0 R ] endobj 1580 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1582 0 R /Contents 1589 0 R >> endobj 1590 0 obj 418 endobj 1592 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 679.364 180.0 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1594 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 667.364 204.0 675.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1595 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 655.364 222.0 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1596 0 obj << /Length 1597 0 R /Filter /FlateDecode >> stream xœÅTKOÃ0 ¾çWø‡;mú8i Ð@*ÄaÚa¢í¦ÑIü}òèÖv[5í2ÒJ¶ìø³?Û토y+’LÀGÍ6­ Æ­IÆ@jhu •½ÕSÄN3Â_2Ê7¼³Cxdó…q–€&à—á!œ .XÞËo=xõü_ì^±» „ >»…ÄcBsb‚”‡"³G€ªa~3{*TPä³ PoÓÉKq»õ̦j@($ñ„rWƒcàÆ,Ì›p7ëCF8ôôö`oï¬.aèmÆâs[WÕ®•¾¯z>^ŽòÀŽöY ãªÉÇw"±„<lƒ tt®Üµ£AÚÜ{>!ljvš´Üp“–”çTh “ªYï‰u¸Q !òÄÿ,nvØ'<úbšM4Û½¬O¶Ê`FâRÌeYçqet)n©+½Õ§¡Ïô1#.)Ͳ„Ú>¾®·ºññ'öÉ”G$yŠÂ@er²Ò¼—2gNÚ0 endstream endobj 1593 0 obj [ 1592 0 R 1594 0 R 1595 0 R ] endobj 1591 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1593 0 R /Contents 1596 0 R >> endobj 1597 0 obj 369 endobj 1599 0 obj << /Length 1600 0 R /Filter /FlateDecode >> stream xœÅVMsÛ6½óWì1ñT(¾¹I¶›ºÕ±­Ii°ÙœR¤CRIôï» !‘–(ޏ”f-ðöãí¨¯ŠŸ‘´á0_E_ƒæ T0Å ˜$<†„y ™ßÕ›ðí ‡vNáS”GÞGŸ¿àâ(¾Gtß]¾‹nzñý }õøý ãÿK>‡¦+M_8~5išól!–ôùJ¯q;{gmŠÖ†–6¶_ÊÓali§m=íx´Ú•A‡y ¾^p Ñdýú[ ŒÂlÙé\{ £$áÆ?f+øü†súö Ìþˆ.gxeÖécïêÀ°± ¥”=+«i®Eµ5MíʵE Ð à†PûýI 8›ŒÏÿ¼œ^Œ>o§WÓ÷£ÉåïãWÝžAëg‡æ,&Rû$8?ôó7çzÀOà¼Èë²È*¸wö[Z¬K(rønË<Í*X–Å Öù•Ù p{1¹¾#ÛÚô@m’j(FPm„¶Lí}¶ãã8ʘ%Æhf¶Ðlí`¶y:I¦$¡Ý™¸…];ë“_®3øæ=T`Kï|M¿À;W–E‰cúh¶ù¶Þ;w.9QʳÅôaœéÕ‡£yqE‰BÖ™âI~Nv ¥)‘ @WyZ§6ƒ†•S„0©H,´1R„.7µ¿ ¦–ÄøÞiÁZà…«æeúT§E~2¢1„kI±Èq<÷x £˜“ÞÔE7rå²(W¡¿1(¯3¬\UÙlâÎÒhr÷ëÞÎÿqù‚t– ·´ë¬î i5œHCKxm7Ý›U½­÷®›W®>â¯ÑVmï,ú£ÏØU*ÛjsháøÝŠÓ;;¦M† Óñ€¿S²d:ÖQ¥™Ëël!zýè¶Á Ë…!øê£4Èõò‡]=e®:Z€'C+B1 šÄ2ä±}˜K’ÁÍ?OM0E¤xê ÎåÒÍk·€É攬…DŠ¥BšÂ»jZäîT¼ÉðH L´À;ç`Œ‚: ¯ ™ SýOá$gÄUÄj ¬;â‡bI¼"8Ó&Ñ4@ÎÂ9…Žvïƒ3Àócw4«M%†ˆóRlÀïù‡»›×$C,| îGíò oÒûpý EŽ~Ð endstream endobj 1598 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1599 0 R >> endobj 1600 0 obj 855 endobj 1602 0 obj << /Type /Action /S /GoTo /D [1601 0 R /XYZ 72.0 720.0 null] >> endobj 1603 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 172.78 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1605 0 obj << /Length 1606 0 R /Filter /FlateDecode >> stream xœÅUËnÛ0¼ë+öÖˆY>EñÚ¤-Riƒè!ÍA‘éX€,;¢‚6ýú.õ¶-;í%õ\“îÌìR~ P|Ïü  ‡t<µs 4¶S*& W°‚6Vû]£€wÍ& –ð=( Ÿƒ»{\œEÀÏ€îWƒoƒ›Q~¿Bß<ÿ˜`ü¿0ðêªÔuáøÑ¤.ÎÖ‚’t{eT¸~~˜­ŠfgšÜ~)ondžH6zšñ :È Ó>¶ ß.9…ÇàC¼ÿ¤€QˆCŸkd”DÜø‡xw'œ³Ó{ˆ¿ã½xc×ö és÷z0,lD)e[²êâêVT£é:YÙFÔ„ 2n •ß5€Û›«Ùù×ë‹Ëøòë54ÐÀx„,q³Tlúƒs½ ÇP--¸ç-gÕËÆÂzIžCÇ7Üå˹ Š£lÉõþiçWÈý V®<ÖïÖªgncÓl‘¥®‹yVeëÂuGé Û$#ÔPćmî1 é‡ë¢XdŒfmÎóÄ9øVÚÔÎm‘Z¸Ê\u¬pFˆ¢̨æ÷”Ïzò»e ”hÝŠßCž ¢Ï z<ã‹*‘=oO¸°.-³Íyš3“!QyHÑú/3§ °ùádúÆèâQƒtSØ(]X7Ll¦"" &VŽ÷ ‹"")Ú u8§#14P?5·‹¬°óþ÷ÃË딄t?RòŸI éÁ¾ÜÚL€Ï#ËÁÈâeÊ߬z7’TÉCâl¯z§Ï|ÑêílYQÙr‘¤Öˆ—¶´à·XCgKV _IžýNê””Ï+[T÷”ài%)‚ݺtä/š3 ‰ñWS Ö>וuGŸŒ®%ÅKMÜ%À¾L?”3DDþY"ÌÄQ¯t—DðA,Ø_•-r £?¦›à@(' endstream endobj 1604 0 obj [ 1603 0 R ] endobj 1601 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1604 0 R /Contents 1605 0 R >> endobj 1606 0 obj 702 endobj 1608 0 obj << /Type /Action /S /GoTo /D [1607 0 R /XYZ 72.0 720.0 null] >> endobj 1609 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 154.43 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1611 0 obj << /Type /Annot /Subtype /Link /Rect [ 385.51 624.028 438.29 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1612 0 obj << /Length 1613 0 R /Filter /FlateDecode >> stream xœÅUKoœ0¾ó+æÖDʺ~` צi¥*j›)‡4Âz³H,l0Q›þúŽ1¯eÙM{I÷!¶?Ï|ߌ‡'ÅïÂ*ân¼§vŽâ ‚vJÀ|Â%l µ%äv×Èà…ƒÛ„Æn½Â£ðÙ»»ÇÅ%Püôèô¸|ã]üÛúæþÇÆÿK6†&+M^8þi’³³ }º»2J\??Ì6…›ÃçÛ.å­Òíèq¦ããÆƒ<è@ƒÎëØ2|;ç½±÷þ“F!^ u®,QòÈ~8ĸ;ᜟÞCüÅ»ˆ÷ àUÛK¤õÝóÀ0±!¥”íÐj’«ZRŽÓ×d£©üxDh íþÐn®.××ß®ÁÁúÍŒ„Ú ƒÝƒýà\Mìêµó¼ÕÕ¢~Ùj(Wä9t±ÓX9eDp¤¬ß?íüã>È“ Ä +W(ö± ³Õi¶ÊRÐUUV¦;FÍÈå3B#ŠØ õ[ˬÎÊb$Ñ!ç'ˆˆd!JÂÚüœç‰1ð½Ò©^ê"Õp™™úXÂ"ABŠ:°HºÌS¾hŸÈrâ[ÎT°}Иl³ÍµCöOiGç º]e峯Lü&ú‰”š®ÇN‘A@x„ÈPús!Ž|Ö¯KË8Ç䣶¼=á£6i•mÏóŠ2? R¨(òE[ñ:3p Ø=}8™¶d;{TºÝ–pg6¥ÜÚKšÉÈ@D‘ÁLÇkš…V>¥’‰ðPÔ]½šc>IÝ?Tz[i£‹aÆ]‡³Ô€\êUVèeÿüðò:]Ÿ†„eÜ—ÿL·®ðæ05ƒb,«!ÜâeRp6ÙVó,f-«ßX&uò=(—µ®VIª x­+ þ‹:öY‚&yö;iZ@R=>oP@ƒ{*@÷¤6("ù‹ú ÙÞ¢ðºÞ]ÖÚmÞŒ¡(Xœ†“fX¶Éánʰ›Rßv|ùíóJéa;¥Òv*gÀ Õº0¨½N¯¼?Â:ZT endstream endobj 1610 0 obj [ 1609 0 R 1611 0 R ] endobj 1607 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1610 0 R /Contents 1612 0 R >> endobj 1613 0 obj 773 endobj 1615 0 obj << /Type /Action /S /GoTo /D [1614 0 R /XYZ 72.0 720.0 null] >> endobj 1616 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 167.77 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1618 0 obj << /Type /Annot /Subtype /Link /Rect [ 210.54 624.028 263.32 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1619 0 obj << /Length 1620 0 R /Filter /FlateDecode >> stream xœÅUKoÛ0 ¾ûWð¶H4=,Ë:nÝVl(Šu5ÐC׃ê(ÄI-]÷ëGÙ²“ÆN»]º<`†âGò#)æ>b@ñ=õ¥9ä«è>è(" *™‹ —°‚ KXz«w>Z#p•…Óèúg@ðÑ}w ø2ºØ‰ïOè›ÇßÍ@0þ_2ð94]iúÂñ£HÓœg2¦ÏOv×ë·Ú& hu¨icû£e¨tx¶‰´b˧}äA·4èx÷ Ná.ú˜Eï¿H`²ùvΕ2JR®ý‹C¶‚ë#ÎÅñ dߢÏÙ`Þ¸jƒFúØ= ›RJÙ3ZMsU Õr:7+Û’)Cœׄ&ÒÛ§-àòâlzõáÇù×óSh½9ãŒÐ£R¬Øø“sµh"¸ ^Xpë§…õÌr ]¶É~¶œ%Døè‚Ê¡·“3Ìü S{,Z+¬ô;u›ó"‡GS•Eyç:Gj¤d1’ÒÞW"¯ËYQë2¤Ñ!÷(ÑD²Sa¡G'Kã|¯lng¶Ì-œ®~©iZ”rô¬eëÁÝ/§!õ½hITâsMâ!lÒñ Z-R"»Î†Ë;ÖûH͈@cª‹Øã&P¿^+Æ9^‹‹Åƒ‡OÖåU±ÙF/ÆK¡´ŽEhr¶(ƒÄx´•ü qgƒ'2HÍ`¶âÁùdR“TKJc®Fâ¿< 8DS$šª±ä·²è˸ÃÄÔ\ÙMe-{E7דžP›ÙyQÚY÷óöéU¢1Ç-ÄN5Oþ™h,ÌýhQ>î\W{ƒå›*Ó=sS>ù½QÔïÌLmn³ÛZem«¹É­#-leÁà·\Cǹ(±†fYü6Íý5ÕÝà «æÐ¦ïÛävëÊ‘¿˜Õ4!Ú/%XX¾ëÚº·/c„+\©œ¦ƒ› 8¥æð:dþ/Iéöj ½2n1‚S¿…ƒýUÛÒaMÈÎ?âEôHbGî endstream endobj 1617 0 obj [ 1616 0 R 1618 0 R ] endobj 1614 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1617 0 R /Contents 1619 0 R >> endobj 1620 0 obj 759 endobj 1622 0 obj << /Type /Action /S /GoTo /D [1621 0 R /XYZ 72.0 720.0 null] >> endobj 1623 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 205.53 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1622 0 R /H /I >> endobj 1625 0 obj << /Type /Annot /Subtype /Link /Rect [ 210.53 624.028 258.3 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1626 0 obj << /Type /Annot /Subtype /Link /Rect [ 301.07 624.028 353.85 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1627 0 obj << /Length 1628 0 R /Filter /FlateDecode >> stream xœÅUÉnÛ0½ë+æØ1ËEÉÜœ¥AŠ h9¤9(2c«¥ÄTë¶_ß¡/²¤ô”ÚHzófæ=_<¿·HÍ!Yz/ÍÉA„ÍQó ` Í>€Ì=µ³áí—ú!Ü,àÎË= Þý^΀"`íÑn¸ |ëÝìð»úæü»ÆÿK.‡J•JŽ?I*qö.Ÿîßì·9ßžV„¢>ÓšÛ]eM§›µN¤ÞÖõÔë`t[íïcSáÛ‘S˜{'‘÷ácŒBô´õ¹t@F‰âÚ}8DK¸ǹÿþ¢OÞyt`€7îÚŽ{S†Â*J)Û+«W6EÕ5]ÇKSÕÓ_ׄ†{^Õ€Û›«ÉÙ4šžLoÏ'wÓ/×—×PGØà˜”$t˜P‡¾q.»5€¯ÖÌ ,`¯rX/ÒÌ@œ$ÆÚ4ŸC mþa7Áé‰wz…E -|1ì–²'—Y\Ʊ5¤ {ºæ3B5uõ4ŒE>KË´È!úý¼é÷°L¡Æ”Ö’52f±µðye33ybà*µå˜nZE9FƆVìK6isŸ¸Fbïº*Ag%{¨,ÔÈãŽo€F…D`ÑTР¦Aðq'†Dœ¼Ÿ/iÛÜE*FT€Èõn`GP¾® ãßDÅáM„3c“Uú¼%î—„ù! „ÔÚ™¢Ej·ì°2Ï+cM^Ú¶l:Ïã,Cÿú¾cÅ=®Ppx*²¬X;pš#eœ¥âŠ9^Í,+â8Ÿ5ÅÊ‚ù…6;s:S´Ct‰¡1Þ1 öB¡ÎL‰üq[Ö(­æØ´IzË«»8ÍH ÜK)üž;†üK œú;>©žQA¸vaè÷q:µôP<~7I å".ÑeûYd?Ñ iއ—$ÅyP’×mË'ÚÍ$)X3ú‹ÒØÑÙ`,)´ "€™Á,à„ 7A…î‰8>‹™B°?„E{–&·Øn²ó¿|ãýñu» endstream endobj 1624 0 obj [ 1623 0 R 1625 0 R 1626 0 R ] endobj 1621 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1624 0 R /Contents 1627 0 R >> endobj 1628 0 obj 769 endobj 1630 0 obj << /Type /Annot /Subtype /Link /Rect [ 178.993 624.028 213.423 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1632 0 obj << /Type /Annot /Subtype /Link /Rect [ 442.368 624.028 495.148 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1633 0 obj << /Length 1634 0 R /Filter /FlateDecode >> stream xœÅVKsÛ6¾óWà˜ÌT( øÖºn§OÛêää€PÅ>d’jìþú.ˆRzr-ÏpÀ¾¾ à9¢ˆÀoe?©b(+£g?FQÊOüH1¨D^¨°«Nv”àã°C£*"è·èÓ˜Ü ß"2u×?F÷'ñí yóø§pÊþ— l=+=/ þSÜ“3š1Ïœ7Œ‡Ñ> wc0âbÛ©Â#í¿.'ºzÜ÷l$”A–qô¾]p‚ž¢Ÿ×Ñ¿ D ZoÃ>O­!%X2eÿZ—èÓ;ÆÄû/hýGt³žm€7FmF¤=ÔÃb%!„ŽÊêÉM}Q®¦?ui\Q 0Ä1…I"ìzé ïoW=Þ<¬nîÐ{ÄcôÎyì(qB!É+h`懱nžeß2ºÚ e¦m-Ûæâ«Kw£É$Ðïàü]¡³PH8w¸=#$_°¿*!¸~2£²éÿÉçÂÎÈS io-¸äæÆ7Èê¿$OY<9Ò.”O Ç,±‰$ñ‚K”ÛÒ>üýÓ•%î5¸’SNýçîŽ}}îåY¤\ÉD²¸-ênàÿ<””* —7©XðtËY6LP¸Î/͹7'–FgÏM€+…Bù Ö—ÏMx €1„&Œ/…š Ÿ<ï£ÎB… endstream endobj 1631 0 obj [ 1630 0 R 1632 0 R ] endobj 1629 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1631 0 R /Contents 1633 0 R >> endobj 1634 0 obj 1009 endobj 1636 0 obj << /Type /Action /S /GoTo /D [1629 0 R /XYZ 72.0 720.0 null] >> endobj 1637 0 obj << /Type /Annot /Subtype /Link /Rect [ 186.914 679.364 270.914 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1639 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 602.628 204.0 611.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 1640 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 590.628 198.0 599.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 1641 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 578.628 192.0 587.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 1642 0 obj << /Length 1643 0 R /Filter /FlateDecode >> stream xœÅUMoÛ0 ½ûWð˜‹&YþŽÐ †AìÐöà¦jjÀ–ÛÙš?Zò·ã è!k ˆ¢ÄÇ÷HI>: (þVÕJv©s¬} BxP»ü˜G\R¨m’jWÏp » 7øåh‡Â7çá _€bÀ‡ŽáLðÆY÷òW+ôæù)ì/[çóW…íkW¢@ß÷)¥œ ܕ՟ Û›õål¿;÷ÛÎÜÿ am8Ò¦³.þ‡Ä´w°à{t¸Òk}ëï¼&!·>ôØÜÕRR÷ª-kZ=vœÕA;´¯bxnš|þ„=D ڳݿqÉ&]¬r·b:vUàfM¦³a­ÉJºß©Cg:B踥Ï*ïæY϶Ññ®óà;ÚMÔû!WEçîqy êÌ$.ÊË›~«]ÙŸï2]F±Fš½ý:9w3,R¡z4›BM ðQAL IÓÃùû&ñ1H†¬Ü(wI‘µIw1£!ñìe6yrKèä“TÝŒ®‚ß§ ˜Ég•›a—³ã6ÙÀþëáÂϲ[}–=!,ÎϬTW*&]âóPJ·!Z‘^εóÙüK endstream endobj 1638 0 obj [ 1637 0 R 1639 0 R 1640 0 R 1641 0 R ] endobj 1635 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1638 0 R /Contents 1642 0 R >> endobj 1643 0 obj 625 endobj 1645 0 obj << /Type /Annot /Subtype /Link /Rect [ 188.292 573.892 272.292 582.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1647 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 509.156 138.0 517.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 1648 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 497.156 198.0 505.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 1649 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 485.156 192.0 493.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 1650 0 obj << /Length 1651 0 R /Filter /FlateDecode >> stream xœÅUKÚ0¾çWÌq÷×v?Ž[‰V­ªm)H­´Ú †F…$$AÛý÷;†$@h»žÌdæ›oa0 ø í!5‡ù&ØzÉ!^•`1á lÀË ¬íSï%<š‡Pøß‚, ð>xxDã(:<ô8œsžã¾µÐ«ãSXo§Á›w 0 Óe[¢HÁ(^‚"×öâ0ÝÀÃÍdü)}ÿòu4™|ø|ûÓÁhÚ£1þèŒ].×dŽ_I\§{†$¦}Kg úVë£F‡šÛšÖ¾mþliĆOsò - ÚeÑ‹«‚O„ŒPCTo„ìþ•KvÒE‹} ƒ©cWŽ3ëqr•ž“îta`´\šy]5äÎÔ"ViB…À€Ê;Þç™!{a@!I‚>Z2ïwç°Ìž^.áiFåO'ÿ„Ǹ­SŒ€Ü;Ž~ÍMQ§y6Ãâ¥õnfå‹\YŒ«I­ãHù¤3¸…W%‚S–yÙÞæËV®_ ÓÞí!ô1c‚pͰŠŸ«¶ëpW™2tHƒ‰bq0 þÊ89¥Í#­Z¹JWX‡5–¿5wÌ:> endobj 1651 0 obj 593 endobj 1653 0 obj << /Type /Annot /Subtype /Link /Rect [ 186.603 679.364 270.603 687.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1655 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 614.628 138.0 623.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 1656 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 602.628 204.0 611.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 1657 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 590.628 192.0 599.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 1658 0 obj << /Length 1659 0 R /Filter /FlateDecode >> stream xœÅTAo›0¾ûW¼c{ˆgcŒíc&eÓ¦©]V¤ª²ÆÉ" @µößï‰2©‡¬©äÇ{øûÞç÷™áÀð7«exÞ“C›ã Q›’ðöÐÆ’ú­^#\ÜKü†Ÿ$% >“Ç',®á†?„Â5›ȲÇ_WØÕùlÉǘ|ø$3ˆ7Ý MeÄãB¦"0õ_ño–ßf÷ß?æñ—û»Û'ˆ¿’E²Ñkn/[Ç©êÚÎMÍdU«ÉIZ¼>Û¼Úeé ¡wÕ˪ŽK'óÌ©„„¡,«Âu 1Oá¶6pc‹"+üS¶ñaõ–[ÿpD7§èëÃö"-Æ<å!™½”¶˜5,“-r£/€ø&v¥ËÝå'vÝ7£f‘å„(ÕF"3c¢,·ÅªºÐ§`á…íçúL³ÊÇ«®û·ý¯,ñ…Í [Ú´Ú¥Ûso¿äyVTvíúêVò“ð»Gô¨cÚ[ÊP‰{âÇýÖÂ<)3i:Ï"‘4t¾m<;2}‡Ñgï‚q¦Þ6³¯õa•hùI`nÞ<œ~û¯›‰n ¤d,ÔÚáÜe•½x¹ÆÏ„PÆ„ÂoI-íq.É_莸u endstream endobj 1654 0 obj [ 1653 0 R 1655 0 R 1656 0 R 1657 0 R ] endobj 1652 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1654 0 R /Contents 1658 0 R >> endobj 1659 0 obj 545 endobj 1661 0 obj << /Type /Action /S /GoTo /D [1660 0 R /XYZ 72.0 720.0 null] >> endobj 1662 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 192.19 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1664 0 obj << /Type /Annot /Subtype /Link /Rect [ 197.44 624.028 231.87 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1665 0 obj << /Type /Annot /Subtype /Link /Rect [ 464.2 624.028 516.98 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1666 0 obj << /Length 1667 0 R /Filter /FlateDecode >> stream xœÅXIoã6¾ûWð8Ä,­¾e2iÑ"h'‰¦se:Q+K)'q}Ej1%kb´H“âö½õ{OTžføëG3”ngOv¢!Ø%?@ÔÃÌG[dÇ>Êõ©Þ€5#x˜C0xD¿ÏŠA?;~ƒÍ5"x™W\ ¾ŸÝöôëòîúûpÊþ ´ uVê¼0ø qœ£ ß#Ç;½ÄµëÝj­›5X1ºõVn#mŸÆ34þ˜çI?Hç£õðý”ô0û´œýð£(AËMÇóP)Á‹õCË-úú±àã7´üev½à£6H¤ÖÝúÃ…ÄF„zäVÜÐ:e|ú5Ù ãÔH¼±“À×ç#¸¿½™¾\^~º¼¿ž_ßÝýv‡ ¾EÑ€áiåŒ ñ0º€p €Ò²XgUVHŠJUV< !e)Z丹=í…< RÂéí6)ÖH¼Št¯QwáˆwÅ$& +0º®ZUËîËép1öiÇ!µá¼Ê¥Ð)R±E*ÐM¦ª©øÆG|§±o$¨§|¾Nªd•(1¯}t£Å¦1ô˜j…ŒxŽ¢ŸA4È[ “îDPK\Ó>â#øEÓÆ&ÕÒÀ]Z£§ÓSìGºksoD@ÛÌæo2€¹•Ö+Ñ ß)á˜éÖÞˆ¥F=*WŠ´Buõ½í²â¹ÌŸxY‹i¯‹ Oê¹t93AüÂD)[Oªõ]ž› €.Ao2 p‰uœ 4oß'ÒÄ©¾Nñˆ(&#¡€º‘Yjg¥´uخʼ]¯ n¶v"Í6Yš4}Ø×M¸ÚË2k¦«ƒT­ž–öD’þ5ÅÛygÐs’ï…vº„×¥®ô¿*K¡n€Sð®H¤&V%ä&{Hcì4Å"—ÆgRl€_(¡_U‰<¼)× èß‘m( #Û™¦P—¶.í8ýïüÈÆe(˦Y‹hÍjzLÔS÷úd‹zÞ’±ÞtÙ¨ûtÔóU«¤ê è3²>ÔPrÈ=ÎÆ È0ýg4äÜeøy4â[ Qò0ù"àžKÞs¹70|ÍßbHàrØeô5i’{|÷ÆÇ¤]v"T%› ^=_׊VGk–)f²“å*Ûþ®½QFíRŠõEQ*•­òCïPÑØg¨YYNèîóÔÕLaiè–[Çæ©Û:D Çús0„20_ÇeÕ´àñ{ºŸU,äqD¬+•—U{ù:MJcÌCýMú#’Nßc–À75æÍwÚPÒuØÚ ОãP£C>‚¾º{ÿiÕ!€u ÛÆT‹×J ˜‹{ÿ;¹ý7uݲ endstream endobj 1663 0 obj [ 1662 0 R 1664 0 R 1665 0 R ] endobj 1660 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1663 0 R /Contents 1666 0 R >> endobj 1667 0 obj 1330 endobj 1669 0 obj << /Type /Action /S /GoTo /D [1668 0 R /XYZ 72.0 720.0 null] >> endobj 1670 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 201.64 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1672 0 obj << /Type /Annot /Subtype /Link /Rect [ 207.955 624.028 280.145 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1673 0 obj << /Type /Annot /Subtype /Link /Rect [ 286.46 624.028 320.89 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1674 0 obj << /Type /Annot /Subtype /Link /Rect [ 140.56 612.028 193.34 621.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1675 0 obj << /Length 1676 0 R /Filter /FlateDecode >> stream xœÅXÛrÛ6}×Wà1™±X\xô–ºi'ÛšéCšŠ‚m¶©”õë» x@ÑRÒIã̈¸ìîÁž³ À/3‚0üÍõO$(J6³/MAE,lº‚ߣÚ æ9@™ž5x íü˜Iðð„þ˜å3Œ~›}ú ƒk„Áàe†mwµñýìv_àˆ€ú¿ ÐjVj^(ü¼šœƒÀLJ#âºþ¾·ÈLô˜Øz(k2Ýü æÑ¬Çü]î—ÇóجðÇÇèqöóröÓ¯"-zGÚ`S¡ÿQ´Ü Oo(Þ~FËßgï—Ž~pÖ"uìn=  –cŒÉÁ²jr£fQfM×ñFšE¤Áçˆ ‡žÏÁýíÕüòæúúýåòÃÍõüýÝÝÍ2:;A6txŸxø³ËcoÀ§ PRäë´J‹•r[J%ó*Í‘,Ë¢Th½+u &å2ѳÚõD#ëñ‰‡ß¡ñ}Ù¹^î·]&Ž'0^@¸ix™ÅJ¡¥LäZæ‰DW©ª¦2*˜Ç1Ï"0Ô—lÞƒŸ×«²ó9 ™N ®ƒ ô&1šyc²ÀA“9¼Ž«x+9—bîÌ}—‚ÐüòFd<îh8Ÿ{œŸ²L•n¶Yƒy¤¿ÌpÌ,Ë´Ø)3{na¦,ËÙ!÷-×Hï_ŽIîãÐJ<¦i ™?bzë¨^×&aúý˜*ª=ü"UR¦ÛaQŒI’° á³Æpù”ª±²SmÑUOq…Š$Ù•èå)Í$ªÊ½®Âªh Q?ƨ•—7’^ލ=YV¼hWiÁã,ý'®1ÄåãnSCˆó5Š“D*¥‘ȯPp‹©š'‚Z>€kð·@G³ÂA} ›ºqí]ÕTƒ]c,6žeû®AÞ¶yòF®ƒ®zæ§£ ¡åd Œ‰,Ì<j$¡?椉t|`®YÈÁFŒâª’›m5 ÚÚ;×~1ØLÕV&“Ñ}[ƒçÒã8èé9G`Kì[rœ,éÐ(Ò‡41µSr Ev„3onh‹òLÒû®¢&ÃF¶ÏeËqàÓ$n‹í[hrœhšÚð¨XýUïžzƒ}‰0ô\dÏ=Uiž¤pÒ˜&ý]¹ö “¥t=–Ø <“ ×AOÐI¨-¬C‚м;«¡‰}þň+M“ñÛ¨L“¦ûžyPûͪȺþp;tPz¦¯”Õ®ÌYÓ\훇ª‹Ó‰¢™'Ïe¾öšvè9ÎvR¹ïXÆlÁë—§’›ŽÐ‰BÅh ^õq©…UÉò!†#l vZbþ÷mÜ®ýBI}äˆËýi\‡ß¹w»z± %šÞ¾Ñœ‘Wtð6/ޝ†fí¢ƒÕv ”¨›FoõÌu»c=h«Qwå¨Û«.HÕ*²žÔJrD{|¬€ŒRÑ'Ca+üL:ö‹ ˆ(~œ|øØï™Ús¸—±áé j+ØÖážÿŠòüÀǘ²1oïzªªoÙ]{]Zô5:1mY¬2¹ŽÂ­kÕw‡R®/…Ré*Û&å‡C}šžÕþHì¡J›©Z§®F}f[¯å©«Üm=¡¿#DPæCJQµðø%ËçG#&xÈéáû„qA‚³¢4û NßwTY„ Ï'€“…áH ã‡(õ£)O§ ¡AäEBe¢ÑIhî/$&‚)wÜåëSðù4ò © Gñ‰EDÖÔ‰S¾[j!ñPoy­MèØD£¤ùŒâ_^Ýß^§ƒ1Õ⥣‘å×Jæ p+oðYóvö/{9½ endstream endobj 1671 0 obj [ 1670 0 R 1672 0 R 1673 0 R 1674 0 R ] endobj 1668 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1671 0 R /Contents 1675 0 R >> endobj 1676 0 obj 1390 endobj 1678 0 obj << /Type /Annot /Subtype /Link /Rect [ 216.739 624.028 288.929 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1680 0 obj << /Type /Annot /Subtype /Link /Rect [ 293.488 624.028 327.918 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1681 0 obj << /Type /Annot /Subtype /Link /Rect [ 140.56 612.028 193.34 621.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1682 0 obj << /Length 1683 0 R /Filter /FlateDecode >> stream xœÅXKsÛ6¾ëWì1™±X<øÔÍqÜN;™¶NÔé!Í¢ ‹-E*$Ûýõ]<(B$E[M'µ=CbÝýv÷Ãôç‚¿sõˆénöÙÊ(D xhEAÔ÷X;°ïäj•óÂÚ7|˜Eø²…ßgÅŒÀ³Ÿpr f¤oN+˜Ý9þÕ ùæþ]œ²ÿ «¢ëÂð/òtqN&ŸœÎ8…;Ê;©vÈ %Æ·šÊm¦íÓ1¯&ó<é ãy´~;çîgo–³ï¾€Xn:žGJ‘/f‰úa°ÜÁÇWŒÅ¯?Áò§Ùír@€oœµA!•ïc<(6&„Г°tq#”‰ég±“&¨‘4ø1°Ä#a ÖÇFáÃÝ»ùÛëåõ›ë·úe~ûþý/ïÁ9ªÒ„cöAÄÙÐÈŒE=F¦à·Z®¡)¡Îî ‘ƒ(@VUYÁCÖl¡ÙJ@\°€½¨íZ¡+QK¯ 1 ѧIú ¯›²XgMV°|Ú“s>§aâ4N’ˆÚœÞä~­d*ײH%¼Ëêf*É*Wc§I`,ÔŸóy‹]¿Ìu´Wð|ߣðªŸm”F1Ä>}Æš6ÔÏ= ½„%[ ÕÏzeŒz~Œ)ÁR{u^B#µ­¢)gu¶Û粸•¦mº™þBYeå¡6+ç= ˜sJ‚žkkîte{"b¤šÓ@EÅx„Ò¯ f‡sE+î¨^Có<Ë(WÍ? 3n,¼•uZeûÎõ8¹h€!pÌ·Ï­âr›Õ˜§9%Ô‹àÕ‡#«ä¾’µ,w¡Î°+h¶¢q†eš*gü°Íréê?ÊôÐdŽ#SÛ¶ÕhäN¹½r¥{™f›,yþ䈅 Eœ€¯ù °ÍHýU?IËN䛲ÚaïP ä£Ê@i©½í„ ’*aSæyù Ì ̨ȳ¿…N¬¨î:,l\kiŠ–U*å#v†ÅTsbÄï9úM£½œ-zŒ›Š+ Å|DÑE6é{©ⵅÝyNúz õ‚ØR~hàØæ/„ÀúÌu(??Å£„… FèYÚÓ¢Û²–`ù‰ãTô‚+5àÉóƒù}&]X¢þ¢íÖ“nƒ>/-ÐÀ@W ûÔú7åQåiÝC¹úS¦ èFó€>+¾”ù,MVèêdEšáÛL(ê3ñ ô&KÙzÒmÜgÞ¥pvÐ þÉÁËÊÔ‘0ê˜:‘@a•ÕžÐKzož…Áâ…æˆ &a /¼ ?H"•[ü¬‚í UÊq„Õ¨ÍÃpDùæ^xÏWËš¨oSîó1Ïò±‘…û%¤ÿÿu7ûâÕH÷ endstream endobj 1679 0 obj [ 1678 0 R 1680 0 R 1681 0 R ] endobj 1677 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1679 0 R /Contents 1682 0 R >> endobj 1683 0 obj 1400 endobj 1685 0 obj << /Type /Annot /Subtype /Link /Rect [ 203.184 624.028 275.374 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1687 0 obj << /Type /Annot /Subtype /Link /Rect [ 279.698 624.028 314.128 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1688 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 612.028 172.78 621.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1689 0 obj << /Length 1690 0 R /Filter /FlateDecode >> stream xœÅX[Oä6~Ÿ_áGVbRÛ‰s™7JiÕŠvvªªÚH›Ëg€é¯ïq®Ç30jE)ö±Ïýóñ1 ‚0ü.Õ'ˆ(JŠÅcO#( Èõ{óñÊPú1C¹Ú¥ è0‚O· è·E¹Àè‡Å—¯°˜" Ï lŠk™?/n4ýj¿»~Ý—ÐÿÅeC›•6/þ§MÎÞóðþŠ–¸‘>Q[…nGJ§[-å}¤ûogH7ìüé¾ýÀ“ØÇÞÃ÷SŽÑýâÛõâ›ï"­ï&œŠ‘`'¤‘ú¡h] /g”F¾¢õO‹«õ ïµY"•îÑHlˆ1&{nµÉ z§:Ÿ~á…蜲„Á ì3µ?ì>ß\/×W?úx{qûûòêööã-êŒl$ V<˜=ð¥Éc@¿J‘¢¦B2»/yŽ8jD±©j^ï¨ëªFY‰šRÞð˜Kbžü%ÊÔ ,Žy 2 Åï´\Veš5YU¢õn3†äp$ýÈa$“IÉËœK‰>Õ"©(®3Ù mä:!¦ 9bù˜/G×–­kçèòÇGgfÈ\âÐØž]ÒNÁN±ë¸ ÐpÏØj¥¨Q©Á̮ժ̣QAd‘ÅëI™ÌŠM.LÇ{j2ägZ17Š:«¶RÛiØ1'˜YŒ9Ì cìBb`c=GšQÍë!®ªß c/ì¡ýIm&Õv¤:ÌC<·g\?d_âxèl4c"ÕbS )ÊFÛÖÆK›WI²­ë¬¼ŸHÏB¢Õ8Oפ–—eÕhsóÝDÚÔU"¤¦“OÃ'žgé4ÍÊFÔ<±¤AE@Uä½Ä"á[)ÎÑñÂHÎQÖ Œl²<¢H¶rƒ™¢†t/S´©¤Ìb°3“r µ%Þ[@díXôGt–ªó¼zV²âþüÍÛ4ðú~[´ÁWêx¢b B/^ &¬Ž•%Š=CÑ ä­ÐA„„p¤\…·Ðµð¯†ÄUK|ƒí¢7zÒ™|qX¨*¨ëYŒÕ`ù&¨ qílñ@!£¾2Â÷,BÖúµPÅФ«‚7è™KHÚS•?Aþûû#+“ JwsôÞ ž‰Ä4ã_uQÊÒ£j™ ÀS40%èMø&°ö„–l¸.¤É%êR÷#‹¨uWh@B ç¦Î’~G»È]WùHï®ý~i#’ì.KøP™ª~Ͷ.EÚOã]?hF=z5S; cXª–¡ŸOA•Ú 9¯40¯ŽºP`š,‘¨ºLA-âµ”¶;=Á`ìqˆ…&ŒO„ØŒ%…º#ƶâ•\ƒ ¶¹€ l'šBLØš°sÉ+¸ca—¹¬>ÍJÄhÖ@Ш¦ÞÚÕ|c»h¢Qu8ªy<*i&tD¶›HαçRÛêŠþ3º®‰ðÓ`8ç_"~ô"p=¼§bo&`~-ßbˆobØD Ußr{<¿1umÒ.&²»°vž¶Šâ=ÚЋ…}[ç¢ÐWy3ͺÆN¤çÇÐòL›JM ŽÐŽïèÞë»­ ©”æqÓßd‡Ûdˆ˜©§YÇ {¤VÍP‚í ²G™Cá9ú!„Ì¡;š¯Ãà!$‚·Bf‘t¸™Y/[ÇUÍ#Ô"Iµ¦|´ÃŸq{ÌQo«ˆ®…ûòžÞ‡UÀ¬Ž Í¦Z¼4¢”€\GûÆÍâò2È^ endstream endobj 1686 0 obj [ 1685 0 R 1687 0 R 1688 0 R ] endobj 1684 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1686 0 R /Contents 1689 0 R >> endobj 1690 0 obj 1336 endobj 1692 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 201.64 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1694 0 obj << /Type /Annot /Subtype /Link /Rect [ 207.955 624.028 280.145 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1695 0 obj << /Type /Annot /Subtype /Link /Rect [ 286.46 624.028 320.89 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1696 0 obj << /Type /Annot /Subtype /Link /Rect [ 140.56 612.028 193.34 621.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1697 0 obj << /Length 1698 0 R /Filter /FlateDecode >> stream xœÅX[“›6~÷¯Ðc2³¦º @~KÓ´“ζé&îô!ÍÆÚ]Z ÂÙl}¸X¬tÒlfŒ¤sÿ¾# >.Âð·Ô?± (Û->Ú9‚bŠXd§x„HPŽvÈ>sTh©ÑížàÇÁÃ=úcQ.0úiñþ,n…‡v͵Êï7#ÿzsÿã¡ÿK:†• ÿã çh‡øxe\??̶™™ƒã[/¶Òö×bM>æ÷dxHO×Ñføíœct·ø~½øîGŽFëÛç±V$8H¨Ðÿ(ZïÐûg”áçÐúçÅ«µG€o\5Hí»Ï‡!À&cr”V nl“29ýšî¤Ij¢ a‚¨pĵ|bÞÝ\/ׯyõæ÷õòÕÛ·oÞ"£Þ+¥Ð¾ÃdBýOJcW!šS@YUnó&¯JTË}-•,›¼¼C²®«Z¡‡{Y¢T •2k¥š|'ªMÐåOä’ n"ãæeïeý¸ï+rº‘8I„ˆ‰-äË"U ýVËLne™It«f®²‚ ¦`YpcA},–CË6A·TPžˆéê0á¸BÏAˆàÎ3W‘ñ@p ›ö¼M›t“*9é—â$ !¨‡4¾È/Â…Ô/ŠÉ´ßIwa$É9iª|·/lÌó=wÆk¾°¬óê ŒôÒ‰"˜;!X“Ç’QpÍÜXïcžŠEׄãÁJ¦aX8¡z…Fy4Os“0}NpÓP­…¤Êê|?¸ž¦$á‹…™U\ßç *Ń=ÑNôý؋ئ´£æ>mºç*Ëu7h›¶’ÝcGÁ~©íäÎÀ¡Ôó¢Ú×U&•Ò[‚QÕ®_­ö²NuÌÁ¬z—w²•è¶*ŠêA›ËKÈ6-òZ(­ï»6Ù´Ü¢4Ó^u²ò34újn¯! u½Ó`o…N¢‘ë6ýêë¯únmF»Õ¤o:º/läƒsáê h‹¤££g ïÚåÙQP9FFŒœ©Á, ‘Ž$ §Œt„Ñþ¹i6΂´iänß̆F\Î_ޝ¿mâj/³YïÌåà…ðøx.‰#t)ö%yFÖÇpè(òÛ<3 uPr Mv³ÙÓ›r—”‚æé÷5ë6rx)Zž¿™fˆ]²} Lž S¿ùV›¿ ÔnÞ©„>Uŧª¼Ìr¸á<piy!@žþÊT)ßιeØeà…ù€Î €¸Ä:-û;Ò ˜Ñ÷žHL˜Z·G¥¶PÂITç™Uµ}P»MUôómÀÝÒQ뙹Z6‡ºdÍpóhšÞÏèDn%Òìï¥,·}J‹ƒTþ˨Kx}x*¹KáŸÁ5ý8WŒ´ÖÄjd}›ÂÕ¹ v–bŒ}ÝÆí믔Ôwœ´~<kþ•{·o` Û…¡DóÛ7Z2òïxÒÕųeaÖ&ú°º‰õÐð­•qQ{2¶‹.õ䘎z¼é4CcF¶B%'¸O5a*úïh˜¸ ¿†žþ n½*½›=˜pÉ{)÷<׺3 ‰Ëa—yp? Ÿà^ÈCŒ)›²öb0¡šÚÜòíxÛ:ÚÍY¦˜¼l ¹¯¶/$vÔ¾’Ôr{5Ò¨àMbS<Ž„Ê‘Á1CÍÌæñ„ï1O­¨fªÏÒºí6°yî%ÞÆ¡¿`ÄÐæSNÕt[ðôë]󀯀|”Ðã¶B.ªf4^q†¹“Ü"L€Æ,Š&¾æxÒ0ž³tuN4”ÇA,ôw.ŸÍÑŒ|ÎܸfåöœøBÊ<èE*èÉø¦È’ÄŽèÌ=ßoµˆNXh7½N'òtbPb?àøÊ/¯ßÝ\Ÿ†ƒ2Õ䥓žåçF– âVÁèÃêÍâ_öœÙï endstream endobj 1693 0 obj [ 1692 0 R 1694 0 R 1695 0 R 1696 0 R ] endobj 1691 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1693 0 R /Contents 1697 0 R >> endobj 1698 0 obj 1433 endobj 1700 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.028 201.64 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1702 0 obj << /Type /Annot /Subtype /Link /Rect [ 207.955 624.028 280.145 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1703 0 obj << /Type /Annot /Subtype /Link /Rect [ 286.46 624.028 320.89 633.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1704 0 obj << /Type /Annot /Subtype /Link /Rect [ 140.56 612.028 193.34 621.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1705 0 obj << /Length 1706 0 R /Filter /FlateDecode >> stream xœÅXÛrÛ6}×Wà1™±X\xƒÞÜ4é´ãic[3}Hó@Q°Í–"‚Š£~}EBDKI'3#â²»{Î ?ÍÂð7W? §(ßÌ>õ}%±¸ïŠbD€Fhƒúç•j–ñ@Oð£'ÁÃúcVÍ0úyöá# ®ƒç¶ÝuÆ÷³[#¾Áß=¾‰€ú¿ P:V:^(üO‚Žœ£(ÄÇ#qCÿØÛdºztl5Tö™î5ý¨×£O®ËÀþ<ö+ü~Á1zœý¸œýð.B£åèóD¤”«-7èÃ+ÊÈëhùëìíÒÀwΚC¤Š=¬‡!Ħcr´¬ŽÜ¤_”^ÓoÙFèEyÒ¦ˆòÇ‘šŸjƒûÛ›ù»ëåõÍüíÝÝïwH&$$AL 2މkü'¥‰mM ¼®ÖE[ÔjĶRTmQ=¢ =dmV"Ñ4uƒŠ :ÖбʤP&•È•Íaa‰ga€s ‘béÍh¹ß)9ɘI9OHŸÉ7e&%z߈\¬E• tSÈv*µœ)¦à™GÚƒüTÎGðónmv¶ C1S bÜup…^Ã$F@<¯lC<Š`rÊü‘ùóÆ¥8 Hæ!M.ŠKAqa¬ØMˆ?®7\˜izÎ2e±Ù–=fOÿ sÌ,š¢ÞI={na¦Ž,½Ëã™qDJ¼‰ÚÈ“ž] Ç¡•LѳÐcz…Œu´/k“0uP(¶Ò¾Ž~2oŠ­Y>I’–ÀÎCÖ.Ÿ é+B©KO¢:ÏwM£jòùIT¨}¾JD४QYW¢A;™­Jxb'¾@uYÖÏ*DQŒ¬,þÉ:§Yó¸Ût`²j²<R*Lâ ”Þbªú §V _À5ø[ “ùIA‡ ë ríCý´Æþá‹MqhÙ^÷ÈÇàܶã Ô´ˆë`¨£ùù(Hl9142‘‚Y@c…$}NÜ«øÀ\Ó)ÂBÖ¶b³m'¡Q[…—‘ãÚ/ŒmUnE>=´5x)=Žƒ‘žKpD¶Ä¾† ÇÉò˜…¢x(r]P;)Öê4õsLÂmQ^Hšc?TÔdØÄVà¥l9ÜbšÚbûš'Ks­WÀJÖ¢çLCŸëòóHUQåÜ9¦ ‚DA®ýBg©XO†%¶/$Èu0tj ë˜ 4n-'hbDÝDbîq¥hÒ*8‰š"ï[°ïé¹ß¬êrè×÷Õ~è¨ôt_#Ú]S³º¹Ú÷ígE?#Ëÿž‹jôíÐç¬Ü éž±ŒÙ‚W‡§› ®Ö9è )8®³F «ÍC—ÙØi‰…ß¶q»ö )Ôå#köçqãÞí:Åv!”dzûFsF^Ð]”òâøêiV.X‡C‰ª©õÖÍ4´¨Úƒ»A[ªÓ”£j¯† íÀTd7é IöR_i¥¢ÿN†ÜVø…2tìQö8y„Øï…Úsx®uç¡¶†må‘4_Ð^…Sæóv=ºmwóÚë.ÐꨯWŠnl›nþsδ¡¥_&Äúʰ¨¥,VåÞ˜TM…êžÕþDlS§ýT¥TW¥!³ËmTóÔk¼ç\}SH  ôוº=lÁþ®0š0žÆ)=>QX0HpY·Fs|ÅûNj‹0„êË ‹cO Ó×( “)OWç ¡Q$\}z¢ÉYhŽÞ`HŒGSîÌœUësð…4ò )§'ñùÄÂkêÄ=ß-µ˜z> endobj 1706 0 obj 1390 endobj 1708 0 obj << /Type /Annot /Subtype /Link /Rect [ 484.72 669.641 537.5 678.641 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1710 0 obj << /Type /Annot /Subtype /Link /Rect [ 308.745 657.641 361.525 666.641 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1711 0 obj << /Type /Action /S /GoTo /D [1598 0 R /XYZ 72.0 720.0 null] >> endobj 1712 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 566.345 284.97 575.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1711 0 R /H /I >> endobj 1713 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.449 566.345 541.449 575.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1711 0 R /H /I >> endobj 1714 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 554.345 197.76 563.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1715 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.016 554.345 542.016 563.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1716 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 542.345 175.56 551.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1717 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.162 542.345 542.162 551.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1718 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 530.345 190.54 539.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1719 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.063 530.345 542.063 539.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1720 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 518.345 247.2 527.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1622 0 R /H /I >> endobj 1721 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.694 518.345 541.694 527.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1622 0 R /H /I >> endobj 1722 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 506.345 204.45 515.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1723 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.974 506.345 541.974 515.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1724 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 494.345 232.22 503.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1725 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.791 494.345 541.791 503.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1726 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 482.345 243.88 491.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1727 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.716 482.345 541.716 491.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1728 0 obj << /Type /Action /S /GoTo /D [1677 0 R /XYZ 72.0 720.0 null] >> endobj 1729 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 470.345 263.32 479.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1728 0 R /H /I >> endobj 1730 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.589 470.345 541.589 479.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1728 0 R /H /I >> endobj 1731 0 obj << /Type /Action /S /GoTo /D [1684 0 R /XYZ 72.0 720.0 null] >> endobj 1732 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 458.345 240.56 467.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1731 0 R /H /I >> endobj 1733 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.736 458.345 541.736 467.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1731 0 R /H /I >> endobj 1734 0 obj << /Type /Action /S /GoTo /D [1691 0 R /XYZ 72.0 720.0 null] >> endobj 1735 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 446.345 223.88 455.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1734 0 R /H /I >> endobj 1736 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.846 446.345 541.846 455.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1734 0 R /H /I >> endobj 1737 0 obj << /Type /Action /S /GoTo /D [1699 0 R /XYZ 72.0 720.0 null] >> endobj 1738 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 434.345 211.11 443.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1737 0 R /H /I >> endobj 1739 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.929 434.345 541.929 443.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1737 0 R /H /I >> endobj 1740 0 obj << /Length 1741 0 R /Filter /FlateDecode >> stream xœÅÝÁrÇ€á;ŸG'!3ÓÝ3ÓGZ¦%ŽKLR©TI[¬¢È˜¤íÒÛgzwéð¿8¶« ’ÿ |t-?åUÿ>‹ÿ5/«³G?l¿—W­¬¤n¿eu•u]lõaµ=m««¨N”O§Æÿ6Ñ8ñ~õ£ë£´úÃÑ¿þ=~x¾JcƒŸÒó›6~sôíÁåÇOÒ¯~ù‡{ ¹ü_ö öaR™\Êø¯­'œÏ~`š>ÿÉÜîûûïN(›ïïl.;~tµ½¥·ÿßìÈæäæúlþÿèõHû«‘–oÇí5üõ.<­¾?úòôè÷_Û*§Õéwûûy‹ sZ÷âñOY~Xýë‹’ý7ÿ^þéèätvø•oµd\öîúȪèºO;ÿÙÕÊ©®knîµ”UÉëÒ[J©ÖÍÕ{þÍ›o¿Y=¿¹>¿¼¿¼¹^½ùxwñasÿu}xiÿ­sïãRr?8‹O[ÌoÕ¾Ny\`÷øÙ¦«ß¬ž•:nÄ/þs{óÓåùÅÝþ;o¯Ï÷_üx÷Ùö'Ïv{¾ûÖÝtö__üìç÷—gïÎèêjÿÅÅííÍíc;ðóÛÛëËëï|{±ÿâæ»ýéûÿ9øÉæ†Ù߀¹¬[·G³Ûãg»kôpËjãþ1Ûdý0뫚4§ï/cÇMÆÿ‹»‹³ííµùzÜèg·—ï.öÅýû‹ÝéŸÞÞ^Þüx°õïήÞÞÝäÓußœ|°/E꺩ºÛx°Ìöê—®lé¾¶2¶Ÿox°ëß]^_œï¾~÷ñÁž,܃El­ÙÇ#@l~Ö¿|_–A c×úxdÎ6]ï.û«‹û·—WûhsOÙž¾º»Ù}±½ÓŸÏ [ç>v²Äƒ9Îý»›Û±™¤µ®¾xóóîô°ú¸ûbsA›Óãs¾ûbzlN>zÃd÷/·Í=svù¿|Ãäf뚺É|Ûýþ]îÒýÅõùÁ>ÞßìN¾Û_»Ëï¯Ç£tùºŒë¸¿UÎnÎ/Ö»¯¾¾ŒÍ>þnFW7÷û9;»¸»Û<Ú7ß9¼}ïn>\ÌIº>¸Zã~”ý3P<ðïVðé1u¾þt“ɸÆSo<ð?»åÆsyék«y|ç"oÛç¢ùùÄsذ´ùÃ:×uŽ{J“¥í>#ß (/…åÆòŽrÉ,W–7”kb¹°œ©*S5¦jLÕ˜jeª•©V¦Ú˜jcª©6¦Ú™jgª©:Su¦êHUR•„T%!UIHu¼µa9R•ŒT¥ U)HU S¦*LU˜ª0UeªÊT•©S5¦jLµ2ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT©:Su¦êHURÕ„T5!UÍHU3RÕŒTµ U-HU RÕÂT…© S¦ªLU™ª2ÕQ”2$žÐ;Q¿TÇ›r˲°])iþ>>§ïϳ7ß~óìù«—_½8}ñêåƒ òx{Ùêv~9ß4ö,—z}¶kyÜ7JoøMÚ†o<î(7–w”ûÊ•å å–X.,¯,gª•©V¦Z™jcª©6¦Ú™jgª©v¦êLÕ™ª#Õ’jIHµ$¤Z2R-©ÆÜåH5æŽ(Gª1w$¹0UaªÂT•©*SU¦ªLÕ˜ª1Ucª•©V¦Z™jcª©6¦Ú˜jgª©v¦êLÕ™ª#Õ˜;¢©ÆÜåH5æŽ(Gª1w$yAª1wD9S¦*LU˜ª0UeªÊT•©S5¦jLµ2ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT©:Su¦êH5æŽ(Gª1w$yFª1wD9R¹#Ê‘jÌQÎTÙlIÙlIÙlIÙlIÙlIÙl)掖š»ÕŒ¦{:Þ'¤lî¹,mXJ^<ŽçÀùàñäõëW¯ŽÆ«2gî-ŽŽm¶Ù­¾Îó¡ãx»ž5¹÷® ÎF ãí:Ê…å•åŽò8LˆäÆòqóê°¯Úž’ÇaB$W–7”ÇaB$–W–;Êã0!’Ë™jeª•©V¦Ú˜jcª©6¦Ú™jgª©:Su¦êHµ$¤ZR- ©–„TãðQ”#Õ’‘j)Hµ¤Z S¦*LU˜ª0UeªÊT•©S5¦jÛWKÓ‹¸ÿ×Äraye¹£¼–Ë;Êã0!’+Ë™ª3UgªÎT©JBª’ª$¤*©JFª’‘ª¤*©JAªR˜ª0UaªÂT•©*SU¦jLÕ˜ª1Ucª•©V¦Z™jcª©6¦Ú™jgª©v¦êLÕ™ª#UMHURÕ„T5#UÍHU3RÕŒTµ U-HU S¦*LU˜ª2UeªÊTczÛG>ž,ј4¦·¹fïM¶+¥, oÇ«Êùðvû–³If_›Ž4yYØp³_K/3ÍÔ²{¯ Û-4IÝG]FPä)ù¸×¡\YÞP>îu(–W–;Ê­°ÜXÎT+S­Lµ2ÕÆTSmLµ1ÕÎT;SíLÕ™ª3UGª1ÑD9R‰&Ê‘jL4QŽTc¢Iò‚Tc¢‰r¦*LU˜ª0UaªÊT•©*S5¦jLÕÚæ%Aòö”¼&– Ë+Ëå­°ÜXÞQÞ3Ë•åLÕ™ª3UgªŽTc¢‰r¤M’g¤M”#Õ˜h¢©ÆDåLU˜ª0UaªÊT•©*S5¦jLÕ˜ª1ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT;Su¦êLÕ‘jL4QŽTc¢IòŒTc¢‰r¤M’¤ª©jaªÂT…© SU¦ªLU™jL4%§d‹3½Ç'‡Óñ¨µxïeiVYŠ,Œ4ÇK³ùHó«ãÓã/ßœ<6ÛœÿT·…sˆ=/nÛ|´Ùb&ZÝ[j ÛÍ' ™åÊò†òñ‚åÂòÊr'y/¨Qn,Gª%#Õ’‘jÉHµ¤:B,Gª¥0UaªÂT…©*SU¦ªLÕ˜ª1UcªÆT+S­Lµ2ÕÆTSmLµ3ÕÎT;SíLÕ™ª3UGª’ª$¤* ©Ž:,Gª’‘ªd¤*©JAªR˜ª0UaªÂT•©*SU¦ªLÕ˜ª1Ucª•©V¦Z™jcª©6¦Ú˜jgª©v¦êLÕ™ª#UMHURÕ„T5!Õø$”#UÍHU RÕ‚Tµ0UaªÂT…© SU¦ªLÕòzüñ®1_yúô"Ö¬‡t]Ø®WâÍî|¼ò·7'¯—ÿæw¼¥‹Ê˜+ómcׯK½…ÁÊxoçR70ßn6>ïíH>ÞÛ¡\YÞP>ÞÛ¡\X^Yî(ïíPÎT+SmLµ1ÕÆT;SíLµ3ÕÎT©:Su¤+¢©ÆJ€$ÏH5VD9R•I^j¬ˆr¦*LU˜ª0UeªÊT•©*S5¦jLÕBµ¥œ[yJ^3Ë•å å-±\X^Yî(ï…åÆr¦êLÕ™ª#ÕX åH5VD9R•QŽTc%@’¤+¢œ© S¦*LU˜ª2UeªÊT©S5¦Z™jeª•©V¦Ú˜jcª©v¦Ú™jgªÎT©:Su¤+¢©ÆJ€$ÏH5VD9R•QŽTc%@”3UaªÂT…©*SU¦ªLuúðñrß-“ñ[L½m?¹d¾Ýxo¸0,KŸ@²;ðjq:KÅ~úØàùöÓàÒ×u>¿)j¬SØ$/l7Ÿ#U–;ÊÇo ”Ë;ÊÇo ”+ËÊÇo ”3UgªŽTã3”#Õ8ÂŒä©Æf(Gªq„Ê‘ja†r¦*LU˜ª0UeªÊT•©S5¦jLÕ˜jeª•©V¦Ú˜jcª©v¦Ú™jgª©:Su¦êH5Ž0C9R#ÌHž‘ja†r¤G˜‘¼ Õ8 åLU˜ª0UaªÊT•©*SU¦jLÕ˜ª1ÕÊT+S­Lµ1ÕÆTSmLµ3ÕÎT;Su¦êLÕ‘ja†r¤G˜¡©Æf(Gªq„É R#ÌPÎT…© S¦*LU™ª2Õ8ÂÌÕ»§¥üÑAMÌ‘š'ï–—¶oöæH²ôÏ_½|yò<>Êvy’4^u÷>¶Ñ¾tÓÚÒçÙÆ'øÈذš/l·4!y|‚É•å åñ >$–W–;Écƒr¤Ó’g¤Ó”#՘Ơ©Æ4åLU˜ª0UaªÊT•©*S5¦jLÕ˜ª1ÕÊT+S­Lµ1ÕÆTSíLµ3ÕÎT;Su¦êLÕ‘jLcPŽTcCòŒTcƒr¤Ó’¤Ó”3UaªÂT…©*SU¦ªLU™ª1UcªÆT+S­Lµ2ÕÆTSmLµ1ÕÎT;SíLÕ™ª3UGª1A9Ri Ê‘jLcPŽTcCò‚Tcƒr¦*LU˜ª0UaªÊT•©*Sá<·Lf#Óð&×”DËÂv¥´…á.-(¿;(N,ÏoÆó‰Ä‘@MÊ™Ä>Æ_GÏç7›1oJ¦¾°Ý|ìÐH^6cÞ§çÂòÊrGùfÌûôÜXÞQ¾ó>=Gª¥0UaªÂT…© SU¦ªLU™ª1Ucªª‡ ÊSòšX.,¯,w”O‡‚ÜXÞQ>Bre9Su¦êLÕ™ª#UIHUR•„T%#UÉHU2R•‚T¥ U)HU S¦*LU˜ª2UeªÊT©S5¦jLµ2ÕÊT+SmLµ1ÕÆT;SíLµ3ÕÎT©:Su¤ª ©jBªšªf¤ª©jFªš‘ª¤ª©jaªÂT…© SU¦ªLU™êxwPbu¡*FÞÒÇØÁz÷î¥.lWJ_;X,^¤Þm\Önìpzò—¿¾z}üúŸüñQ_›¹{³ºpÓX¤®}ᑼöñº4¥n ÛÍF±Ì ÉÊc™’ Ë+Ëå±Ì ÉåäÓ23$GªÓ23 ÏHuZf†äHuZfä©NËÌœ© S¦*LU™ª2UeªÊT©SefÊxÊ_|&žW2ªÕﱀ ¨ÕÕNêX^Ô†jdéÈÒ‘¥ËiaPËiYPËiQPËiI™§×…XN Ê€Y ²d)ÈR¥"KE–Š, Y²4dY‘eE–YVdÙeC– YvdÙ‘eG–Ž,Y:²tb9-jb9-óô:ËiÉPËiÁPËi¹P#KA–‚,Y*²Td©È2Ž©-%'£é1÷ñ^ea»R|aTÓòÒ¨æÅ_N^ýítyPc‡Û3Û|ZĦ¬e>¨oB$wima»ÙÀ`¼ !ùx‚reyCùx#‚raye¹£|¼A9SíLÕ™ª3UGªqøÊ‘j~„r¤‡¡©ÆáG$/H5?B9S¦*LU˜ª0UeªÊT•©S5¦j¡*)y’§ä5±\X^Yî(o…åÆòŽòžY®,gªÎT©:Su¤‡¡©ÆáG$ÏH5?B9RÃPŽTãð#”3UaªÂT…©*SU¦ªLÕ˜ª1UcªÆT+S­Lµ2ÕÆTSmLµ3ÕÎT;SíLÕ™ª3UGªqøÊ‘j~DòŒTãð#”#Õ8üˆä©ÆáG(gªÂT…© SU¦ªLU™j,}<Þk%ÍF¦F1ÓêZSêK—2Îpa¤Õea¤õõñéñ7|(š¯sN›ƒšæO»V—þØ)>E®éöÃÔfÛͦ ñ)r$ï(·/Ê•å åãÝÊ…å•åŽòÆTSmLµ3ÕÎT;Su¦êLÕ™ª#ÕX±åH5V,"yFª±bÊ‘j¬X„r¤+¡œ© S¦*LU™ª2UeªÆT©Z¨Z|NÀÒoÌyî(¯…åÆòŽò–Y®,o(ï‰åÂr¦Ú™ª3UgªŽTcÅ"”#ÕX±ˆä©ÆŠE(Gª±bÉ R‹PÎT…© S¦ªLU™ª2UeªÆT©S­Lµ2ÕÊTSmLµ1ÕÆT;SíLµ3UgªÎT©ÆŠE(Gª±bÊ‘j¬X„r¤+‘¼ ÕX±åLU˜ª0UaªÂT•©*Sa\•íßô=}⥇Ï6+’7ýÉéÑ·ãßÿð¡ endstream endobj 1709 0 obj [ 1708 0 R 1710 0 R 1712 0 R 1713 0 R 1714 0 R 1715 0 R 1716 0 R 1717 0 R 1718 0 R 1719 0 R 1720 0 R 1721 0 R 1722 0 R 1723 0 R 1724 0 R 1725 0 R 1726 0 R 1727 0 R 1729 0 R 1730 0 R 1732 0 R 1733 0 R 1735 0 R 1736 0 R 1738 0 R 1739 0 R ] endobj 1707 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1709 0 R /Contents 1740 0 R >> endobj 1741 0 obj 4576 endobj 1743 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 654.764 284.97 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1711 0 R /H /I >> endobj 1745 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 654.764 412.22 663.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 815 0 R /H /I >> endobj 1746 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 642.764 293.87 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 970 0 R /H /I >> endobj 1747 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 642.764 422.78 651.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1748 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 630.764 226.66 639.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 87 0 R /H /I >> endobj 1749 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 630.764 392.22 639.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 654 0 R /H /I >> endobj 1750 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 618.764 204.99 627.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1463 0 R /H /I >> endobj 1751 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 618.764 386.1 627.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 699 0 R /H /I >> endobj 1752 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 606.764 232.21 615.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 136 0 R /H /I >> endobj 1753 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 606.764 531.64 615.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 526 0 R /H /I >> endobj 1754 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 594.764 260.54 603.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 84 0 R /H /I >> endobj 1755 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 594.764 528.86 603.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 523 0 R /H /I >> endobj 1756 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 582.764 313.31 591.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1757 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 582.764 435.0 591.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1031 0 R /H /I >> endobj 1758 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 570.764 258.31 579.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1759 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 570.764 389.44 579.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1029 0 R /H /I >> endobj 1760 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 558.764 279.97 567.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 163 0 R /H /I >> endobj 1761 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 558.764 418.89 567.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 256 0 R /H /I >> endobj 1762 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 546.764 207.77 555.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1763 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 546.764 364.44 555.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 1764 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 534.764 292.19 543.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 1765 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 534.764 390.0 543.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 186 0 R /H /I >> endobj 1766 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 522.764 304.97 531.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1228 0 R /H /I >> endobj 1767 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 522.764 518.32 531.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 512 0 R /H /I >> endobj 1768 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 510.764 203.88 519.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 778 0 R /H /I >> endobj 1769 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 510.764 383.89 519.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 1770 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 498.764 234.99 507.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 964 0 R /H /I >> endobj 1771 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 498.764 366.67 507.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 1772 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 486.764 161.11 495.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 1773 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 486.764 428.33 495.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 833 0 R /H /I >> endobj 1774 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 474.764 167.22 483.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 76 0 R /H /I >> endobj 1775 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 474.764 410.55 483.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 817 0 R /H /I >> endobj 1776 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 462.764 242.77 471.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 106 0 R /H /I >> endobj 1777 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 462.764 412.21 471.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 836 0 R /H /I >> endobj 1778 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 450.764 215.55 459.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 251 0 R /H /I >> endobj 1779 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 450.764 419.99 459.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 1780 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 438.764 193.32 447.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 737 0 R /H /I >> endobj 1781 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 438.764 452.21 447.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 853 0 R /H /I >> endobj 1782 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 426.764 214.44 435.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 805 0 R /H /I >> endobj 1783 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 426.764 348.89 435.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 602 0 R /H /I >> endobj 1784 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 414.764 194.44 423.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 1785 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 414.764 407.76 423.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1786 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 402.764 188.32 411.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 1787 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 402.764 453.88 411.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1788 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 390.764 254.44 399.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1789 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 390.764 473.32 399.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1728 0 R /H /I >> endobj 1790 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 378.764 173.33 387.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 293 0 R /H /I >> endobj 1791 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 378.764 442.22 387.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1792 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 366.764 206.1 375.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 226 0 R /H /I >> endobj 1793 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 366.764 457.2 375.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1622 0 R /H /I >> endobj 1794 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 354.764 265.0 363.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 204 0 R /H /I >> endobj 1795 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 354.764 385.56 363.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1796 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 342.764 201.66 351.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 315 0 R /H /I >> endobj 1797 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 342.764 412.78 351.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 605 0 R /H /I >> endobj 1798 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 330.764 202.77 339.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1799 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 330.764 421.11 339.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1737 0 R /H /I >> endobj 1800 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 318.764 259.99 327.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1461 0 R /H /I >> endobj 1801 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 318.764 408.88 327.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 607 0 R /H /I >> endobj 1802 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 306.764 207.22 315.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 980 0 R /H /I >> endobj 1803 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 306.764 405.0 315.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 632 0 R /H /I >> endobj 1804 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 294.764 223.88 303.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1805 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 294.764 419.44 303.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1806 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 282.764 222.77 291.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 254 0 R /H /I >> endobj 1807 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 282.764 392.78 291.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1808 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 270.764 271.65 279.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 499 0 R /H /I >> endobj 1809 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 270.764 450.56 279.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1731 0 R /H /I >> endobj 1810 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 258.764 183.33 267.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 117 0 R /H /I >> endobj 1811 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 258.764 433.88 267.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1734 0 R /H /I >> endobj 1812 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 246.764 226.1 255.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 141 0 R /H /I >> endobj 1813 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 246.764 414.45 255.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1814 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 234.764 172.21 243.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1027 0 R /H /I >> endobj 1815 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 234.764 400.54 243.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1816 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 222.764 181.1 231.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 1817 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 222.764 445.55 231.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1818 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 210.764 202.22 219.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 813 0 R /H /I >> endobj 1819 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 210.764 435.55 219.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 1820 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 198.764 182.22 207.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 652 0 R /H /I >> endobj 1821 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 198.764 367.78 207.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 191 0 R /H /I >> endobj 1822 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 186.764 176.1 195.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 697 0 R /H /I >> endobj 1823 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 186.764 438.33 195.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1824 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 174.764 242.22 183.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1825 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 174.764 408.33 183.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 662 0 R /H /I >> endobj 1826 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 162.764 268.87 171.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 485 0 R /H /I >> endobj 1827 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 162.764 439.99 171.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 950 0 R /H /I >> endobj 1828 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 150.764 222.21 159.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1004 0 R /H /I >> endobj 1829 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 150.764 503.33 159.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1830 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 138.764 199.99 147.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 189 0 R /H /I >> endobj 1831 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 138.764 445.55 147.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1832 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 126.764 213.32 135.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1223 0 R /H /I >> endobj 1833 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 126.764 473.33 135.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1834 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 114.764 197.21 123.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 750 0 R /H /I >> endobj 1835 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 114.764 478.89 123.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1836 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 102.764 257.19 111.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 152 0 R /H /I >> endobj 1837 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 102.764 418.89 111.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 977 0 R /H /I >> endobj 1838 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 90.764 204.45 99.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 985 0 R /H /I >> endobj 1839 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 90.764 503.33 99.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1840 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 78.764 230.0 87.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1403 0 R /H /I >> endobj 1841 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 78.764 473.33 87.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1842 0 obj << /Length 1843 0 R /Filter /FlateDecode >> stream xœÅšKsÛ6Çïú8¶™Ë§Gˆ„l:AP,5ÍAvìÄS9ÏδýöŃ¢D[½<¸¶gÄ!Åÿþv]K…(P¿XLfº}}oÎ…h¡xÜœJÇ(L΢=¢æ8E;ý­£ƒh¤>ì—ÔÁgt=ú2 Ðùèýuñ# Ô ‚§ræf1º:²¯¯¯nÿ˜ £ÿ…@3˜Q1ã©¿É™œÎ…4 ºWŽ®=8k Æöœ:cmëK»&Òͧ±‡Öûéô#8¸œŽcãáëЧÑ\Ž~[¤( ¼?Ìó‰¾1 ΦÑLÿDH>¢÷¿Dqüë$/GT>›¯µg©m·þÄ(T; ‚ ì¸ewÒ8e}ª¶wÖ©aH¦(šãTjo »oŸ·7w=Ünw¨øòñîtÿõú¶½ýsûée¥¸*‘Ulu"Êd¬pÆ“ð¹âQ4yzCä»e»eífw‡ À×{´ÝíÐÏo¾î~¶ct‘r$UžÛBuzÈ4=‹;ÃýfN²·´Êñ5áUQã9½ ï ÆßœœQ:ÄHY‰½ZÑ*£â¤°‚ÁðÉ.(–d^R¬ÔyAÎ邬Jéæ‡Û±üW%’S²tz0™Â=`UE3‰‹¦keF¸¹áê†ÛDlj< ÀÈù“•dXlªÌM 6´ï zí„ ƒNk§Ή ÔM<@½d)Ë Î aæ ž#j†ä”ëèH²vzÂ3õ©'XnjŸ;p{whô&‚§îÞ›U­ü¡˜Í/U¼$k\ÒÊãÜVÉXŒc"°\ÕžlcxïQµA×O./<üpKR›ê¶qb§ð,.ªB¤,~§ywFy*Ð;5gsÚp:0§Éó£’ìF†+ûC=g•&•œT‚d²`ÎØrYH|ÁØ[76Ü §Í³Ä‰>gÎStÎÊR/zàá†8’ñ%G¯*N—fàd"Råé|%ídwûWÞÇ«ˆ@Éë'ñyAKÏ|‰"pêØ©íF„+îWÍê×NÚœ1¾|1¸pÉ·$ÂØœ êQ­öL¸|‹]ѵ;§D¦rYö”ƒ —Tše¨gÊiæ <ç,sQåôô‚ÇÃu5p皉BWT'÷ž{–{o—VUÙ :ƒ§5UÍM ×ÕÏ•'¹7°qÏ=Ë«w&Nܲ ®Nkýh¥œ3¦ž¦Æ Ζ8S%É]4Xд+G}ÐãC N™Þº1@³CíNÀ‰Ò Wd顆 w¨›V“Þ épÛé"jš¹=€›ÐøÃ ïËtö-nX¸°]×jU*|µÞ‘Q›E›’=ÙWÖÈ ¾(Ãû2¹Z%š¢ZŠëg—ÞhðÜ7¡áYM9ñ•îÞŸiÐûˆ(ˆÝ±Nà˜øÛâvs¥C¡Εtï°äjûÆÙ¦¡7@»'ÞR5ì 9܈—tY3NøÆŸ– ¼³¢\èÛÀ P5ÌÅ’²•ì!†7VÄjýËJš»Ááâ|%Ô8ú©á}•œyšo®©a{žâ ¼‰’sV÷ì[¨ªªÏ%îÔ'3¼ib˜{÷,„-öQóÊÂû&Ú¿ ª;]+gk:…÷N ¦wÛ2@TH=`/™ )¼}Ò¿dË2@ßvÒúZI)¼zcb_¢‚mH¾ª²ÞvŠæ‡wSèšfº'ª»)¤ræÒÍ žvùhFÖ·"ÓÀÛ+ UøúׄŸ¼ ºdÊ'7¼·RTûéIiÐáÚ º v³­+™³Y–Â{.æiãO(ÃWv°»ÿ{Þ9¼Ã/ÛI°Ñqà ᄄYHÕ®ok3@¹‹lC¿Ï^§ðFÌÑ~r¡6ÚžåàõÆ =eŽ+Α ýûs¦È endstream endobj 1744 0 obj [ 1743 0 R 1745 0 R 1746 0 R 1747 0 R 1748 0 R 1749 0 R 1750 0 R 1751 0 R 1752 0 R 1753 0 R 1754 0 R 1755 0 R 1756 0 R 1757 0 R 1758 0 R 1759 0 R 1760 0 R 1761 0 R 1762 0 R 1763 0 R 1764 0 R 1765 0 R 1766 0 R 1767 0 R 1768 0 R 1769 0 R 1770 0 R 1771 0 R 1772 0 R 1773 0 R 1774 0 R 1775 0 R 1776 0 R 1777 0 R 1778 0 R 1779 0 R 1780 0 R 1781 0 R 1782 0 R 1783 0 R 1784 0 R 1785 0 R 1786 0 R 1787 0 R 1788 0 R 1789 0 R 1790 0 R 1791 0 R 1792 0 R 1793 0 R 1794 0 R 1795 0 R 1796 0 R 1797 0 R 1798 0 R 1799 0 R 1800 0 R 1801 0 R 1802 0 R 1803 0 R 1804 0 R 1805 0 R 1806 0 R 1807 0 R 1808 0 R 1809 0 R 1810 0 R 1811 0 R 1812 0 R 1813 0 R 1814 0 R 1815 0 R 1816 0 R 1817 0 R 1818 0 R 1819 0 R 1820 0 R 1821 0 R 1822 0 R 1823 0 R 1824 0 R 1825 0 R 1826 0 R 1827 0 R 1828 0 R 1829 0 R 1830 0 R 1831 0 R 1832 0 R 1833 0 R 1834 0 R 1835 0 R 1836 0 R 1837 0 R 1838 0 R 1839 0 R 1840 0 R 1841 0 R ] endobj 1742 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1744 0 R /Contents 1842 0 R >> endobj 1843 0 obj 1460 endobj 1845 0 obj << /Type /Action /S /GoTo /D [1742 0 R /XYZ 72.0 720.0 null] >> endobj 1846 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 624.345 282.89 633.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1845 0 R /H /I >> endobj 1848 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.461 624.345 541.461 633.345 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1845 0 R /H /I >> endobj 1849 0 obj << /Length 1850 0 R /Filter /FlateDecode >> stream xœÅØ=oÛ0à]¿‚c3D=Þ¿Æ6h‹YŒèdp;)ê¤5Ðþü’¢ÙU:¼‹›M¾y|äAyj¬¡ü{^.!±Ylš§¡ÏšÀFüÐå¼±Ú²33´Y—ÔAƒŸ[ùRC¹ñ`¾6ۆ̧æú&ÞÊ~5ô÷íúÉWÍì`ý2B'_ÿpbù¿ì ì¡Wé]8ÿ…¶Ç9pJÇ#p/ýco¿ Ô¾ÜS×.CëᤇkÝHmÖzêõŸuÐX½~ŽC…§[œÌ}ó¾kÞ~tÆ’éVãsÊDKmäT~Øtsý†…ÏnL÷¥ùÐM€ŸÚ²¬ýRÖ6ö›?*‹ÙµŽ$¥ Û–c "ïkuŸ·wËßµ¾r›˜‡íѨ?oSò:Ìëæ·ë¥Ù­ÌÅn»_n÷?Ÿï19U&I«Ñ•Umýnýø0¿]î¿-æksf΃ä'²îeü¸Úý?<Îßç÷˱ãâòjvY+-x±ØIš.:ÎLÓÖr®N‰§ÓÚI: i&(-PÚC鄤…¡´ƒÒI«…Ò¥B–²t¥+–L”ø•ïË4´g(í tDÒÁBi…ÒIG‚Ò¥!ËY&È2A– ±B,…K!ÄR,b)±‹XŠE,…KaÄR²ÈR K,²TÈR!K…,dé KYzÈÒC–² e€,d ËYFÈ2B– ²LeB,•K%ÄR ±TB,Õ"–jKµˆ¥2b©ŒX*C–Y d)¥@– Y*d©¥ËïÑœ(¿U[àES¶ê)¥èt:EþÑ0kþã)èQ endstream endobj 1847 0 obj [ 1846 0 R 1848 0 R ] endobj 1844 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1847 0 R /Contents 1849 0 R >> endobj 1850 0 obj 620 endobj 1852 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 709.5 233.88 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 781 0 R /H /I >> endobj 1854 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 709.5 402.21 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 707 0 R /H /I >> endobj 1855 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 697.5 205.55 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 792 0 R /H /I >> endobj 1856 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 697.5 412.76 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 286 0 R /H /I >> endobj 1857 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 685.5 187.23 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1380 0 R /H /I >> endobj 1858 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 685.5 461.64 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 340 0 R /H /I >> endobj 1859 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 673.5 203.33 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 264 0 R /H /I >> endobj 1860 0 obj << /Type /Annot /Subtype /Link /Rect [ 330.0 673.5 429.98 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1861 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 661.5 187.21 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 742 0 R /H /I >> endobj 1862 0 obj << /Length 1863 0 R /Filter /FlateDecode >> stream xœÅUßo‚0~ï_qÛ¬´ ðX7âÔÖéb|`þ\¦N—%ÛŸ¿Bq‚Z\â ä.w½»ï®_ÃY€åk$Âõ Œ–h“Ù,p ÐJfr*@l“8°„Lw`!wå²Õ¤P›¤2‡Z! ·h0”Î1`ð‰ð~º4˜£v®~âÁ¯a†ªÝ4°0ˆénDÔ7=Ëö}¯BÁ3)ñ“‡€XÂàŠ-Öóøyòñ2Š®Æ“¯ë!ˆû\°kÚŽƒ±åQ x/zúöëxôÏ&P‹x;RÁ(̃ZäæÑN1¤=¤,!r¹fJ•‚ñqÑ“£Ñ}g•ŸmRe“U;q-²sϤ¢TÕ’Ú>ð® œï¢È«‹×SÊM-lz:jk pá©dñmO1Rß!>¸*QÈ…Á„è„Õ® ñÔ øÑv‰sFöÇ0èA_ÖàFëhZ‰Ù"­Ç[>s/wF Ve<ЖW÷Àµˆq~mù´ mÐ`ÝHüŠZý=J£Þ¦Õã.Ÿ8Å-:¬ÉYM„Md¹Î6ëAÿ`•V]¨oI¥s endstream endobj 1853 0 obj [ 1852 0 R 1854 0 R 1855 0 R 1856 0 R 1857 0 R 1858 0 R 1859 0 R 1860 0 R 1861 0 R ] endobj 1851 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1853 0 R /Contents 1862 0 R >> endobj 1863 0 obj 421 endobj 1865 0 obj << /Length 1866 0 R /Filter /FlateDecode >> stream xœÅÙrÛ6ð]_¦±3ޤߜ4‡;™6±Ôétª>@$dqL4(ê×wq DRÎS*Ú]{a±»ÀÓÌB~æâ+ˆlïgOšf¡ÀFޝIž,ÛÚ# {(³z€ÝBð¥&°CÎòAfÿƒ "°à0#çìäâåìKO¾!?\~_Dzÿ „rW侨ð`¹9'žKNGz×Ñ U t (J¶Ê´§õ·RDÊõ=i1fq?j œp‚foV³Å{Y­¶&αÐ"8´#ñ±Ñjþ¾²ïú´úuön5€ìµÁF Ù=²]JåOÌ"ȶ°„ßW6ÝË“ôºÅèZÓ ­zCãÇ9+e®dHpçü”›çc—8 Åq·ü€Þ~Z~ù„¶),G4OPÆ)@[^²ô!GYº)i™²ŽõÀ÷nˆB‚ýø†–¥ø¾ç%ºFs×Áºªøž,i•î(õ±`•A•>º£½±šXèi0ö­feN3Ci-0 Ò´ÒjÇúšÐ²‡4UC³ìسƒÑ2Þ±äD„AÒ\¹¨ï˜È>sL½“"‚]`Xƒ¿i™JÆcZ§<¯ éd/X ò‡“cU³½Á›ŠõVošÚ GÞ$¦yOË2ƒµ[íŸoµc˜„!±ì`hšÜ·É(q\XQdEîpmOÞ÷4Xš÷Ç8ø¥4h’–,®¹ Ôþ.XÄ=“§bÊw°…®Úv…mŽn*íi…êPȶÉc±S†Òš›nùö¼ˆ/pGt‘~»ùüÇòãüÓÝ›ûÛû¿æŸoW§=I`F5Í(¤‚sh–òUÖ£ìižMÖEÖˆ½UÁâ”f#εü3 ¾Â)£›L,¶,^ðLhc/² 7ÂG9æÕûßïßÝ}ø­sÎòÝíýÛÒGËW“^²£Pò¶ˆ7ÂwºÝm_wpEQÖëd†¤CUN<öñâ W¼#äŒ%,ñ•‚"®Š©ˆÈ ŸyU?”Ld½ª) ^Ö(­L 4Í‘P¥ p:åMÛ#ØåϼQ ^Ô‹-ç‹ ‘ý Ô˶­¢RH‰ö4Þ¥9ÈËA™TIØì[Ø\]HŠÏú*Ϊ§ì¦hªÝ\;s^Ðz‡^tJ¾X_ø/pÎyÉÏ¥ÚùÛ‘v@9–k6L”جÐRUDE}Ø…¼€dðÍ?ÿ¾\}¸§ ’ ïyÒd kl}õ¯Ù`m]Ò43L«ŒV; Ó ÿÊ~Z_kôn«•št yÝòáˆù~:Ä&þ™qõbç‚/·¨^´©ùvŒZKùÖuô5¥èvùË{DQÍâ]ž>5 †™ º-Ï2~‹¼|¬n.í³íDØr`sœ 4{³¾JØvÏêO­’í 0ðþÝÐ-l__q5"ô›óBøfh§g0îqì)ƒÿR„hræº`¾”1¸¾V?#"EÞs¬( =§/r-S?tRüö.0Ìs íÎËŸ‡Ñ=*%ðF¥L$%ÐîÑÖ3a„q\füsqrØFyDрǥ£SqD‚(Œt0Þ&I*Фè£Dfµmhº¯ª´fsYO¶–-5Ía*ÍÒ©.«Š¬ÚoX&<7H[§Ö[0Ás›ª#¬0y¨Ž°™Ô!ÓOì¡Ù VÇ ¹7ó¡SÇ:-”ÄYZ“®µ„óe¢4Û®h|Óª®^·¨<ÿÖ&Høª.GÀ›ŽZ2ÕC XÈŽM7g²´=»ªCý.·ƒ6”~7„¥®<“¶É̤aÓç Ì)ÒKp‹®&ì×í®y^Ó±nÝ|_‘©*i¸b5: [q á¾¹V´ðïhgrÚ[.Ü8=q“³†‚žqV –Bûâ9Þp-‚ K›¬F_iÖÀíæ™; Ì`ÀY¨ëºé?ÌRhôíPlíÙjZ„šÙ0ð´øOßsA„z#¬}7_©ƒô磞†¶ÑwZC)ÙS]Pe(õsLÞ0ÎR&+«ÆM§ ëéSî8p¿<éC[Úþoº± ÂKë×ר¨qâ˜ö>h(|Û7?¹í¸PˆúiSÅ3ƒ>< Ôñ,›[EA ¿*”OE&«ø\Vhø¯^wS»4Þu˜EÃ_¶0 œö®bׇ k¹#Ú/šª\€ ‹gÝìBÀ_`„;UL]q´§ë¶}Aºó´E Ì’T‡ª‡=+ÍU}R¸zdPpßýТܝàs÷·'Mº_Miݯ°žûÊ®¯^̳¸<õ‹Ž&(Pûñwœû ‚« ùšè+ÔÝIm½tø=bC“*·Ú®ýËWHs¢"¸v'DõoêùŸ~è۠¹qÖX/ã¹ÁÏ‹­ŒçÃ!% y¤;ð¤|p)§—iÚ,…‘8·ÝÛ–xÒOhSÓÅïÆ(üé[>\Ç,W¿¾åyÎÔÄRW¥“­pħ{ÆÆ‡~ƆsBàx(6Ë#TÃoâVw e™ë=~™ýÖØÏ^ endstream endobj 1864 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1865 0 R >> endobj 1866 0 obj 1932 endobj 1868 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 720.0 null] >> endobj 1869 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 73.5 159.44 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1868 0 R /H /I >> endobj 1871 0 obj << /Length 1872 0 R /Filter /FlateDecode >> stream xœÅWßoœ8~ç¯ðcÓÔƒ”VJêN½k“¬Ô‡¶œ`Šaw+õ¯Y6»°»ƒ:}H“• ¶çóÌ|ÃÌø›Ãµÿn?ÈØ'ié|ÛÎ1"}„Û)Æ=_’lŸ)ú]£ÿáÉÃ&ûpO>9•CÉ;çóW»˜jV=„Û_;—£óûúèçSrç¼\8ÏÞ Â(YÜî]Ä{ÑÈ ü¸ÿóÉ¢$ŸŸ\_¾w?||su±øpuö•,þqÞ,&VÌÿV\ntب½áÖ·?émž,N§+#òwóûÙÍÁ0gg†³û¥bËÖv{†´ƒîÍ c+¦Ñð¨‡Ã ;ãE“8>Èþ#»ìˆÅ)…<Âqg^|h= òJ·'­³XÌÇ‚uU®+ÎçX¸¼jUcT j8ä0 d™Wàì §Ö©ªAõB4ºÉTãÞ|‡%š’ª+ -B3ò‚ŠÑLü†EÓð a4.ˆ _äÿ+Ž£½ŸTˆ&Ðè Ñ äàgÏ"4¦»1-¬]ŒæáÇ0)Q4 ÏA,†æàÄòѼ€/š°‘íýs,D{ÿ6S¢ÝŸê®³·¡)(“5Xª(š„þ¨|mN–w ¾4›®ÑðUù¶«Òv¦uð•ùFµ+¥`D|mÎrÓæÕL3òÅy Öæ_œM¡[w™Xs|™îŒjTµ!ÎÜ¢l å‹ @ ¹;CVª(ˆÛ{Ej£ºL»ºVMÒê† À'Ta’y"¢”²(8; ™Êø,ž“÷Á‰î<<Ø´° ßê¢Ð«¼º#:’4ÖF/óLe½aJ„ÇJPOr«„àñ üWïí¶ÀÞJ¥8!FÔºU•±Ö[Ÿê[_é²Ô•E#ÿövlMÛ[÷ìÿzr¬ÒŒv.l(éÖ‹pï`ðмÌaÝbÁºktWÏ4Ý‚J Ü}²œ±S0 özæÎµð"@Ñ Ö6‰÷ÁQtõ\+Š„Ö*D¹ÿ9Øm‰r½ý¬@¤åõT'…2)R”ß—¹Z¹i‘˜±ËÀŒ¾ØîƒIòÿéV‘3âÌcÄš™´û7£ËÑš¾ïSf¼´K†»©>+î^làŽP»ºÖMk“ånêæûHЖèÌýËÕë—ÿ^ÿ2&˜’9ååaKûY;g>%óÀ IihËó±ðþø/OŒš8Y×›óù‹ºVU–¯öFÒã}ñí•ñXÈV¨†dªMòÂ|9óF1qéüßÙ´v endstream endobj 1870 0 obj [ 1869 0 R ] endobj 1867 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1870 0 R /Contents 1871 0 R >> endobj 1872 0 obj 967 endobj 1874 0 obj << /Length 1875 0 R /Filter /FlateDecode >> stream xœÅXÝoÛ6÷_Á§5b…E}ô±Ù2tè†q±‡¦²DÇBeÉå¤Ù_¿ã‡DI”줺´€ïN¼»ß‘Çã‘ aø·?aì¡t·xÔ2…"ѹ¾ãQ´C𦍣z„×Rð£±E/ÊF¿/¾|… ð¼ÀcsRùnqÛó/¾àŸî£‡Å‡Õâòš"£ÕÆL âÆðÄ(rˆ'H˜³Õ}9û5i’uÂú¤ß–¬ÌøùW´úcñÛjq½ÿ!¤[‰AÆ Úƒÿ¡#W{ðúxø¥— ÜH¥C¢d Q¾Å§B/þU@©âQ¿³q`îG1LŸê|>+B¡èb'äƒG‚ÙøÉ³f-¤ðÝÅãñ#‘ÜTæy ‚AâïþLty #È·t¶oZˇ‹'œÌ›w]Û~¶ž·îo²N}›ýÀ¶¿O8®êlÖ‡¼åã—jßäU™G¼y¡ n_ÕókAð„§yûÛö,>ïb*§Ž¸ ör7Í˼ùОàûs5¼ŸÖvH€á/p»¼n±+ýYŒ|߉ƒ0Ž#ª‹<ãiË`QµAiU–,Ü’ïYÚš²*¸'Æ`)t‰2u]Õè-‰ï„èŒ=±úŰû¤Nv¬a½yièfË 3Âpa¾”yÑ×Ïò4iï›Iš£7°wjvwûÉÈ2¶IEOƒ•Oy]•;Vö„OI/홣QøÉºPXDáDg÷gœ1Ãý+YV¥á+±ÞŸ›ÏyQnÝ3›8»0¬šqEçC7PªzZIÝ7QrÖ\ôÇö>¦ÕnŸ,[ªÕÑ8Õ<õ‚«¾˜=;1ÍÎJ‹\Ìk‘¯ëRC`Ñ8ó›츮ëPˆCȵ‹°•–.ìd[宩óòA®¨çÄè¬fûšq3¶é"᥄Œ5Ü’þxcè$ËÀŸ±3J;)ƒ:üÄê>žg¬g¡*Ã|æl`{4×2bŒ"f»}#v´w°B¼_±MÕ‘íêIG™]8¥XTiRˆIê$O¹Ñý\æß—¿V»$7ʼJ¿1™C­kÞ°$ëx™RŠ\]Ý\N…I(„B­ƒ³Y†ùñæDöÐÀñ0QÐñ;;–‚ÎAʈ–ɘµ2Ì•àõÃtéIòÐ0p"êÇ1 ‰}ZOCµTæ  S / m —“|‚1©,>'ÐÅ¡C1ÝMõÓÇZ³øJV¦õ˾aj-ÿ(TÏ—ж5ŠìFa§­2T˜êƒb¹;”zΛ­ÖÛó*N@&‘ac7¦“½Ç4jKk õæP¢ÕàEÂ*Ëý@¥±ãS †V3 ÓÒèŠqäA“?®ÅJ¨J¨¦e!S´¬ÁŠÜÀ)eÆTyàF¼éÏØúððÐw²ƒª<Ⱥ«‡×Õn ˆ+Ñh¶ Õ‚«d}˜;ê·¼(€¢ iŒõ6ý«‚žåXcE0ÌYäC‹Fh«R²ž/húBŒ;Ôiìé™îÁ¾“Å÷4Z7?×`¹°.±ŸäqŸ@Ã*Ç~¤}¯tSáB:î}¤L!2üZ¿1IÉXÆ Ûúìk…gö¯¤¬f‘{ÞQMã;IS}Ä+^æ[KŸŠôʺêxÝ ] ÏË´g/ï ÖÕf¢õ1AoûbJr?¯á*^:,U-£Pô¿uÝŠb\í![wX9ß²¬“À†*XÓK±¸jmõкjª´*.: ¸àªÕP¼ç`§cVÛœOD I<ŒšÁ¬Ú¨P¨‰#)ŠD÷0Zš¨SÌ.ù6Ðh ½¯8Ï×3µêŠÎ»½á®þüÜc>õ ît…Ñ<ô 4EmߩǷݡ¯È §§ñbb.¼xœàIöÙ€Zëqô¼ÍÓ-œÈt}ýްŒ½¢ŠùйPÅ\ê¶­W™7yRäÿÈé=Vü°A9‹]__d¡¥½ø‚…|ãê`îÏžmÞW{V‹fõäŠ*É–Õ½K þX,÷*u©ZÍ©ë2…N9 H†˜ŽîìSÐ)Ü–‰x£íõZæ€çªXv¯ŠQAуM¤D]µSl[ìœN²êéwídgüeou¨ý¯@æ–"ß‹é›(-p­ÍÀ`Ž_‘:4"£ÓìÊÜ,îà~ŸotuôÝ"€Ë¦Œi¤³èîöÒ÷#S¹ˆ iô ¶ÖɧÀ GÇm…Ïoó@¼ …“O‚oóLùxÕ³à„Ÿ×> Nx<õ4ø¦¨Äã ­ðšçÁ·¹¡S)pê‰ÐÖh«ž|£¿]ü 7Ïi endstream endobj 1873 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 1874 0 R >> endobj 1875 0 obj 1763 endobj 1877 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 709.5 243.98 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1879 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.832 709.5 541.832 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 1880 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 697.5 353.781 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1448 0 R /H /I >> endobj 1881 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.0 697.5 541.0 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1448 0 R /H /I >> endobj 1882 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 685.5 255.66 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1359 0 R /H /I >> endobj 1883 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.75 685.5 541.75 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1359 0 R /H /I >> endobj 1884 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 673.5 282.31 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1885 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.566 673.5 541.566 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1331 0 R /H /I >> endobj 1886 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 661.5 278.44 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1887 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.59 661.5 541.59 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 1888 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 649.5 226.77 658.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1889 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.949 649.5 541.949 658.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 1890 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 637.5 266.22 646.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1891 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.674 637.5 541.674 646.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1350 0 R /H /I >> endobj 1892 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 625.5 211.23 634.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1380 0 R /H /I >> endobj 1893 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.058 625.5 542.058 634.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1380 0 R /H /I >> endobj 1894 0 obj << /Type /Action /S /GoTo /D [1447 0 R /XYZ 72.0 720.0 null] >> endobj 1895 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 613.5 371.22 622.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1894 0 R /H /I >> endobj 1896 0 obj << /Type /Annot /Subtype /Link /Rect [ 525.886 613.5 540.886 622.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1894 0 R /H /I >> endobj 1897 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 601.5 228.99 610.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1463 0 R /H /I >> endobj 1898 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.936 601.5 541.936 610.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1463 0 R /H /I >> endobj 1899 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 589.5 248.43 598.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1466 0 R /H /I >> endobj 1900 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.798 589.5 541.798 598.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1466 0 R /H /I >> endobj 1901 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 577.5 337.31 586.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1902 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.184 577.5 541.184 586.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1469 0 R /H /I >> endobj 1903 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 565.5 254.0 574.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1403 0 R /H /I >> endobj 1904 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.76 565.5 541.76 574.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1403 0 R /H /I >> endobj 1905 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 553.5 283.99 562.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1461 0 R /H /I >> endobj 1906 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.554 553.5 541.554 562.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1461 0 R /H /I >> endobj 1907 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 541.5 317.33 550.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1908 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.322 541.5 541.322 550.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 1909 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 529.5 287.33 538.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1910 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.529 529.5 541.529 538.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 1911 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 517.5 292.89 526.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1912 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.492 517.5 541.492 526.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 1913 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 505.5 317.33 514.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1914 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.322 505.5 541.322 514.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1455 0 R /H /I >> endobj 1915 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 493.5 287.33 502.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1916 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.529 493.5 541.529 502.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1452 0 R /H /I >> endobj 1917 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 481.5 259.55 490.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1918 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.723 481.5 541.723 490.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1486 0 R /H /I >> endobj 1919 0 obj << /Type /Action /S /GoTo /D [1533 0 R /XYZ 72.0 720.0 null] >> endobj 1920 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 469.5 223.863 478.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1919 0 R /H /I >> endobj 1921 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.846 469.5 541.846 478.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1919 0 R /H /I >> endobj 1922 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 457.5 259.55 466.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1923 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.723 457.5 541.723 466.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 1924 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 445.5 252.33 454.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1925 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.773 445.5 541.773 454.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 1926 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 433.5 233.44 442.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1927 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.903 433.5 541.903 442.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1522 0 R /H /I >> endobj 1928 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 421.5 206.78 430.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1929 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.09 421.5 542.09 430.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1541 0 R /H /I >> endobj 1930 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 409.5 231.77 418.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1931 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.916 409.5 541.916 418.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 1932 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 397.5 247.88 406.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1933 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.803 397.5 541.803 406.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 1934 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 385.5 236.78 394.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1935 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.881 385.5 541.881 394.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1550 0 R /H /I >> endobj 1936 0 obj << /Type /Action /S /GoTo /D [1707 0 R /XYZ 72.0 720.0 null] >> endobj 1937 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 373.5 244.254 382.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1936 0 R /H /I >> endobj 1938 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.712 373.5 541.712 382.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1936 0 R /H /I >> endobj 1939 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 361.5 308.97 370.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1711 0 R /H /I >> endobj 1940 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.379 361.5 541.379 370.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1711 0 R /H /I >> endobj 1941 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 349.5 221.76 358.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1942 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.986 349.5 541.986 358.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1602 0 R /H /I >> endobj 1943 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 337.5 199.56 346.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1944 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.139 337.5 542.139 346.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1608 0 R /H /I >> endobj 1945 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 325.5 214.54 334.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1946 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.035 325.5 542.035 334.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1615 0 R /H /I >> endobj 1947 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 313.5 271.2 322.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1622 0 R /H /I >> endobj 1948 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.642 313.5 541.642 322.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1622 0 R /H /I >> endobj 1949 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 301.5 228.45 310.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1950 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.94 301.5 541.94 310.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1636 0 R /H /I >> endobj 1951 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 289.5 256.22 298.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1952 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.745 289.5 541.745 298.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1661 0 R /H /I >> endobj 1953 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 277.5 267.88 286.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1954 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.666 277.5 541.666 286.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1669 0 R /H /I >> endobj 1955 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 265.5 287.32 274.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1728 0 R /H /I >> endobj 1956 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.53 265.5 541.53 274.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1728 0 R /H /I >> endobj 1957 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 253.5 264.56 262.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1731 0 R /H /I >> endobj 1958 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.687 253.5 541.687 262.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1731 0 R /H /I >> endobj 1959 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 241.5 247.88 250.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1734 0 R /H /I >> endobj 1960 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.803 241.5 541.803 250.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1734 0 R /H /I >> endobj 1961 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 229.5 235.11 238.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1737 0 R /H /I >> endobj 1962 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.894 229.5 541.894 238.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1737 0 R /H /I >> endobj 1963 0 obj << /Type /Action /S /GoTo /D [1844 0 R /XYZ 72.0 720.0 null] >> endobj 1964 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 217.5 156.134 226.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1963 0 R /H /I >> endobj 1965 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.286 217.5 542.286 226.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1963 0 R /H /I >> endobj 1966 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 205.5 306.754 214.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1845 0 R /H /I >> endobj 1967 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.392 205.5 541.392 214.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1845 0 R /H /I >> endobj 1968 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 193.5 215.483 202.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1868 0 R /H /I >> endobj 1969 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.9 193.5 541.9 202.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1868 0 R /H /I >> endobj 1970 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 690.141 null] >> endobj 1971 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 181.5 330.997 190.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1970 0 R /H /I >> endobj 1972 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.224 181.5 541.224 190.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1970 0 R /H /I >> endobj 1973 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 372.422 null] >> endobj 1974 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 169.5 192.89 178.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1973 0 R /H /I >> endobj 1975 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.186 169.5 542.186 178.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1973 0 R /H /I >> endobj 1976 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 338.733 null] >> endobj 1977 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 157.5 204.1 166.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1976 0 R /H /I >> endobj 1978 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 157.5 542.259 166.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1976 0 R /H /I >> endobj 1979 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 264.385 null] >> endobj 1980 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 145.5 219.11 154.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1979 0 R /H /I >> endobj 1981 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 145.5 542.147 154.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1979 0 R /H /I >> endobj 1982 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 148.425 null] >> endobj 1983 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 133.5 270.264 142.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1982 0 R /H /I >> endobj 1984 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 133.5 541.766 142.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1982 0 R /H /I >> endobj 1985 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 456.879 null] >> endobj 1986 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 121.5 191.33 130.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1985 0 R /H /I >> endobj 1987 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 121.5 542.353 130.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1985 0 R /H /I >> endobj 1988 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 406.845 null] >> endobj 1989 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 109.5 223.597 118.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1988 0 R /H /I >> endobj 1990 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.972 109.5 541.972 118.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1988 0 R /H /I >> endobj 1991 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 373.313 null] >> endobj 1992 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 97.5 204.1 106.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1991 0 R /H /I >> endobj 1993 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 97.5 542.259 106.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1991 0 R /H /I >> endobj 1994 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 287.279 null] >> endobj 1995 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 85.5 219.11 94.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1994 0 R /H /I >> endobj 1996 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 85.5 542.147 94.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1994 0 R /H /I >> endobj 1997 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 159.947 null] >> endobj 1998 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 73.5 270.264 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1997 0 R /H /I >> endobj 1999 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 73.5 541.766 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1997 0 R /H /I >> endobj 2000 0 obj << /Length 2001 0 R /Filter /FlateDecode >> stream xœÅÝ]“ו˜é{þ ܺ#PÎ̵ö×%D@z @ u;l_°%HÆXM¶%öxf~ýäΈ:u’æy=mGHß,ô€ÄÙ;w®üï_­O–ýÿ=ÿÑÆöäÿòÕÿôcë“¶=‰úé‡J}²æÝVžüË“Oÿ½<ùˬü—íóÛÿã>ÚÿË}ò_}ûÕòä—_ý§ÿ²ÿÍ?>Yö þÇWËã/w\üî«ß>øùçßYþÝþåÉŸ¿úùû¯þÃ/ö^ž¼ÿÓ—ÿ‰¢Ü±,ËZû“~Û˜ÿ·=yÿ/OþÓϾ~õî·¯þî¿üéã·¿ÿøÝ·_~ìÕ7ßþùß¾ùó‡/?òŸöæÍóç¯þóß]}â\ïZ_—¥ôzý}¹þê²Ü/Û–uy}ÙõÇÚ&õX¨ª+ÕêX6ª Õ]êu¥Z,cËýŸ ªÅ26±Üÿ®ÔA–A–A–I–I–I–…, Y²,dYɲ’e%ËF–,Yv²ìdÙɲ“å ËA–C,sË\Ä2±ÌU,sË\Å2W±ÌM,sËÜÈ2È2È2È2É2É2Érÿ·ý}ÿû{qûÃýÓðu½Öö(›ÇöÏü1ïˆ÷¸¯Þ½öúù³·ÏŸ>ÿùÓ7?ÿ‡_¿tÑ^ÞÕº_µ^_>¿¥ýsf¹¾¸ÿè²ÿáu~Ùã_÷¼Ÿ&uP]©PÏ{jRª»Ôû§O©“j±œwÖ¤ËyoMj² ² ² ²L²L²L²,dYȲe!ËJ–•,+Y6²ldÙȲ“e'ËN–,Y²b9oºI-–ó¶Ô«XÎoR‹å¼õõ&–óæ›Ôdddd™d™d™d™dYȲe!ËJ–•,+Y6²ldÙȲ‘e'ËN–,Y²b9ïÊI-–ó¾œÔb9ïÌI-–óÞÔ›XλsR“eeeee’e’e’eYï¢Ø˜·èÎ.Xk¿Þ—˜§/ª¿þâÏ~÷êýÓwïß¾|ý˧¯^¼þåû_ýýÕÊt¹‹eŒÑJ½þó[›‡‹¯o¤íˆÊØÛ}Íw}Ùõò·R=¤Þ?I]¨îRNª›Ôû"©É2É2ɲe!Ë2-÷åJ[N~£_/QWª“ê&u[¨ª+ÕCê¾Q]¨&ËA–ƒ,‡Xî“j±ŒE,÷åK½Še¬b«XÆ&–±‰elddddd™d™d™dYȲe!ËJ–•,+YV²ldÙȲ‘e'ËN–,Y²d9Ä2±ÌE,sË\Å2W±ÌU,sËÜÄ27±Ì,ƒ,ƒ,ƒ,“,“,“,÷ÛïŸ GÖ™s \æÍóQN>ã¯u\/„ç£gÕ×o_<{ÿâéï_¾øÇ§¿xûæ×O¿~õìÝ»ÇäöO™ûe[æõ—8¾¿qrŠvÛ?Gµ(c싨ëË®W¶Õ…ê.õþ9JꤺI½Ž’:¨®T“e’e’e’e!ËB–…,+YV²¬dYɲ‘e#ËF–,;Yv²d9ÈråËã8;Ôbyg¿½^Åò8εXÇÙ¡Ëã8;Ôdddd™d™d™dYȲe!ËB–•,+YV²ldÙȲ‘e'ËN–,;Y²d9Äò8εXÇÙo¯W±<޳C-–ÇqöÛëM,ãìP“eeee’e’e’å\5}]Z£À²ôX6÷1F“ÕìÚ–ëeóœ~rQ=ñ‹û5óÙry«ˆ¶ç¹µëK‡NOÏ´—~·/°Ç(ëÉÏøø¿Ö•ꤺIݪƒêJõºoTªÉrå Ë!–Û"–Û"–sIj±œ›GR‹åÜ<‚z˹y$5YYYYY&Y&Y&Y²,dYȲ’e%ËJ–•,Y6²ldÙɲ“e'ËA–ƒ,Y±œ›GR‹åÜ<‚z˹y$µXÎÍ#©ÅrnIM–A–A–A–I–I–I–…, Y²,dYɲ’e%ËF–,Yv²ìdÙɲ“å ËA–C,çæ‘Ôb97 ^ÅrnI-–sóêM,çæ‘Ôdddd™d™d™d9ƒµc,'õnÒÌÍ£‘cYÊ×—­m»Þ<šch/7Þ¾ùÍOœ¸8Öøsþغ|㡈¸ë×[Hó{.mŒ>ß0ðø²³Å¾ÔAu¥zH=OÜB]¨îRÏ·P'Õddddd™d™d™dYȲå|WÞ§¿~ð®¼ûùü®¼û¿úõ7ß~ü×ûË7Ÿß–wÿ£ß–wÿ#ÇÛò~}ò¶¼yúóQ›ëoî˸úŒ¶Ý­uÿ÷šõäºëtÅòNù¾à§<-o”ïk~ÊÃòjù ü|àú˃«/2¿Ç9óõúÞå|½y­côí캳õ±äóç’§åòùŽsÉÃòjù |¾ç\rSMS-¦ZLµ˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¤z¼û\rR=Þ~ùJªÇûÏ%'Õã è’“êñtÉM5L5L5L5M5M5Mµ˜j1ÕbªÅT«©VS­¦ÚLµ™j3ÕnªÝT»©vS¦:LuêñrtÉIõx=:ä+©/H—œTW¤C¾‘êñ’tÉM5L5L5L5M5M5Mu®Zûtpàö•hoIÞÿá*g—­ãäjó¹èËìÓAßOkäûw¦^9Ÿ¬‘~¸øú+Íïsÿ𽪟‹¥Ë-Ö“ëÎK”§åò9µPò°¼Z>(ŸS %/–›j7ÕnªÝT‡©S¦:Hu.–('Õ¹X’|%Õ¹X¢œTçb‰rR‹%ÊM5L5L5L5M5M5Mµ˜j1ÕbªÅT«©VS­¦ÚLµ™j3ÕnªÝT»©vS¦:Luê\,QNªs±$ùJªs±D9©ÎÅ’ä©ÎÅ妦¦¦š¦š¦š¦ZæÌøuY—–²™‹¥ØÖ±ÿLíäºul'«¥þø1Ê‹ÕÒýbéÝ«7ï¢[.”®¾È± «wåäÖb¿+£,÷/˹ºîêƒã¶Zž–7Êc±<,¯–Ês³¼XnªÅT‹©S­¦ZMµšj5ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªƒTçò—rRË_ÉWRË_ÊIu.)'Õ¹ü¥ÜTÃTÃTÃTÓTÓTÓT‹©S-¦ZLµšj5ÕjªÍT›©6Sí¦ÚMµ›j7ÕaªÃT©Îå/å¤:—¿’¯¤:—¿”“ê\þJ¾‘ê\þRnªaªaªaªiªiªiªÇIÂ\–6g ݾ´<î~zíõeë8™º|<ízËê÷êdíœR¸ÿTcÄ8ù*Ç÷˜wõzù»/P×9z-g×-P%ߨ”‡åÕòAù¾@¥¼XÞ)Ÿ;0’›j™ªŸÞ`wC^ËÃòjù ¼m–Ë;å}µ<-7ÕaªÃT‡©R=Þ\-9©o®†|%ÕãÍÕ’“êñæjÉIõxsµä¦¦¦¦š¦š¦š¦ZLµ˜j1ÕbªÕT«©VSm¦ÚLµ™j7ÕnªÝT»©S¦:Hõxsµä¤z¼¹ò•T7WKNªÇ›«!ßHõxsµä¦¦¦¦š¦š¦š¦:¨¹ÜßÎV?ºöËãç~Až®×q2¾ökt¶@ýáÉÏc‰ú#><Ìzý•n;Ìz}ÝÙb‰ò´¼Qþð0ë-yX^-”?<ÌzK^,7ÕnªÝT»©S¦:LuêÅaÖ[rR½8ÌzC¾’êÅaÖ[rR½8ÌzKNª‡YoÉM5L5L5L5M5M5Mµ˜j1ÕbªÅT«©VS­¦ÚLµ™j3ÕnªÝT»©vS¦:LuêÅaÖ[rR½8ÌzC¾’êÅaÖ[rR½8ÌzC¾‘êÅaÖ[rS S S SMSMSMS}x˜!‡Y¯¯[ÇÉœœc˜êÙjiÞÂ{¸Rzü‰îáaÖë/rÛaÖëë®>8><ÌzKž–7Êf½%Ë«åƒò‡‡YoÉ‹å¦ZLµ˜j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:Hõâ0ë-9©^f½!_Iõâ0ë-9©^f½%'Ջì·ä¦¦¦¦š¦š¦š¦ZLµ˜j1ÕbªÕT«©VSm¦ÚLµ™j7ÕnªÝT»©S¦:Hõâ0ë-9©^f½!_Iõâ0ë-9©^f½!ßHõâ0ë-¹©†©†©†©¦©¦©¦©><Ì Kˇ‡Y¯/Û–“Á7Ç+9ÎV¿Ÿßpùo^¾~|pŸD÷_Ͳð:ù ÇÛzòŽžuÿH:ÖýûØJ=¹îñÿ ëþ‘”òjù|Û?’R^,ï”Ͻ’§åòT·T·T·ÍTÃTÃTÃTÓTÓTÓT‹©S-Su½ÅMõºnTª»Ôm¥:©nR÷…ê š,;Y²d9Är¾•Wj±œïä…zËùF^©År¾êM,çÛx¥&Ë Ë Ë Ë$Ë$Ë$Ë$ËB–…, YV²¬dYɲ‘e#ËF–,;Yv²ìd9ÈråËùÒ]©År¾rWj±œ/Ü•Z,çëv¡ÞÄr¾lWj² ² ² ² ²L²L²œï¡©Ë[žå?º‚?^D³¯±Æ:òäº}‘üø‚~ÿöÌ‹ì÷/_¾¼›?Ç$¿<sC^,ï”_œŠ¹!OËå©^žŠ¹!'ÕËS1?‡©†©†©¦©¦©¦©S-¦úðTÌ õúᩘêBu—úᩘꤺIýðTÌ uPM–,Y²byq*æ†Z,/NÅüt½ŠåÅ©˜j±¼8óÓõ&–§bn¨É2È2È2È2É2É2É2ɲe!ËB–•,+YV²ldÙȲ‘e#ËN–,;Y²d9ÄòâTÌ µX^œŠ¹¡Ë‹S17Ôbyq*æ§ëM,/NÅÜP“eeeee’e’åÅ©˜ÛWð—§b®®ÛW½'; m»Úaxó›ŸØ`x0þïúúãÛë'ïÃÞó»¶Ö1Ê–'×]mì¿FÊåûgWÊ‹å]òmÿøJyZÞ(ß?ÁRNªÛJªÛJªÛFªÛFªÛfªaªaªaªiªiªiªiªÅT‹©–©Ú–un—þt]Wª“ê&u[¨ª+ÕCê¾Q]¨&ËA–ƒ,‡XîšR-–±ˆe,b«XÆ*–±Šelb›XÆF–A–A–A–A–I–I–I–…, Y²¬dYɲ’e%ËF–,Yv²ìdÙÉrå ËA–C,sË\Ä2±ÌU,sË\Å27±ÌM,sËÜÈ2È2È2È2É2É2ÉrîvôÏ/0¸};áØíh±ÿ,ÛÙO³¯zOv;z>Þíx¸Ññô7×ñû§ýÌeY¶Ì“‹£åì,Åþ¹¿uo·qrÝÕvÁþÁ_òý“?åayµ|P¾ú§¼XÞ)ß”›ê ÕùL å¤:Ÿ©¡œTç35”“ê|¦FòTç35”›j˜j˜j˜j˜jšjšjšj1ÕbªÅT«©VS­¦ZMµ™j3ÕfªÝT»©vS¦:Lu˜ê Õùˆ å¤:²‘|%Õù˜ å¤:´¡œTç£6”›j˜j˜j˜jšjšjšj1ÕbªÅT‹©VS­¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê Õù å¤:ŸÂ‘|%Õùå¤:ŸÄ‘|#Õù,妦¦¦š¦š¦š¦:ŸÉ)Ëè½5Ù¨™›Hc‰e-ëÙϾ >ÙDÚ?È]o"½{ÿöų_?Þ˜÷ôÛØÛÖO®›ßÖ:§D_o í4Ç–cÔQN.¼ÚjØÿh¦<-o”—Åò°¼Z>(¯›åÅrSm¦ÚLµ™j7ÕnªÝT»©S¦:Huö¢œTça/ÉWR‡½('ÕyØKòTça/ÊM5L5L5L5M5M5M5Mµ˜j1Õ2UË€¿Þ’×Õò´¼QÞËÃòjù ¼o–ËMu˜ê0ÕAªóèå¤:QNªóøå¤:€I¾‘ê<F¹©†©†©†©†©¦©¦©¦©S-¦ZLµšj5ÕjªÕT›©6Sm¦ÚMµ›j7ÕaªÃT‡©R‡Ã('Õyxzïúêã›Ë»õä@ÏÜ_Zƈ%O®»Úo8î±Bž–7Ê{¬‡åÕòAùqòb9©n ©n ©n ©n+©n+©n+©n+©n©n©n›©†©†©†©¦©¦©¦©¦©S-¦zÜc]W-ÞP·Xo¯“ê&õqõö:¨®T©{«·×…j²d9Èrˆe,b‹XÆ"–±ˆe¬b«XÆ*–±‰elbYYYYY&Y&Y&Y²,dYȲ’e%ËJ–•,Y6²ldÙɲ“e'ËA–ƒ,Y±ÌE,sË\Ä2W±ÌU,sËÜÄ27±ÌM,s#Ë Ë Ë Ë$Ë$Ë$Ëò`n6ìœÛ:}]ÖuÔ“ë¶õñLïìÇýŠËìå?ÝSÃËœþõ«w¿}õà/¿ûö¿ÿøÝ·_~èÝÿý·ï?üËÕ¶É®ZöªÛÙÏðåâ«ËÊ]]?½ºíúºëÍ™Nùþ/^ÊÓòFùþï^ÊÃòjù|>E9©Îç¡$_Iu>E9©Îç¡('Õù<妦¦¦š¦š¦š¦ZLµ˜j1ÕbªÕT«©VSm¦ÚLµ™j7ÕnªÝT»©S¦:Hu>E9©Îç¡$_Iu>E9©Îç¡$ßHu>E¹©†©†©†©¦©¦©¦©¦©S-¦ZLµšj5ÕjªÍT›©6Sm¦ÚMµ›j7ÕaªÃT©Îç¡('Õù<å¤:Ÿ‡¢œTçóP’o¤:Ÿ‡¢ÜTÃTÃTÃTÃTÓTÓT猵R–y…lvo`[·e)u;¹n[O†gGyž]1Ÿ™øúÍëç/ß¿|óúÑë¾ÆieŒ±'—÷þÇ]\ß:Ÿú•ý#`™‚\]÷øW?ßDù ¼n–Ë;åóÉÓòFù|@DrSí¦ÚMu˜ê0ÕAªÇ"’“êñ€ä+©ˆHNªÇ"o¤z< "¹©†©†©†©¦©¦©¦©¦©S-¦:){²œþùv¶÷EyZÞ(Ÿ‰H–WËåóAÉ‹å¦:Lu˜ê ÕãqÉIõx`DrR=‘œT‡F ßHõxlDrS S S S SMSMSMS-¦ZLµ˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¤zGÝKž–7Êç¨{ÉÃòj¹©†©†©†©¦©¦©¦©S-¦:_£¸îK«­ÝT©çK¡.Tw©ç¡Nª›Ôóõ‰PÕdÙÉrå Ë!–s@j±œ›P¯b9·¤˹õ&–sù/5YYYY&Y&Y&Y&Y²,dYȲ’e%ËJ–,Y6²ldÙɲ“e'ËA–ƒ,‡XÎU¾Ôb9×øR‹å\áK-–s}õ&–su/5YYYYY&Y&Y&YÎ=€ˆei}•%öñÄM-£—õìºmk'{ålhígæ9ݘã$clhqöEæ÷8wL¯GkÌ]«^–¥¶õäºëõåjyZÞ(Ÿ»V’‡åÕòAùܵ’¼XnªÅT‹©–©šc¬YoÉëbyX^-”·Íòby§¼¯–§å¦:Lu˜ê0ÕAªs®$å¤:çJJ¾’êœ+I9©Î¹’”“êœ+I¹©†©†©†©¦©¦©¦©S-¦ZLµ˜j5ÕjªÕT›©6Sm¦ÚMµ›j7ÕnªÃT‡©Rs%)'Õ9WRò•Tç\IÊIuΕ”|#Õ9W’rS S S SMSMSMSÝW[-Ë^YZÎåï|·ôè­Ÿ\·mýdù[ÏÆJ¾ñëß¼yûìíü‘;àÛ—÷?_cyžwyr¼Ü%÷eÌ8»îñÿ Ç Ûóc†€äiy£|Î<,¯–Êç ÉIõ˜!y˜j˜j˜jšjšjšjšj1Õbªs†Àû¿áÚ-õ!uRݤžó ª+ÕCê9;êB5Y²d9Äò˜µX3 ËcbÔbyÌ ¸½ÞÄò˜5YYYYY&Y&Y&Y²,dYȲ’e%ËJ–•,Y6²ldÙɲ“e'ËA–ƒ,Y±dû’ü¸c¾_´®§{Û6N¶ ÚÙŒÊ÷/ýâÍïÞŸo´‡Gæ¯.?&,wÛõ†Á(o›åÅòNy_-OËMu˜ê0ÕaªƒTçq ÊIuÇ|%ÕyƒrRÇ1('ÕyƒrS S S SMSMSMS-¦ZLµ˜j1ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÝT‡©S¤:cPNªó8†ä+©Î㔓ê<Ž!ùFªó8妦¦¦š¦š¦š¦:ç+.ë²,ƒv/æÞJ_b¿l‰“ëöÕÛÉÞJ?›°ø‹g:ßYÙ?ý¯ó[[êzrññ½åÝÉ+@æ©ìÒöËzž\wµÝ0OeC>OeK^,ï”ÏSÙ’§åòy*[ò°ÜT©s*%'ÕcN%ä+©s*%'ÕcN¥ä¤zÌ©”ÜTÃTÃTÃTÓTÓTÓT‹©S-¦ZLµšj5ÕjªÍT›©6Sí¦ÚMµ›j7ÕaªÃT©s*%'ÕcN%ä+©s*%'ÕcN%ä©s*%7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕbªÅT‹©VS­¦ZMµ™j3ÕfªÍT»©vSí¦:Lu˜ê ÕcN¥ä¤zÌ©”œT9•’“ê1§òT9•’›j˜j˜j˜j˜jšjšêÜÊ:Æ2šì¼»B#—uËrrÝëã ú“²<eñOwó'X×ãLÏËoÿøáÿztUÏ»uÿãsÙê8¹üÁůkw­µù ÑÙOûø„±PTWª‡Ôë²Y^,«åi9‰®‘®™®¡®›©†©†©†©¦©¦©¦©S-¦ZLµ˜j5ÕjªÕT›©6Sm¦ÚMµ›j7ÕnªÃT‡©RŽRNªóÑQÉWRŽRNªóÑQÉ7RŽRnªaªaªaªiªiªiªiªÅT‹©–©Ú—µ¬yK^WËÓòFy[,Ë«åƒò¾Y^,7ÕaªÃT©ÎI)'Õù()å¤:&¥œTç㤒o¤:(¥ÜTÃTÃTÃTÃTÓTÓTÓT‹©S-¦ZMµšj5ÕjªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT©æBª¹j.¤š+©æJª¹’jn¤š©æFª¹™j˜j˜j˜jšjšjšêþÇAÍuO6ÛjÎ9¥¿×e]ÚÙϳÅöè‚¶=)ûÇ›9zm˸Ϟýå_ÿë7ÿüáûøæ/óçšÿ þ´%þå/ÿôÝ_¿üÅ¿~ó‡ÿöÍŸ?|ù¯_½ûí«³Õ`ÙÿÑoýä'ýríɪp”uYr‰“ëÎV…”‡åÕòAù($y±¼ïù²/![»%Ÿ…$OËås¨äayµ|P> I^,7ÕaªÃT©ã…$'ÕcÀä¤zŒ’œT!Co¤zŒ’ÜTÃTÃTÃTÃTÓTÓTÓT‹©S-¦ZMµšj5ÕjªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT©ˆ$'Õcä+©Cˆ$'Õc ‘ä¤z "’ÜTÃTÃTÃTÓTÓTÓT÷?Ö½?^ ¨y<*ÆçÕäÕu[Äã öõÙþ áÑ¢ð85ÊÝúägÏ¿ùþ›þæo¾üÈÏ÷àÓßþño¾Ôº/¯²_h=ù¢_¾ÀÕuûï±yت̅ìÕuÿ§Yç: ò¹Î’¼XÞ)Ÿë,ÉÓòFù\gI–›j3ÕnªÝT»©S¦:HuΪ¢œTç¬*ÊIuΪ¢œTç¬*É7R³ª(7Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕbªÅTç:k_†ŽåôÏÕë±Åò°¼Z>(Ÿë,É‹åò¹Î’<-7ÕaªÃT‡©R³ª('Õ9«Jò•Tç¬*ÊIuΪ¢œTç¬*ÊM5L5L5L5M5M5Mµ˜j1ÕbªÅT«©VS­¦ÚLµ™j3ÕnªÝT»©vS¦:LuêœUE9©ÎYU’¯¤:gUQNªsV•ä©ÎYU”›j˜j˜j˜jšjšjšêñTâØ?î¯![X÷O%îÿãä²-Ê£~ÅØ×\—Ù¯¾ûǾÞ:_Í}ªøò—úøíÿöå/¿ùö_þâ/ß}óðïý黿~øøçoüýÿü×oþúñÃãýºãŒÀhË2¶~òí|ùW …ín]Æè%ÊÉu×ëŠby§|ÿs‡ò´¼Q¾ÿ¹CyX^-”S¦:HuG¡œTçpÉWRÃQ('Õ9EòTçpÊM5L5L5L5M5M5M5Mµ˜j1ÕbªÕT«©VSm¦ÚLµ™j3ÕnªÝT»©S¦:HuG¡œTçpÊIuG¡œTçpÉ7RÃQ(7Õ0Õ0Õ0Õ0Õ4Õ4Õ4ÕyX`ö[†|Ÿ«–mÛGc9[œ/[öoí2ûÍwûþÏýp}|ÎÂè?¬Š®®;N¶ïÿ,]_ëþÛîËA‚« ÿò×ý·äûo;ÊÃòjù |ÿmGy±¼S>Ë’›j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:HuÎ{¦œTç¼gÉWRóž)'Õ9ï™rRóž)7Õ0Õ0Õ0Õ4Õ4Õ4ÕbªÅT‹©S­¦ZMµšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕAªsK“rR[𒝤:·4)'Õ¹¥)ùFªsK“rS S S SMSMSMSMS-¦ZLµ˜j5ÕjªÕT›©6Sm¦ÚLµ›j7ÕnªÃT‡©R[š”“êÜÒ¤œTç–&å¤:·4%ßH5mo)mo)mo)mo)mo)mo)mo)mo)moini–ñé…ì²w8§b¬½.KÖ<¹ðzOsì_¿.²W?rdbŽÈýüº°ë«îguœìgÎi&Û£´8¹ìzO°S>§™Hž–7Êç¤\ÉÃòjù |NÊ•ÜT«©6Sm¦ÚLµ›j7ÕnªÝT‡©S¤zLÊ•œTI¹¯¤zLÊ•œTI¹o¤zLÊ•ÜTÃTÃTÃTÓTÓTÓTÓT‹©S“rg±ŒqK>'åJž–7Êç¤\ÉÃòjù |NÊ•¼XnªÃT‡©R…TI¹’“ê1)ò•TI¹’“ê1)WrR=&åB¦¦¦¦š¦š¦š¦ZLµ˜j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:Hõ˜”+9©“r!_Iõ˜”+9©“r%'ÕcR®ä¦¦¦¦š¦š¦š¦:'åný~¦ìÍ›oǘÜ2>½Êíê²ó ÁöxpÒËo?~ÿñ›¿|ü¾ùþãwßžì‘­?l ^]{¿YÙNFøÎݲÚ?O—¸ºðl·Œòjù ¼n–Ë;åmµ<-o”wSí¦ÚMµ›ê0ÕaªƒTçnå¤:wË$_Iuî–QNªs·LòTçn妦¦¦š¦š¦š¦š¦ZLµ˜j™ªŸŸœþé¼®–§åò¶X–WËå}³¼XnªÃT‡©RÝÿ¦å¤:wË('Õ¹[F9©ÎÝ2É7R»e”›j˜j˜j˜j˜jšjšjšj1ÕbªÅT«©VS­¦ZMµ™j3ÕfªÝT»©vS¦:Lu˜ê Õ¹[F9©ÎÝ2ÉWR»e”“êÜ-£œTçn妦¦¦š¦š¦š¦:OÐÍ»ã})´)uœ Ë¶,±¶“ Ï7Ìúã™G_÷í·þ07ËæÏ4ê>ùÙ»ýð‡úø‡Ó=´ÑïöEÁ²´ÒN¾Ü—/r¶GmŒrrÕéÁíqƒxî܇ÄUâñܸ=.wˆCCCSSSS‹œ«ÿì˺l7åsõ/yZÞ(Ÿ«ÉÃòjù |®þ%/–›ê0ÕaªƒTÕ¿ä¤z¬þ%'Õcõ/9©«È7R=Vÿ’›j˜j˜j˜j˜jšjšjšj1ÕbªÅT«©VS­¦ZMµ™j3ÕfªÝT»©vS¦:Lu˜ê Õcõ/9©«ÈWR=Vÿ’“ê±ú—œTտ䦦¦¦š¦š¦š¦ºÿq°ÿËcô^B–Ós$X«eŒu[O®;_üÇ“Ã^÷ýõ£sûÒtVËÚãä’ûã;íä•fëþ;nYæ~Ä<÷suáã_ùºÿŽ£|P¾ÿŽ£¼XÞ)ßÇQž–7ÊËb¹©S-¦ZMµšj5ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªƒTç>%å¤:÷*%_IuîWRNªsÏRòTç¾%妦¦¦š¦š¦š¦š¦ZLµ˜j™ªõÓ§¡ŸÎëjyZÞ(o‹åayµ|PÞ7Ë‹å¦:Lu˜ê Õ¹›I9©ÎÝLÊIuîfRNªs7SòTçn&妦¦¦¦š¦š¦š¦ZLµ˜j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:HuîfRNªs7Sò•Tçn&å¤:w3)'ÕÜH57S S S SMSMSMS7·Z#{£½Ãy–)Ê6F=ÝtÜ¢>º mOêòão88^×çOôî»?ü·ß_m;Í©emnrž}/W_]·SΣ]£ÆÉu×»[ò¹œ‘<-o”ÏåŒäayµ|P>—3’›j7ÕaªÃT©n ©n ©n ©n ©n+©n+©n+©n©n©n›©†©†©†©†©¦©¦©¦©S-¦:—3=—5û¸%ŸËÉÃòjù |.g$/–wÊçrFò´ÜT‡©S¦:H5R…Tc!ÕXI5VR•Tc#ÕØH56RÍTÃTÃTÃTÓTÓTÓT‹©S-¦ZLµšj5ÕjªÍT›©6Sí¦ÚMµ›j7ÕaªÃT©æBª¹j.¤š+©æJª¹’j®¤š©æFª¹™j˜j˜j˜jšjšjšêñżÛ'ìͳz£­£g¯'×]on=ÛþWFÝ__uÓ¨ûëË®¶Žº¿!8êþ–<-o”?uK–WËåGÝß’›j5ÕfªÍT›©vSí¦ÚMµ›ê0ÕaªƒT/FÝß’“êŨûò•T/FÝß’“êŨûòT/FÝß’›j˜j˜j˜jšjšjšjšj1ÕbªGÝß?uKž–7ÊŽº¿%Ë«åƒò‡£îoÉ‹å¦:Lu˜ê ÕXHõbÔý-9©^Œº¿!_IõbÔý-9©^Œº¿%'Õ‹Q÷7äaªaªaªaªiªiªiªÅT‹©S­¦ZMµšj5ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªƒT/FÝß’“êŨûò•T/FÝß’“êŨû[rR½uKnªaªaªaªiªiªiªFÝß¾ùv1êþú²ó Áø_u}í£î¯/<Û-£¼Z>(8êþ–¼XÞ)8êþ–<-o”wSí¦ÚMµ›ê0ÕaªƒT/FÝß’“êŨûò•T/FÝß’“êŨûòT/FÝß’›j˜j˜j˜jšjšjšjšj1ÕbªGÝß?uKž–7ÊŽº¿%Ë«åƒò‡£îoÉ‹å¦:Lu˜ê ÕXHõbÔý-9©^Œº¿!_IõbÔý-9©^Œº¿%'Õ‹Q÷7äaªaªaªaªiªiªiªÅT‹©S­¦ZMµšj5ÕfªÍT›©vSí¦ÚMu˜ê0ÕaªƒT/FÝß’“êŨûò•T/FÝß’“êŨû[rR½uKnªaªaªaªiªiªiªGÝ˦ÔŨûë Ï7ÌòÿÓQ÷×_î–Q÷×WîÜ7ˆ¿Œº¿%‰«Äâ/£îo‰‹ÄâÁÁÁÁÁÁÁ"‚EŽº¿!8êþ–<-o”?uK–WËåGÝß’ËMu˜ê0ÕAª±êŨû[rR½uC¾’êŨû[rR½uKNª£îoÈÃTÃTÃTÃTÓTÓTÓT‹©S-¦ZMµšj5ÕjªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT©^Œº¿%'Õ‹Q÷7ä+©^Œº¿%'Õ‹Q÷·ä¤z1êþ–ÜTÃTÃTÃTÓTÓTÓTŽº‡åôŨûëë~Xü¿xÿÕo÷ÿ÷ÿÌ£¨ endstream endobj 1878 0 obj [ 1877 0 R 1879 0 R 1880 0 R 1881 0 R 1882 0 R 1883 0 R 1884 0 R 1885 0 R 1886 0 R 1887 0 R 1888 0 R 1889 0 R 1890 0 R 1891 0 R 1892 0 R 1893 0 R 1895 0 R 1896 0 R 1897 0 R 1898 0 R 1899 0 R 1900 0 R 1901 0 R 1902 0 R 1903 0 R 1904 0 R 1905 0 R 1906 0 R 1907 0 R 1908 0 R 1909 0 R 1910 0 R 1911 0 R 1912 0 R 1913 0 R 1914 0 R 1915 0 R 1916 0 R 1917 0 R 1918 0 R 1920 0 R 1921 0 R 1922 0 R 1923 0 R 1924 0 R 1925 0 R 1926 0 R 1927 0 R 1928 0 R 1929 0 R 1930 0 R 1931 0 R 1932 0 R 1933 0 R 1934 0 R 1935 0 R 1937 0 R 1938 0 R 1939 0 R 1940 0 R 1941 0 R 1942 0 R 1943 0 R 1944 0 R 1945 0 R 1946 0 R 1947 0 R 1948 0 R 1949 0 R 1950 0 R 1951 0 R 1952 0 R 1953 0 R 1954 0 R 1955 0 R 1956 0 R 1957 0 R 1958 0 R 1959 0 R 1960 0 R 1961 0 R 1962 0 R 1964 0 R 1965 0 R 1966 0 R 1967 0 R 1968 0 R 1969 0 R 1971 0 R 1972 0 R 1974 0 R 1975 0 R 1977 0 R 1978 0 R 1980 0 R 1981 0 R 1983 0 R 1984 0 R 1986 0 R 1987 0 R 1989 0 R 1990 0 R 1992 0 R 1993 0 R 1995 0 R 1996 0 R 1998 0 R 1999 0 R ] endobj 1876 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 1878 0 R /Contents 2000 0 R >> endobj 2001 0 obj 15845 endobj 2003 0 obj << /Length 2004 0 R /Filter /FlateDecode >> stream xœÅËrÛ6ð®¯ÀôÐ8‹@‚$rk’¦ãNÚ‰Çêôç@“Ì EÊ|ÄQ¿¾‹ >¤$=¤Nf´»À¾‹Waø·–?§(ݯ  ˆ"?4$"x”¡=20C…ÜåÔBð£7ð€þ^•+Œ~[}ø‹ÂÀð´ÂSqŠùvuãè—+ø‡ëÇh·zµY]½eˆ`´Ù!ò#Ï'þBŽbϧ„˜möèÃÅ›¤Mî“F WIúi-ʬyþm~_ýº¹äú?¸t£lP>¨DSøy*Û£àñŠS =} *…¾¦Eë–K…IùÕ†hPû£Oú7°ëŸ4~¨òÓUIF‚½xTÔNÀŽÚ,‘RwïŸúIJ¸™ªóP;ƒÒÎ\½õ¥õÁˆ#ŸzÃa¾9 ¢IëüÐæU‰ª-J«²©ÄÖÍA¤V(žëfEò”ùFùCÕ´–c|‚Ã9Çõ=GëA\.Ú‡¼0N°ië¼Ü]:ûڮš(ÛÆ•*DX&{‡RÕ|ýÞQ™e ꔜ÷ gW‹Û›wŽe¢þ,jט&Ï„é-£(„!Dbì“HG¡*=à‹• ¥…L8œÊveáj¿ïÊHXrŽúçd‘ñÁÚn¯ªX"H‘È. ¦Khz,$í)W.+6]ûÓ•¯ôìN±K‚ ‹´ìdÀ3ð%|6ñAGÑ;ÛD c÷ŒYh®ìþl3ܪžˆúî'™K•eèéÎìÐJÜtðÒxàW B‘@6o®õv 伩3–S¦JQÚ^°´…Æœt²ÜZ“Ó¯XÇ#s¸ }l¢" 婪³óÎØŒ…òHÂý1²Ô확pWŠ2­s ͪªa3ðnõí£à‰³=}cÛžDÒ¤ìá{áÚ³Pó‰obhH_¡(ߢ²B½© ¥ô°ì»ƒO)÷Â(‚©‚³áôž üœåºlÅÎ\ dxI³w0€¦=hre!\ šØJpÚÑܘS¹“›Ø–ìYTæc)Ø™ø“‰mÒ0Š€y,€¹ë|C ƒ`Ä9%z(P3Ys>Š3®¥¶íjð°Fu¸l Z²J³tÝñÙ8{ÞÔ˜z±ó˜S3ŵíñ¼™3Žþ”Á ›%[ÍŒ¡áöØÃ*±Üæ…³§êA]f³?÷Ýnç*Ù×ìD3l×WØÜ„QehÒ$Z0pÃÃ+–ÓõtꆣG”Ç,6GñϪ§s Qö¡b"?„ÞɈe)…£‹b¹>UÑ"™2üヅÜ÷¨€…¾a|—ß×IŸ·2 !ô˜¬Äæ5e&.C¸í•v¿7On‡dºNãÚ³2^;pZäP5¡PVÊÝ…u`ö~ò)ñ".ƒ4ZpdíÍc¡•xMu:0¾œt÷Üs G¨¨Ö“v"ÃJ㉈¡y1,ߤÕÖAì¬eP'†2Z–»|›ë ËÐôDd±ÊïuS­‹*ÉÖr¤~qé¬?=ä郃÷½Î1©r“H°àìU×ÔWàÄÕBdüŸ³D^à—©Tèâ—,Ëe”“¢'m‹d×ô˜òIƒEÖƒ%Ì•b@u¿1»òò“î6OjÑÃn4Eç@ÃNì9|q¹F'îèÔ¸—ÏÝÅOë"ý Šðëm ˆ¸Gäç²þB¹.!&I‘ÿ£ ð\/`˜xœÃÈil(8y`ð/Ä1ãá<À²íËê ê¤è™ÂT Vô,-dHT`îžÏcÁ‚p"57Œ< t!3æB¬¤.u'ê¦cÛ•‡6î Ý¢¿=Ç;åõR™ø Ñf<ðˆl>1÷âëár«ë#Å}ñ›Nm !¦Ø^·Gxg~9ó=g)a@=ÀcÌl:N,X`p?ÍTDK*Ði ñ’†áq4“ÏÃï“OàÈÌÜGÍL¡ß«Ã_Ò1}šÌõÄxIÏÏzr“ýé¤F,™èÎã3m4ZÒf˜ú*z³ú™ÙÆ endstream endobj 2002 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 2003 0 R >> endobj 2004 0 obj 1733 endobj 2006 0 obj << /Length 2007 0 R /Filter /FlateDecode >> stream xœÅWYoÛ8~÷¯dM¬URÔE{] ©"‹ —Ýö¡)ŠM§ÚÊ’#ÉM½Eÿû©Ã:¶Ý$ˆÉ!‡ßß éÇ‚¿}ùasæ«Þc&£`ëÀ¬LdZ@ M7aÙØ_î* ô|„é&|„w½ Gàuïý\\A…§©§”§½›¾\!¿ŸÀCïtÖ{qf%0[îBÄlQŽ?GcºbÌf+x4v÷ÞœºóO},âã0û«7™U\bTÿ\ºQ6(T¢uü³5•íÊ‚iêJ‰ …|'U€,•¡$Å–K~–ºì35$¦þ¤Ÿ~¤ìE•¿¼›¶T¤Ds*|Ðï$À/ŽZ#‘»ð‡ÅÄ:„ZqK%×ΜJ}:¼Äs}ï_7ñ u¯% †Œk—GZNªú&ù~Þ²ßf7 TÐtÿÝ‘/–ƒp-"7p¨f~è.úáç~üè÷ÃÅýüî8=¶|˜cÖ€}ÆR‚ÅÌlÎm#SHBX|p5>}÷YQk0CÑ"¯õd»° £æFðbHµyOœ±¯èÔÀ¶Â2üWaˆ¹ 2L×bî-½y%äLæÆ¨c¡ß”pnYÐ§Û q¿@¸„yq`?Æ÷¥‚:\³L‹Ó±ò\äûqwMÁ4ZqЉ€ìk*@7€ÝfÑ&Q'%?ùoQX»qüF‹nÙ‚š8¿Û}`¼Íºr~’È :QuÞñ¼ :¨¡SK# ’™ÂXÄóÈ[+Šuó£i>;›f› ËÅi¤»Q^Ô"M…©r"±ŽD,‚DNŠ ’Åq¸‰æw%´ýÆXºFm¬*NX“íæ4Tºì‘G)NT©»\Â=iE>cch¡Üá¶ÙΪv j"˜GÛu"ý³Æ2bkDGVî<ÃÊV«›ú·îƒij”Î*Dé™ÅTÚnäSô¢¢§ùx,DäoËŠŠ6ùdyŸE¤óߟâbz¿•0ýÚ¥¡Ì§¼f¾Ä˜GÂUÑva<½´^ƒ¼ Ï·vfØÒŒP“f­ý2LD¼·X™mi&æžs’½%ÎÆã‹}Þuø0Å3YÞtݬùh¶í›©Èö¹!c3Ÿ$|1ÇF¦øTÜèa³B:í$*Iù¸|–4y7[n•ú¸$ KH¾'iFs¤ ‹«®Vt‹Ë¸„÷ÿ ÓJX^Ü ª×bá=a$ß‘UàÅ«–pS¯\Ø0ùâ®Öþ.Ám¬Ý›ëåþ3’C#ÍV1>nÝðu³ô6hXN> Ö>†qòÄêq Š¡CÊÍæ«È$´ 2Ð…j©ÝV4)¾ÎtÛwîîK¸;Ro°AVÖpxw”~Ÿ×—ý³<Ï;ÔÁÝ1´Àèf ª?ƒâ õît½ÿL|OU½„ßþ|u1½¹èËf1ÿúã“ÙÉéÉtÊî«áêzr _1Ŷi©Î¾½lÁ±h #„åFÑÌUéª/@&¯Tk†Ïž ƒŽ†[µ¿/ËÈÃg¨¿í§|èËÜb. ±ô2“´%ÃiIFÓ>8ßž¿Ü޾žEBÌÆÓoÃéäV TP3ðaêQd =|s>UÂ>¼~W’ät^_ÝÎFÔ`lˆ¿QŒŒ O®¯GÊ÷Jñ:~’Rá?D©¶è¿hľ“eímÞbزtàw§Ò¾±1ìŠ-˜»Õ¬£Ö¶–ìöE¥IøÛÝl“^ÏÙì »ÙÙ7éT’”m«ÜþùáªM—Â’-)0Œš÷HAá®´Ò×ì›ÞÂs¤t endstream endobj 2005 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 2006 0 R >> endobj 2007 0 obj 1388 endobj 2009 0 obj << /Length 2010 0 R /Filter /FlateDecode >> stream xœÅVKSä6¾ûWè¶Ëa„ž–´·IŠ•ŤrXö <pÅØƒåaÃþú´ü{Æö°ìåQ–Zúú­î~Š("ð»eJ£§–F‘bˆÇ-Iƈ Ì$zDíZ¢,Ü,X·‚Os èŸ(ú=úüWˆàkDÙÕà›èz ?œw—OÐ}t¶ŒN“ˆ´\÷.â sjà'6HcÎÂ|¶|DŸ?^ØÊÞYïЙMþ]¸|åO¾ åѯË=“8e?Á¤ëZ‡Ú†:Ð þ®£½w Ù?dÂŽÞSk¼¡¥‘޲6tí·Q¤Y6ö4ßY;HoZ±Ÿï*|>+TR‚õ^>0Afà½6 d½³‡#F°‚w>´ ®* Bo ú寋³óƤ‚s¦á˜à„ÁŠ c´P î*½+m™:ßaG)I¬€ jùàÐ Zˆ<Õˆî·wí ë)¥{Ú¦¥ó=Å&‰óƒ}U ÖCÞû¬Ó¼råÚ&ƒ Åz H–¹û²8¿êI¹}tM.Î.q¿[>¤~‚y㉡ý:>°pyQ!ûlÓÌÞe¥9 zWej3ôìJŸ9Ýv*½ ‹‚˜2®)—yZ¿ô›­€Ý±Q®±a” ‰Ucÿö®˜)€â˜xBÒpÛ… }°Åê.Y<³Û“±+¨–# õ«õ§bãJ[tØe…]-Š údþ)[Ô'ÙuÀ!tÌRF &!ó©ˆäNVû¿IÅ.1 yºêJõ²qh]”7ôS­$~=PL(,%(-tûˆÎ‹ŸC ›’3/’)Ŷޕó2ø[eð)ëý×¢\ÍËÑñl*79ãcÏ )‡òÊd³Ví¾p>)ÓMÕ–ƒ™¸Ž âÃ1‡üZB4z”Ĉ(Hù=*Ýʯ˫° Ù_'xÈÛêi¨“ø¸:FàXkc$ÇáœÖg™Ó'°ªu@ðšaS?S»…#¸Ó¼¥ãÚ c%”ÑR‹éD˜Ôp ›Õ0wyR¾l*h'ëïPöH'² Œj«ÈŸEu¼ ‹Øà˜@Å0JvÜ dMŽ ’PL yÕÍ 7×W)Tê®M±×••Ú…Œ 'ì-sƒ”0’M ~ȽÁÇðv:=vûN¡õËáTÑP†SEC©~”¹°¥°Îjã^zÂ:Íî·—Õ@êÊ­í6«ö/÷»:«w»Ô«å¼ï¯Ó­/OAð,¾˜Oi%&x|G2JhÃ:šâT¼uöˆƒq–AC¦ñÁìQ××ÑÿÈŠq endstream endobj 2008 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 2009 0 R >> endobj 2010 0 obj 1050 endobj 2012 0 obj << /Type /Annot /Subtype /Link /Rect [ 286.93 341.187 352.93 349.587 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 2014 0 obj << /Length 2015 0 R /Filter /FlateDecode >> stream xœÅXIsÛ6¾ëWà–x¦B°\|L·éd’ºR¦Ó‰s€(ÈFM‘2AÅQ}¸BÜœÉ!µ­ððö÷áðã‚"¿KûD ÅûÅcM£(`ˆû5Iøˆz˜ ´GõX Är9ÖŒà«b‚Á=úk‘.úuñù ,n§é«+…W‹Ǿ]!?Ý>Aw‹×ëÅ«k(Aë]—"`N#øñ#bÎìr¶Þ£Ï/¯d!7Ò(ôZÆK•nÍÅ´þ}ñv}§ìé¦ô¡Œ¡,4ƒ¿—Õ>[9_qÐÒ;jiW4 T¶íRR—®þ®©†U<Õ÷d¤ ƒ¸QœCã§ŸFE`)Áá˜G'ð“³6(¤µÝÆõãñB nQâܯ‚¹})Ívw™T. …^”³$“Ûev@/âÄ<&KøèBÝ^TQ»ÚÁÜ'ðãÓJB¨âÉ&ð{ /þ0ªø‹ Yc¨¸WhuóÌ ¯*7:KC›z¿a´†åm³ ‹ÓA¡]–Ï !mÐeå9n\âˆÒC°OÏ<#¶ÒŒ‚c, *ÇÞdiªâÂê\T¬w:–væ¨ò°×Ó…˜Èea¥euJ ù e;·ú–ô5jÆJDÅÌóἩQÃÌ=~á ùw:Q©Ü«I#”°+³±QÏÇ‘m‘!­St¥LœëC™£é‡.ÛýG,ˆ"ã>ÐC‰?"¶*rÞ!ÃA÷VÊÕ!WF¥…]°iT['G!Ó"Ër~X(Ô™D°ÔáCV(3›=Æ|LB˜ðY`s†y˜RµÜ-c¢·ÅßÒ› ´d8B3Š(¸BK€M9Ôó|a8ˆ„!ž`#ò­²}•ÉQµ3¨JßÇ!`CŽ}Ûi¨óñr¯öY~ºœô‘q:'ß:𤓤Ĺ²-qè‹—† Óvx¸?h–Ê5‡Õ ÞHôG[¯‘Òú´ç®,Š»[mðH[)#”ó¨ð­²}¥~é]y,FCl’TO7®À^¦'gZè½rEw¢Ï‚Þ97¯ÍzZ¨»\®Òø^Å5´6×$Enµu}tå*Šsqè #ɉ¼~rþþðæ·??~øøi…v‰„î’¡××èTª¦µ¼[¿E…#@ÀžQ[UH˜Û <Û8œ¤‚BK¼îl×WWïç:÷8̾Q8Wã!Ÿ=L!vzy™=¥UEªùƒ:=eù¶#ÈünÚQ ênìê².w³Ý1[èԤ̱”hÓ”¡¶”:f¡¡ž¯žÉºH©(Ùæ覎-mFr!D/ú.ÍrµÙCpÄÀùÈ¡ü^0›ßŸÍïeœ%Ç}º´A¢&§m*m§ZtDö¾Éü1åUSZ~ÕêiºÛ…dN…½¥YÌñpÈò6 lþ¡8W@Çò ç Ê››Î~“%:¶ŠPu홿  { ø\v‡|ÃÓ;Sgñ”q&½ S‹7à¡v™$3‡™ýeÆ(s’&›9^™ˆ~Ôªï͆šžf4›%TnÕ)»€5Ü< †²êl 3i™ÃK|Zj¼y<*8O»“ÉA*4Ñ€û}¬Šî'”„tBüùŸ†8`~F¨t¼×›\æZMG(¶s±º÷r¶TãG;oj ¼¶Ïš–’«Ç£Î«ãµ¢?ªÜÜË\9ª“2¸SG(/ÆÝô]áXݪ<&Å9s7+oÞíL›IØØ|1¯—¯WG“¿wì§zÌql²é»hHF”|Ç•^¸ E~‚õÃø]ª -ý¯|îŽ.¿'ûÉL¿½@À§û‡—TÔ¾ð¾÷ÎÇžá>c=…ϼÃ}ÏÜxHùâÙ‡8ÿ‘‡8{ˆsìüãäfñ7ˆÛ endstream endobj 2013 0 obj [ 2012 0 R ] endobj 2011 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2013 0 R /Contents 2014 0 R >> endobj 2015 0 obj 1431 endobj 2017 0 obj << /Type /Annot /Subtype /Link /Rect [ 286.93 296.502 352.93 304.902 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 686 0 R /H /I >> endobj 2019 0 obj << /Length 2020 0 R /Filter /FlateDecode >> stream xœÅYÝsܸ ß¿‚O­s“•)RŸ~Ë9q/7nÜœÝv:ç›®–ëe­¨µ³ýë Š”H­>z“‡4ÉÌ ?‚¨|YùÃßµú‰S‚²bõÅð|D#à #ä QÌ8D¹Zå H7‚½{ôÏU¹Âè/«_ƒÉ- ðºÂçêZáûÕgg5ƒ¿ûþ=­~|X]Þ„ÈÇèag!¢±GýþD)Jl‚1önµ‡§´O×UYò¬U‰î<;‘1EiG[Uœi ˆúQš‚&­åþT6ì+ªv(ëõ­%èëÔ¤ç ŠB‚‰˜âPky¼è–Ãâ³õa0^¿9/YÁg7ñ1K¡?UeËÑüv~4aŸ(E³ÞËÌh´) ¢ ×Þ,šb/&>D±I=\fµhí\@ul7ÀêûÔ b 'ŒÉ4N£p÷¡$ŒÅî›Z”O¨æ‡šK^6Šhöuê”aоÿ|+Ž^x-•¹m»¼©VzËÆÒÀKi„q O[<’}‡Þ 5MÔU¼èT8¬-—â©dMU{wÞ>BS/àT ýfK)\E+PâÒ°g.š9c àçܬŸŽŠÃ‚ãp”漇˜Ñ™òK§G¯Ìïz»y jâPkíªšv=}¨DÙ𺧛Ê÷¼_÷£­ èÊÊ´öŽeJþšŸì¢/ùÖª1¡µU­›aòM‡E e¬qªPÒŽ3–ç­e†ÞœìXûÓM˜îÁQS|+XÃsG†í4 †4·ª§»ëÕ3è|ÚS@ ›<èߢóàdBTmšh.r±©Y}²ŒÒ·–Å´«šÈXi‰ ·ã£äβ6~ÌøÀk·Â2l¾î8]LExB&Ž^°\ü§-lÁA©³Sé¬ ëÎ ‰D9ÓŒãÞÄŽÃKã45¹þò*ãÿÊŠC{kÕ†»°n~h˜a:yK‘¯{‘íÍxËw¢lSD«ÆüÂ}1£¬ÊsÖ¦iMKþåÈˬ3œ²ÞÖ7ükõ&? ‰uõ"¶pV€ÌB̓6:Q]MG½K„¼41xÙ߯ËÙH ˆZ ƒ ¢p¬Ò©¦3 àT|¨Â44qð©j¸\,Ã$&ÄMšÆ8>oæ M]h«Àù$ŽMCôHHxv8µîoLJ}`kÛ¥b”úNâ(I'ôüŸ‚<à„dB¾7€õ£–yOéâ2°qœwêEêêùá”W/ªút5Ÿ|¨¿$ßð*ò¼'²š³†OØßw!C”ýð°?Iht­mš³T6œm§¼?ªó-ÅÑ™¹¬mÜä­Ï牢†’Ä#<>ià/EÍxÝ}U´nùp-Ò¶FÖ&·Yf’!7®@ÁÊ“C6¢à®èŽISŠ CìÂŵ›‡^à©«4ÛóìÙ„v·ÌÝ@aS@;]yÉ›f(yyœŸƒó¯O×?ýr÷éîï÷h—3èY+twsƒA%ï’ûLJP8B@ZD[Þ0‘ËÇ7Þb~ Ð×ÇS|bÒÃÍû÷·K‰&‰DÑ4 ‹G˪œr!»S0;•ζO‡³Y7P4§Úü’©³—c, á>Ã*4ÔéíÄRE"Ué?Åt ßñ:…ï•.skå$ê0í¡TÎÖ;ŽT=£I4¥\ç¤õ‹à¯óÉ.ÁK*Té-«ÉãáPÕ Ü¸ç]Ér´ª(ÇP2â¤{¥›*™Òƒô“})xè}ê§I.ƒ;Z7~V|àN{ Ð%ž©çsMh‡Þm¡„à%Ñ· ›ÒpIRV Å•„é·î‹®–§…ZD µ7un_Èaž’Å‘?!˿³;S/Ão ï„jjë’¨Ãs8: ÕÌÁnŽÍ¿«Y–óÿÝæ…”@gH0I“ÿoÛN]ðyû!¶Ã0³cx“§tp_•½»¥Ý'œæÔÐ[‹Z—MÍi–Ü]´D– “«5ݽ-,çq¾É"©²  ý± +ËËFî=YÍ`”,é€2hMà’WY÷V1Ýuézµ'ì°ÝÙÝL¿'APêÏéj®ž1/\¥`…êÝ/ï®o?üþÓÝ_? Ý•šWš 0¨@ò-Kxù"êªTùû<B€‡&ºwÅ­yÞþCg®>„¢©Ï—~ ßà±p ‰oô8ñ°úħ¾1ŒeÛO7©zÛî™´„ª°ºGÒ´1MØXÓ´ó€×Œ]]–²q«éTر)ýÓ }ìX yý¢ûM«všµoÓÓ’Ð÷ÑÐ@ª€á•›n¿¥ÜmßޱBÕ®Úw͸î±Ð´{ï4çF÷/®zK'Ž MpVƒbGÐÔ=ùÖ²àLjG•îjh¢žsœ4Ur©€ž!]Áá(÷Ý·YÙ–xtUe"†§\ ,¿úaíÈ’Õðšà"°óŠm;¡ù*¡¾]bèQ|õM{´w–Ã{~] 2õ8×$é’ôîþý¹¾žó¿+ŸWÿóÕÄ endstream endobj 2018 0 obj [ 2017 0 R ] endobj 2016 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2018 0 R /Contents 2019 0 R >> endobj 2020 0 obj 2091 endobj 2022 0 obj << /Type /Annot /Subtype /Link /Rect [ 404.78 194.772 488.78 203.172 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1231 0 R /H /I >> endobj 2024 0 obj << /Type /Annot /Subtype /Link /Rect [ 264.16 182.772 366.16 191.172 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 2025 0 obj << /Length 2026 0 R /Filter /FlateDecode >> stream xœÅWYsÛ6~ׯطؙÁÁÓoµÓtÒIêñX™>Äy€(Èâ„"h‚j¬þú.HÐ’xÅ=Æ•=Ã%°ûí½f (þÍí#Œ9$ÛÙƒ[cr[ò`á>lÁÑ>d–ëˆà-…† ‰ ü>Ëg~™}ùŠ›+ (ð}F»pµðíìæH¿Ý¡/®ŸÂýìr1{ûÞFa±>„H„D°A Ü’³Å¾œ½“•\J£àR&ßæ*_™ó¯°øuöóâÄ%ÁøÿàÒMmCíChŽÿ!©³}²á{ôt稞֫µBѬáJ£Ûne.uîÙÒ?ÍsÔzpƒ{qZ/ª|¼*B+È(‰Nê{b´^8j½DZÝOþÄ]¼8%" ø Xã Ü;³ ¤!$ÙÅëµ’Õ®TæõÝyãé1‚àCÒ¬ÖºP¥¬¼ªß2-Ws]À«$3Ù\—2ÉÔ¢çuž·ï0,ͷ؉#¶–IhÓ2ÑÈ|ÈÓ*•Yú§¬R·½”¢º8$4@},ŠÑÏFµüC!c‚ûq,¨×ü;w™':x0e. |´Ù=4ì•« ª‚ëZ ,Ýh"°ÀÅU;±ª}¡`­Ë!VH ¦¼^#?Ž7‹ñ1bpµ+ç*±Á†ÛB%é:MNB/l3xÎ c† DØÀÜîóJ>‚^Cò878•îù„1;°}Ö¦¤åGï Ügz)³y.·ãÉgœH¸&†)ê ìŒ*ÇuøW‡?¤£Æ|×åjT§CQhës,]!–~È(ó\¥¾S&)Ó¢ÎúxÊúFۜŶÍ‚^0î HÞVešßÃ9rxpVª‡•Ê«£5[ðŽlÔ´oV[K£}v×&î­m%Ò.,6Ø7Ž>P™ÖßÔª}ÛÜRïî7!`4è8em¨rc 4ÖéQkÆTð¨r\kƒÁ싸`žDÑÚb¡ |©‰Üáò4½þë|ÚQÕ­Òa {bc¶p>c´‰0"¶!åm•ÿ¦+e&ãxˆD!¥~ÀÛ9¶]ê,Màöæ#4Cmjª{ Ã8¦¡¸ãÜïÔ‰?Ägüh—‡¡¾®ÔµUùãÑgÑ”84 ßµ‰q£Ÿ ë>ž‹=>‡½ÒÊ@®+0»¢ÐeUç||âmÍ mÕ„bS=&ª¨F]çØŽÒO®ÀÛ¸ká7W™>Ê6ÍwfÜ„xJÒÜTJ®†zÏ tï?tSfÙxEÑ”è› ¥xÿ˜4zâ áØùÿL+ç|ÒÕ|?®Ô›Œ†zù°SåÞUÎ*C&GVŽE9žp7°E)s#ëãw¼ª°>|.HàG”㈛ª>ßåÞdöTk¹Ëª7îµÕôÒDñ²jGwxxWq:ŽW‡@aû©…CÆ8ݦ’eeÜKš;¢:Ä­üôyq}uýéÓ‡…[Øê•räÝ™QªãK/ù¿tlÎFÌ1ªšãa£½Ý¦ãƒÅcÁÊÝ9qv,´#–êþÉ-9%ŒÒ)Ʊï(y0 ¬Ë“MÅ ³_^"pëHÏÐ'F—7iì½TàxÀ‹’z,ð¬L«lO޾¥of<\M endstream endobj 2023 0 obj [ 2022 0 R 2024 0 R ] endobj 2021 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2023 0 R /Contents 2025 0 R >> endobj 2026 0 obj 1233 endobj 2028 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 430.541 null] >> endobj 2029 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 575.321 298.75 584.321 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2031 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 553.441 298.75 562.441 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2032 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 619.701 null] >> endobj 2033 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 531.561 269.05 540.561 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2032 0 R /H /I >> endobj 2034 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 441.921 298.75 450.921 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2035 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 398.161 269.05 407.161 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2032 0 R /H /I >> endobj 2036 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 263.261 null] >> endobj 2037 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 230.881 261.82 239.881 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2036 0 R /H /I >> endobj 2038 0 obj << /Type /Annot /Subtype /Link /Rect [ 232.94 73.481 261.82 82.481 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2036 0 R /H /I >> endobj 2039 0 obj << /Length 2040 0 R /Filter /FlateDecode >> stream xœÅXKoÛ8¾ûWð艪÷ã˜6MÑEÚE{¨{`d:ÖVG”’æßïC‰´I79u›æŒ8œ‡ß ù¸ˆâ'+BR6‹GÅ H’(U¬$%Aì… iˆ'¤³ŒA8à'Á`GþY´ Ÿ|Z|ÿ7Äç…¼œ¾[ÜúÅÿë7-ˆ‚ð±@Ø wEîKÿ3OnÎÁ‡$ö¿7ó5W*ŒÔ->Õ*Òê Á!úƒ¿'ýðµ¾;ŽÊÃ?§Ü'‹÷«Å»ë„>YmužgB0ð½<,Ä¿¬ò}ÆñÙ²úkñqe%ÀŽšµ‘B÷ìODÂØË¥ñnù$ ¼0Ï|ßOSôéSÝqNûtìÝu&ÒÑ” r’^¥ ”«@|í6 X±,ö²¸$AÕ®âäŒ\¤^F–JåÌ0¾ñ¡ªë™zbƬaWµµ&÷Ý~¬éÀ6ç3‹¶›yÜvƒæKölËzÖ–Lë¬ZC›Ç 5?°_z½}ÒÓîÓÓö}·g½ae]µ?ÙceF(O"$l/»®ßT­pŠt=Û ®"¨1ÞÐÞSÎ 0jæŒÙpSíM™ží{ÆY;h¥ÜåjèºZvõØ´œ¬—]O¶«7|}&bL šb‡6½Ä‡ ÓB…«*H“É—ZKæŽGSß+bH”Ð)q5ëoñ#á0„4KbR°ædI†s>tm KB*¹l·¦¿j»%ñ6Û-1‡ípšÂTì_PL¶‹ tÙmM}ÕnKâä©)2ÏO@,ò‡˜mwG,(™­~VåÛVm%v@ónà¸ôáX7,I|¸Øzyuu³>sDÁV¼àãã=gƒ|w{CFg ù¿‘V´D@ûE¤Tò¡K‰: Dç\wx 臠0-ÒCOchO–_h[I4W®JæiO“øh1ðôË O-Å+„øÊ) º<Ób8A˜ ™a™‰ªå…’sÍÛ°š±Æ=„Gnæ¨r¥–dC¹;ø¼Qš´‚.G­ üf7²Ä+|ÈÍ4É纶&¿vbl‰7t[Ìa9±L A§oYZ:`É\¶ ”HÛáeÏ~“¹QPxi*â©J}-êC=óµ@Ùo‚[Ìavx œð #Ãl²o9¹Û³²‚ºÖ»Ü°$/É­G'ž„+Q.@‚Èh¹ÃB‰Uòq„ÎÍaUy1Ú@Û@ÿEÐÑžA¡û(QEº³±mj ùä°d)ï¾]½ÿrçPnÏMjáÅdùa9‘[ 9)Þc_)i(: i¡âܽp0y¢Ö¨?Å×9¢Ó€wÛáûNIïiùH¨.«£àÈêF˜‚à7ÕãÈ膑! § B ï.ZJKp͵¯LÈèú¨½XÜ”êÖ—pO:ø¨—ê»gW/ÇÑ‘sx³Á†Z¶ 'Zè8M<_À`£ÚvV…ȥĚz Y ÷:©c‚QD.NÔíCbÓÑSv@çVˆæ( ~ëž]FXó^Ã{ÇÊNóÂËCÉ¢Ð!c[œ@;—}?€§,™3ÙadPøðÏÔÉæ* Å«G^d tÂU8ÎN\µõJ`…ÍIàŠöõîóL´ÚofÆD3[ªiv×ãi@SÇ#}W\ã³Jv$*m5„ 0ÐB@˘¢åq45<g‰ë$w߆l‘•Ä^QÆæÊPà‡ríÂD}“¥çBòV›™Rý¨ZEëùÌê m­æbŸ3“Ûy(K÷¼Þc}Á¤‡.÷ ·> endobj 2040 0 obj 1877 endobj 2042 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 433.491 null] >> endobj 2043 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 709.5 191.33 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2042 0 R /H /I >> endobj 2045 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 709.5 542.353 718.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2042 0 R /H /I >> endobj 2046 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 383.593 null] >> endobj 2047 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 697.5 176.78 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2046 0 R /H /I >> endobj 2048 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.298 697.5 542.298 706.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2046 0 R /H /I >> endobj 2049 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 350.129 null] >> endobj 2050 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 685.5 204.1 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2049 0 R /H /I >> endobj 2051 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 685.5 542.259 694.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2049 0 R /H /I >> endobj 2052 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 264.231 null] >> endobj 2053 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 673.5 219.11 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2052 0 R /H /I >> endobj 2054 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 673.5 542.147 682.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2052 0 R /H /I >> endobj 2055 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 149.171 null] >> endobj 2056 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 661.5 270.264 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2055 0 R /H /I >> endobj 2057 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 661.5 541.766 670.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2055 0 R /H /I >> endobj 2059 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 649.5 191.33 658.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2058 0 R /H /I >> endobj 2060 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 649.5 542.353 658.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2058 0 R /H /I >> endobj 2062 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 637.5 171.78 646.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2061 0 R /H /I >> endobj 2063 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.331 637.5 542.331 646.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2061 0 R /H /I >> endobj 2065 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 625.5 204.1 634.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2064 0 R /H /I >> endobj 2066 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 625.5 542.259 634.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2064 0 R /H /I >> endobj 2067 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 720.0 null] >> endobj 2068 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 613.5 219.11 622.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2067 0 R /H /I >> endobj 2069 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 613.5 542.147 622.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2067 0 R /H /I >> endobj 2070 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 607.992 null] >> endobj 2071 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 601.5 270.264 610.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2070 0 R /H /I >> endobj 2072 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 601.5 541.766 610.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2070 0 R /H /I >> endobj 2073 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 397.304 null] >> endobj 2074 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 589.5 191.33 598.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2073 0 R /H /I >> endobj 2075 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 589.5 542.353 598.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2073 0 R /H /I >> endobj 2076 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 304.016 null] >> endobj 2077 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 577.5 244.25 586.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2076 0 R /H /I >> endobj 2078 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.958 577.5 541.958 586.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2076 0 R /H /I >> endobj 2079 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 720.0 null] >> endobj 2080 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 565.5 179.0 574.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2079 0 R /H /I >> endobj 2081 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.281 565.5 542.281 574.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2079 0 R /H /I >> endobj 2082 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 695.117 null] >> endobj 2083 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 553.5 204.1 562.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2082 0 R /H /I >> endobj 2084 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 553.5 542.259 562.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2082 0 R /H /I >> endobj 2085 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 630.263 null] >> endobj 2086 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 541.5 219.11 550.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2085 0 R /H /I >> endobj 2087 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 541.5 542.147 550.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2085 0 R /H /I >> endobj 2088 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 497.291 null] >> endobj 2089 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 529.5 270.264 538.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2088 0 R /H /I >> endobj 2090 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 529.5 541.766 538.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2088 0 R /H /I >> endobj 2091 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 299.582 null] >> endobj 2092 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 517.5 191.33 526.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2091 0 R /H /I >> endobj 2093 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 517.5 542.353 526.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2091 0 R /H /I >> endobj 2094 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 246.728 null] >> endobj 2095 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 505.5 214.368 514.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2094 0 R /H /I >> endobj 2096 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.036 505.5 542.036 514.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2094 0 R /H /I >> endobj 2097 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 211.786 null] >> endobj 2098 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 493.5 204.1 502.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2097 0 R /H /I >> endobj 2099 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 493.5 542.259 502.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2097 0 R /H /I >> endobj 2100 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 146.932 null] >> endobj 2101 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 481.5 219.11 490.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2100 0 R /H /I >> endobj 2102 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 481.5 542.147 490.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2100 0 R /H /I >> endobj 2103 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 674.283 null] >> endobj 2104 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 469.5 270.264 478.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2103 0 R /H /I >> endobj 2105 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 469.5 541.766 478.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2103 0 R /H /I >> endobj 2106 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 546.402 null] >> endobj 2107 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 457.5 191.33 466.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2106 0 R /H /I >> endobj 2108 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 457.5 542.353 466.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2106 0 R /H /I >> endobj 2109 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 290.373 null] >> endobj 2110 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 445.5 214.368 454.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2109 0 R /H /I >> endobj 2111 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.036 445.5 542.036 454.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2109 0 R /H /I >> endobj 2112 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 255.773 null] >> endobj 2113 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 433.5 204.1 442.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2112 0 R /H /I >> endobj 2114 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 433.5 542.259 442.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2112 0 R /H /I >> endobj 2115 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 191.603 null] >> endobj 2116 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 421.5 219.11 430.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2115 0 R /H /I >> endobj 2117 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 421.5 542.147 430.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2115 0 R /H /I >> endobj 2118 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 720.0 null] >> endobj 2119 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 409.5 270.264 418.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2118 0 R /H /I >> endobj 2120 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 409.5 541.766 418.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2118 0 R /H /I >> endobj 2121 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 499.932 null] >> endobj 2122 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 397.5 191.33 406.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2121 0 R /H /I >> endobj 2123 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 397.5 542.353 406.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2121 0 R /H /I >> endobj 2124 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 246.198 null] >> endobj 2125 0 obj << /Type /Annot /Subtype /Link /Rect [ 144.0 385.5 170.65 394.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2124 0 R /H /I >> endobj 2126 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.34 385.5 542.34 394.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2124 0 R /H /I >> endobj 2127 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 211.853 null] >> endobj 2128 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 373.5 204.1 382.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2127 0 R /H /I >> endobj 2129 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.259 373.5 542.259 382.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2127 0 R /H /I >> endobj 2130 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 148.193 null] >> endobj 2131 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 361.5 237.047 370.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2130 0 R /H /I >> endobj 2132 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.012 361.5 542.012 370.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2130 0 R /H /I >> endobj 2133 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 672.0 null] >> endobj 2134 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 349.5 219.11 358.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2133 0 R /H /I >> endobj 2135 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.147 349.5 542.147 358.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2133 0 R /H /I >> endobj 2136 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 551.264 null] >> endobj 2137 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 337.5 270.264 346.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2136 0 R /H /I >> endobj 2138 0 obj << /Type /Annot /Subtype /Link /Rect [ 526.766 337.5 541.766 346.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2136 0 R /H /I >> endobj 2139 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 365.968 null] >> endobj 2140 0 obj << /Type /Annot /Subtype /Link /Rect [ 168.0 325.5 191.33 334.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2139 0 R /H /I >> endobj 2141 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.353 325.5 542.353 334.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2139 0 R /H /I >> endobj 2142 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 720.0 null] >> endobj 2143 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 313.5 155.55 322.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2142 0 R /H /I >> endobj 2144 0 obj << /Type /Annot /Subtype /Link /Rect [ 527.292 313.5 542.292 322.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2142 0 R /H /I >> endobj 2145 0 obj << /Length 2146 0 R /Filter /FlateDecode >> stream xœÅÝM%Ùq˜áýüŠÚ™Z¸™çkiɲ`ƒ¶@pl/-hjdÀi†–Mÿz߬²óT^➇hRÀ zÞ¬®âSÝÓ7Tñ_íoÛã¿ÿúüKÇÛÏùÕ?þðcû[;Þ¢þðC¥¾íùé(o¿|ûáïËÛ/Îêò7Çïþîñ—ÏÑãoþçÛûêW_moõÕßüíãþÝÛöxàµ}|sïÿô«Ÿ\~þóŸlòŸ{û_ýù×_ý›ÿøáííë¿ÿò?Q”OclÛ¶×þÖ?Å1Îÿo_ÿòío~ô?þéO~ügûöõ|>Yëí·ÿòý7ß}ÿ¯Þþê}ûwß|~ð/¿ž>üØÿþOÞ߇÷÷úý“âxü_ûôþ™1ýƒ’ÛüO.Ÿ5¿ÿñ/?úþÆç{üÈçŸûüG¿øù‡¿~~G>ÿíççó_ÿàDZ}ù0¶ëG1ýIòßÝ>Z~Ú÷ÇgÐVïÖö©OŸÿôíü4øÿowã<î?üQûg÷þõo¾ùþó‡óûlßǧˆó×Oû/‡?{${ûÔÞ~ôñ±#>m[Û¶h÷_vŸnq•x@‡ÄEâqî§Ä â²I,‚E‹V¬"XE°‰`Á&‚]»vì"8DpˆàÁcÁcÁcÁcÁcÁcÁcÁãÁãÁãÁÁÁÁÁÁÁÁ"‚EË)XGïåþçƒ[\w‰SâqÛ$‰«Äâ~H\$Á!‚C>þ@*1Æ‚±àã%Ä ;Æ‚q€`"""""˜"˜"˜"XD°ˆ`Á*‚U«Vl"ØD°‰`Á.‚]‡"8@07Ì sÁÜA0wÌóÁ<@0ÌCCCCSSS¿™×VÆÈÞ`¾–?£GyÄõÉXîñræCÞŽÇ«ÔÕúíï‡ß_^Q?^÷¶öhúãþ·'>¿;ùiÜÇ}_;O‚mÛz¹?w{ÝþøÅ#uRݤ~RÕ•ê!õã×Ô…j²L²L²L²,dYȲe!ËJ–•,+Y6²ldÙȲ“e'ËN–,Y²byŽ;¥Ësà õ.–çÈSj±<‡žPbyŽ=¥&Ë Ë Ë Ë$Ë$Ë$Ë$ËB–…,ËiÙG/u!®»Ä)qƒ¸m‡ÄUâq?$.‹àÁ!‚Ï (Ä xN@!Ás 1žÐõøÁs ±††††¦¦¦,"XD°Š`Á*‚U›6l"ØE°‹`Á!‚C‡<' ƒ`n ˜;悹ƒ` ˜æ‚yˆ`ˆ`ˆ`ˆ`Š`Š`Šà9ÍG\û“)åž9ž#ÐcômËýÉŸÒï3ÐQÿ~þòµŒïÕ¿ýïßýì»oï_õø(÷%Ÿ·‡>¿Kq‚>¤ÚùN”÷§žÙ ~XIT7©ËFuP]©R׃j²¬dÙȲ‘e#ËN–,;Yv²d9Èrˆå9f“Z,Ï1Ô»Xžc6©Åò³A}ˆå9f“š,ƒ,ƒ,ƒ,“,“,“,“, Y²,ËG±oc,Ôu§:©nR·ê ºR=¤îÕ…j²d9Èrˆå9t“Z,ϱ›ÔbyÞ¤Ësôõ!–çðMj² ² ² ² ²L²L²L²,dYȲe%ËJ–•,+Y6²ldÙȲ“e'ËN–ƒ,Y²byŽå¤Ës0õ.–çhNj±<‡sR‹å9ž“š,ƒ,ƒ,ƒ,“,“,“,Ï1ÝÑÇh}}$ö>£+cÛŽúä§x:£{|sõ~õío¾ýÙ/¾ý¿?ûÍ·¿þÕ“ÙÕï¿9ûöèû»u~±Ê}VW¶Oµç¶•–÷çžM±¤®T©ëAu¡ºKÝvª“ê&u'ËN–,;Y²d9ÄòœbI-–ç ê],Ï)–ÔbyN± >ÄòœbIM–A–A–A–I–I–I–I–…, Y–Óòñ'Ë-ûB]wª“ê&uÛ¨ª+ÕCê~P]¨&ËA–ƒ,‡X>þ!ÕbyN±¤ËsŠ%µXžS,¨±<§XR“eeeee’e’e’e!ËB–…,+YV²¬dYɲ‘e#ËF–,;Yv²d9ÈråËsŠ%µXžS,¨w±<§XR‹å9Å’Z,Ï)–Ôdddd™d™d™dùøÝ¾œÿOç¾™ƒ¬=Ï8{»?÷tUê‡ê/~ý«_}óósˆuþ<ç÷¼ýè§ÿðÍÏ¿ýûoþt¶õx ÿø3ý¶µÒîoíËÛxöb>ÛåþÐÓ—òËm[oÏ—ñËm@[¡ëíùò}¹-Ðöõ6À-À-À-Á-Á-Á-Á­€[·óezömߎ•ºîT'ÕMêóe:ÔAu¥zH}¾L‡ºPM–ƒ,Y±|™µX¾¿L‡Z,ß_¦C-–ï/Ó×ëC,ß_¦CM–A–A–A–A–I–I–I–…, Y²¬dYɲ’e%ËF–,Yv²ìdÙÉrå ËA–C,ß_¦C-–ï/Ó×ë],ß_¦C-–ï/Ó¡Ë÷—éP“eeee’e’e’åãwûÇïŸWh­¿ôÍók kc?öûcO_¥×þ¡z¹ÿöÄâüÛs?èi þB=¤¾.Â_¨ Õ]êë.ü…:©nR_×á/ÔdYȲe%ËJ–•,Y6²ldÙɲ“e'ËN–ƒ,Y±œöã/Ôb9mÈ]ïb9íÈ_¨ÅrÚ’ÿº>ÄrÚ“¿P“eeee’e’e’e’e!ËB–וù¯ëëÎü…:©nR_׿/ÔAu¥zH}]¿PªÉrå Ë!–±‰å´A¡Ëi‡þëzËi‹þB-–Óý…Z,§Mú¯ë Ë Ë Ë Ë$Ë$Ë$ËB–…, YV²¬dYɲ’e#ËF–,;Yv²ìd9Èrå Ë!–ÓŠý…Z,§%û¯ë],§5û µXN‹öj±œVí/Ôdddd™d™d™dy]¹Ó¼içþí¹#ú‡¾o}ûPýõ¿ûó¿ø8„_VîßúÏïMýTŸ¬ÜO™bìåþÜmp.õ„zH}®õ„ºPÝ¥>7{BT7©ÏåžP“eee’e’e’e!ËB–…,+YV²¬dYɲ‘e#ËF–,;Yv²d9ÈråËcËcËcËcËcËcËãËãËãËã Ë Ë Ë Ë$Ë$Ë$ËB–…,Ïã-Y·=s%Ÿ§[Öã"q‡ø¼Û²§Ä âóhËz‹`Á!‚CÆ‚±`l ;Æ‚±ƒ`ì Æ‚qˆ`ˆ`ˆ`ˆ`Š`Š`Š`Š`Á"‚E«V¬"ØD°‰`Á&‚]»v"8Dp€`n ˜æ‚¹`î ˜;æ‚y€` ˜‡††††¦¦¦žÃÕZÎÓYOê?<Î|®Æ6FÔ'¤¿WG}Ì6ÿÛCKÛüoOݧl]êë6ÿ…:©nR_·ù/ÔAu¥zH}Ýæ¿P“e%ËF–,Yv²ìdÙɲ“å ËA–C,§mþ µXNÛü_×»XNÛüj±œ¶ù¿®±œ¶ù/Ôdddd™d™d™d™dYȲåu›ÿëúºÍ¡Nª›Ô×mþ uP]©R_·ù/Ô…j²d9Èrˆelb9mó_¨ÅrÚæÿºÞÅrÚæ¿P‹å´Í¡Ëi›ÿë:È2È2È2È2É2É2ɲe!ËB–•,+YV²¬dÙȲ‘e#ËN–,;Y²d9Èrˆå´Í¡Ëi›ÿëzËi›ÿB-–Ó6ÿ…Z,§mþ 5YYYY&Y&Y&Y^¶ù/Ħmþ·§žÎèöí_çvqŸÿýÁgƒ,Ê«åƒòëNÿ•¼XÞ)¿®õ_ÉÓòFy7ÕnªÝT»©S¦:HuZð¿’“ê´â!ßIuZò¿’“ê´æ!?HuZô¿’›j˜j˜j˜jšjšjšjšj1Õbª×ÿ ùuéÿJž–7ʯ{ÿWò°¼Z>(¿îþ_É‹å¦:Lu˜ê ÕØHu:°’“êt`!ßIu:°’“êt`%'ÕéÀB¦¦¦¦š¦š¦š¦ZLµ˜j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:Huº°’“êt%`!ßIuº°’“êt)`%'ÕéVÀJnªaªaªaªiªiªiª×›2”šŽÜ(¿žXÉ‹å¦:Lu˜ê ÕØHuº,°’“êt[`!ßIuº.°’“êt_`%'ÕéÂÀB¦¦¦¦š¦š¦š¦ZLµ˜j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:Hu:=°’“êt|`!ßIu:?°’“êt€`%'ÕéÁJnªaªaªaªiªiªiª×SðrzºEpîù‹ÿƒ¯ÜYÝ#XÉå׋+y±¼S~=J°’§åòë]‚•ÜT‹©S­¦ZMµšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕAªÓ¡‚•œT§S ùNªÓ±‚•œT§s ùAªÓÁ‚•ÜTÃTÃTÃTÓTÓTÓTÓT‹©S½Þ.XÈ¯Ç Vò´¼Q~½_°’‡åÕòAùõ†ÁJ^,7ÕaªÃT©ÆFªÓ)ƒ•œT§c ùNªÓ9ƒ•œT§ƒ+9©N' ò0Õ0Õ0Õ0Õ4Õ4Õ4ÕbªÅT‹©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕAªÓ­ƒ•œT§k ùNªÓ½ƒ•œT§‹+9©N7VrS S S SMSMSMS½Þ>Ùátüàþàóqf~ÜãõÃ×2?Íèo?úËÿó³_þÃ/îÎÇoµçlööøïž»õ—Õ#÷§îƒ›Nyß-OËåc³<,¯–ÉÏ攓ê¹Å\òTÏ=攓ê¹ÉœrR=w™SnªaªaªaªiªiªiªÅT‹©–Ëw̯äƒòzX^,ï”·Ýò´¼QÞ7ËÃrSí¦:Lu˜ê Õsç9å¤zî=—|'Õs÷9å¤zî?—ü Õs:妦¦¦š¦š¦š¦š¦ZLµ˜j1ÕjªÕT«©6Sm¦ÚLµ™j7ÕnªÝT‡©S¤š©æFª¹‘jn¤š;©æNª¹“j¤š©æaªaªaªaªaªiªiªç}»óðãû@euÔq~UÙ(}ÛZߟ}QÍB^,7ÕaªÃT©ÆFªÓË•œT§+— ùNªÓË•œT§K—+9©N·.ò0Õ0Õ0Õ0Õ4Õ4Õ4ÕbªÅT‹©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕAªÓÌ•œT§3˜ ùNªÓ!Ì•œT§S˜+9©NÇ0WrS S S SMSMSMS½Å\¾MW1ï=¶ûá,æíÙÕ³˜·ŸMË(¯–ʧ³˜ y±¼S>Å\ÈÓòFy7ÕnªÝT»©S¦:Hu>‹¹“ê|óu¾“ê|s!'Õù,æëü Õù,æBnªaªaªaªiªiªiªiªÅT‹©Ng1_çÓYÌ…<-o”Og1ò°¼Z>(ŸÎb.äÅrS¦:Lujl¤:ŸÅ\ÈIu>‹ù:ßIu>‹¹“ê|s!'Õù,æëÅ\ÈÓòFùts!Ë«åƒòé,æB^,7ÕaªÃT©ÆFªóYÌ…œT糘¯óT糘 9©Îg1rRÏb¾ÎÃTÃTÃTÃTÓTÓTÓT‹©S-¦ZMµšj5ÕjªÍT›©6Sí¦ÚMµ›ê0ÕaªÃT©Îg1rRÏb¾ÎwRÏb.ä¤:ŸÅ\ÈIu>‹¹›j˜j˜j˜jšjšjšêtsýåô|óöÜÓÿ碛9{yóþÈâYÌûƒ?òé,æJ>(¿žÅ\É‹åòëYÌ•<-o”_Ïb®ä¦ZLµ˜j5ÕjªÕT›©6Sm¦ÚMµ›j7ÕnªÃT‡©RÎb®ä¤:Å\ÈwRÎb®ä¤:Å\ÈRÎb®ä¦¦¦¦š¦š¦š¦š¦ZLµ˜êõ,æB~=‹¹’§åòëYÌ•<,¯–ʯg1Wòb¹©S¦:H56RÎb®ä¤:Å\ÈwRÎb®ä¤:Å\ÉIu:‹¹‡©†©†©†©¦©¦©¦©S-¦ZLµšj5ÕjªÕT›©6Sm¦ÚMµ›j7ÕaªÃT‡©RÎb®ä¤:Å\ÈwRÎb®ä¤:Å\ÉIu:‹¹’›j˜j˜j˜jšjšjšêõ,¦Ì§³˜÷ïãÌv¼ï¾ž³ŸþäÇßþæ›Ï_1µo?ú§o¾ûþ‡¯lúáGŽÛðìñFêy>âxö/OÞ,Ÿz¯cDîO¼é:åÿ!)OËå¯R–WËå¯RnªÍT»©vSí¦:Lu˜ê0ÕAªç TÊIõ<*ùNªç TÊIõ˜å¿èþû›[ÙÁêé„`=nÙÁ¿‡ÄUâñ—ü+q‘¸C"""˜"˜"˜"˜"XD°ˆàuÿB~ÝÁ¿’§åòëþ•<,¯–ʯ;øWòb¹©S¦:H56Rvð¯ä¤:íà_ÈwRvð¯ä¤:íà_ÉIuÚÁ¿‡©†©†©†©¦©¦©¦©S-¦ZLµšj5ÕjªÕT›©6Sm¦ÚMµ›j7ÕaªÃT‡©Rvð¯ä¤:íà_ÈwRvð¯ä¤:íà_ÉIuÚÁ¿’›j˜j˜j˜jšjšjšêu?¼œžvðߟ;ròâÿñ»}œƒ†úxéþž½ÞÁ{duÿíÁù¼ƒ!”O;øòby§|ÚÁ¿§åòiÿBnªÅT‹©VS­¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê ÕyÿBNªóþ×ùNªóþ…œTçü¯óƒTçü ¹©†©†©†©¦©¦©¦©¦©S-¦:íàO;øò´¼Q>íà_ÈÃòjù |ÚÁ¿ËMu˜ê0ÕAª±‘꼃!'Õyÿë|'ÕyÿBNªóþ…œTçü¯ó0Õ0Õ0Õ0Õ4Õ4Õ4ÕbªÅT‹©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕAªóþ…œTçü¯óTçü 9©Î;ørRwð/䦦¦¦š¦š¦š¦:íà‡Ùἃÿöà}œyîàü–9g ;øã6<»î࿽ÅÕü·ïCºNù´ƒ!OËåÓþ…<,¯–ʧü ¹©6Sí¦ÚMµ›ê0ÕaªÃT©Î;ørRwð¿ÎwRwð/ä¤:ïà_ÈIuÞÁ¿›j˜j˜j˜jšjšjšj1ÕbªÅT‹©VS­¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê ÕyÿBNªóþ×ùNªóþ…œTçü¯óƒTçü ¹©†©†©†©¦©¦©¦©¦©S-¦ZLµšj5ÕjªÍT›©6Sm¦ÚMµ›j7ÕaªÃT©Î;ørRwð/ä¤:ïà_ÈIuÞÁÿ:?HuÞÁ¿›j˜j˜j˜j˜jšªÍ–æü0Úwðß|þE„=?dK;øoO­íà¿=vL;ø_çÓþ…<-o”O;øò°¼Z>(Ÿvð/ä¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê ÕyÿBNªóþ×ùNªóþ…œTçü¯óƒTçü ¹©†©†©†©¦©¦©¦©¦©S-¦:íàO;øò´¼Q>íà_ÈÃòjù |ÚÁ¿ËMu˜ê0ÕAª±‘꼃!'Õyÿë|'ÕyÿBNªóþ…œTçü¯ó0Õ0Õ0Õ0Õ4Õ4Õ4ÕbªÅT‹©VS­¦ZMµšj3ÕfªÍT»©vSí¦:Lu˜ê0ÕAªóþ…œTçü¯óTçü 9©Î;ørRwð/䦦¦¦š¦š¦š¦zÝÁ¿<|›wðß{>|üº3ØÁ{vuÿíÁgÓ2Ê«åƒòiÿB^,ï”O;øò´¼QÞMµ›j7ÕnªÃT‡©Rwð/ä¤:ïàï¤:ïà_ÈIuÞÁÿ:?HuÞÁ¿›j˜j˜j˜jšjšjšjšj1ÕbªÓþ×ù´ƒ!OËåÓþ…<,¯–ʧü y±ÜT‡©S¤©Î;ørRwð¿ÎwRwð/ä¤:ïà_ÈIuÞÁÿ:S S S SMSMSMS-¦ZLµ˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¤:ïà_ÈIuÞÁÿ:ßIuÞÁ¿“꼃!'ÕyÿBnªaªaªaªiªiªiªÓ~JÍ;øo>˜ÅãÓÎþY;øïoneÿý©§‚õ¸AüeÿJW‰Ä_vð¯ÄEâqˆ`ˆ`ˆ`Š`Š`Š`Š`Á"‚×ü ùuÿJž–7ʯ;øWò°¼Z>(¿îà_É‹å¦:Lu˜ê ÕiÿJNªÓþ•œT§ü+9©N;øòƒT§ü+¹©†©†©†©†©¦©¦©¦©S-¦ZLµšj5ÕjªÕT›©6Sm¦ÚMµ›j7ÕaªÃT‡©Rvð¯ä¤:íà_ÈwRvð¯ä¤:íà_ÉIuÚÁ¿’›j˜j˜j˜jšjšjšêu?¼œžvðߟ;òxòâÿàü÷Gwðßüø‘O;øWòAùuÿJ^,ï”_wð¯äiy£üºƒ%7ÕbªÅT«©VS­¦ÚLµ™j3ÕnªÝT»©vS¦:Luê´ƒ%'ÕiÿB¾“ê´ƒ%'ÕiÿB~ê´ƒ%7Õ0Õ0Õ0Õ4Õ4Õ4Õ4ÕbªÅT¯;øòëþ•<-o”_wð¯äayµ|P~ÝÁ¿’ËMu˜ê0ÕAªÓþ•œT§ü+9©N;øWrRvð/ä©N;øWrS S S S SMSMSMS-¦ZLµ˜j5ÕjªÕT«©6Sm¦ÚLµ›j7ÕnªÃT‡©S¤:íà_ÉIuÚÁ¿ï¤:íà_ÉIuÚÁ¿’“ê´ƒ%7Õ0Õ0Õ0Õ4Õ4Õ4Õë~™N;øïÞÇ™íxü{óãÒ°¿þîg?ÿÅ7ŸýS-ç8óünüð.݇™_¹±ÇêxòØmÈðø•Ky§üñ+—ò´¼Q~êH–WËÇ£xè¶xö ñl*Ly±¼Sþø•KyZÞ(/›åayµÜT«©VS­¦ÚLµ™j3ÕnªÝT»©vS¦:Luê9¦œTÏ©°ä;©žSaÊIõœ K~ê9¦ÜTÃTÃTÃTÓTÓTÓTÓT‹©S-¦ZMµšj5ÕfªÍT›©6Sí¦ÚMµ›ê0ÕaªƒTÏ©0å¤zN…)'Õs*L9©žSaÉR=§Â”›j˜j˜j˜j˜jšjšjšj1ÕbªÅT«©VS­¦ZMµ™j3ÕfªÝT»©vS¦:Lu˜ê Õs*L9©æFªçT˜rR=§Â’¤zN…)'Õ´ÙRÚl)m¶”6[J›-¥Í–ÒfKŸ§ÂÛ¶GÊö}&ç$0òÉcÏ¿Ä5ÿ˜ ÷§–.DÜ{6”üz!b%OËå× +yX^-”_/D¬ä¦ZMµ™j3ÕfªÝT»©vSí¦:Lu˜ê ÕéBÄJNªÓ…ˆ…|'ÕéBÄJNªÓ…ˆ…ü ÕéBÄJnªaªaªaªiªiªiªiªÅT‹©^/D,ä× +yZÞ(¿^ˆXÉÃòjù üz!b%/–›ê0ÕaªƒT§ +9©N"VrR.D¬ä¤:]ˆXÈR.D¬ä¦¦¦¦¦š¦š¦š¦ZLµ˜j1ÕjªÕT«©VSm¦ÚLµ™j7ÕnªÝT‡©S¦:Huº±’“êt!b!ßIuº±’“êt!b%'ÕéBÄJnªaªaªaªiªiªiª— ë÷éBÄý±çÁòq/Þçào?ïÕÛίEý¯ß|÷ý·¿þÕmBx~÷pÖÇ;¹µ'oçòžÌ‡JÉmÛzyòà³ùåiy£¼o–‡åÕòAù8,/–“ê9¢œTÏùä;©žó!ÊIõœI~ê9¢ÜTÃTÃTÃTÓTÓTÓTÓT‹©S-§jŒ^žýàÙxHꤺIÝ6ªƒêJõºTªÉrå Ë!–çDHj±<çAR‹å9 ’Z,ÏYÔ‡Xž“ ©É2È2È2È2È2É2É2ɲe!ËB–•,+YV²¬dÙȲ‘e#ËN–,;Y²d9Èrˆå9ï‘Z,ÏiÔ»Xž³©ÅòœôH-–çœGj² ² ² ²L²L²L²<·ßʶeï4:9G<Û¾¹?yðùˆ§~Ü~¸~ôþìâÐûƒ·yÁõèJ^-”_€®äÅòNùõèJž–7Ê»©vSí¦ÚMu˜ê0ÕAªÓЕœT§#  ùNªÓЕœT§#  ùAªÓЕÜTÃTÃTÃTÓTÓTÓTÓT‹©S½]ȯG@Wò´¼Q~=º’‡åÕòAùõèJ^,7ÕaªÃT©NG@WrRŽ€®ä¤:]ÉIu:º¤:]ÉM5L5L5L5L5M5M5Mµ˜j1ÕbªÕT«©VS­¦ÚLµ™j3ÕnªÝT»©S¦:Luêtt%'ÕéèB¾“êtt%'ÕéèJNªÓЕÜTÃTÃTÃTÓTÓTÓT¯G@e(5½?øx ôd`Ö?î×ûç½½¹¥# ·§žNÖãñåèBW‰Ä—#  q‘¸C"""˜"˜"˜"˜"XD°ˆàtôu>]ÈÓòFùtt!Ë«åƒòéèB^,7ÕaªÃT©ÎG@rR€.ä¤:]ÈIu>ú:?Hu>º›j˜j˜j˜j˜jšjšjšj1ÕbªÅT«©VS­¦ZMµ™j3ÕfªÝT»©vS¦:Lu˜ê ÕùèBNªóÐ×ùNªóÐ…œTç#  9©ÎG@rS S S SMSMSMSŽ€®¿œž€Þž{þâ|\¤ôúèí‘Õ# ·?~äóÐ…|P‡åÅòNùtt!OËåÓÐ…ÜT‹©S­¦ZMµšj3ÕfªÍT»©vSí¦ÚMu˜ê0ÕAªóÐ…œTç# ¯óTç#  9©ÎG@_ç©ÎG@rS S S SMSMSMSMS-¦ZLu:ú:ŸŽ€.äiy£|:º‡åÕòAùtt!/–›ê0ÕaªƒTç#  9©ÎG@rR€.ä¤:}¤:]ÈM5L5L5L5L5M5M5Mµ˜j1ÕbªÕT«©VS­¦ÚLµ™j3ÕnªÝT»©S¦:Luê|t!'Õùèë|'ÕùèBNªóÐ…œTç#  ¹©†©†©†©¦©¦©¦©NG@av8½=xgf|ú\õW¿øõ÷ßÿì»ß~hßm× [yòÐçw*?ÕÛ;õø}jfìÏžûø±?~›’:¨®T©Ïs§”Ë;åߣ(OËIô> endobj 2146 0 obj 10511 endobj 361 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 720.0 null] >> endobj 364 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 690.141 null] >> endobj 367 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 610.85 null] >> endobj 370 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 283.519 null] >> endobj 373 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 249.432 null] >> endobj 376 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 186.288 null] >> endobj 379 0 obj << /Type /Action /S /GoTo /D [2147 0 R /XYZ 72.0 123.144 null] >> endobj 2148 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 219.501 null] >> endobj 2149 0 obj << /Type /Annot /Subtype /Link /Rect [ 277.692 636.47 295.472 645.35 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2148 0 R /H /I >> endobj 2151 0 obj << /Type /Annot /Subtype /Link /Rect [ 277.692 636.47 295.472 645.35 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2148 0 R /H /I >> endobj 2152 0 obj << /URI (http://cclan.sourceforge.net) /S /URI >> endobj 2153 0 obj << /Type /Annot /Subtype /Link /Rect [ 476.444 199.908 508.124 208.788 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2152 0 R /H /I >> endobj 2154 0 obj << /Type /Annot /Subtype /Link /Rect [ 516.1 199.788 540.0 208.788 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2152 0 R /H /I >> endobj 2155 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 187.788 205.52 196.788 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2152 0 R /H /I >> endobj 2156 0 obj << /URI (http://uffi.kpe.io/) /S /URI >> endobj 2157 0 obj << /Type /Annot /Subtype /Link /Rect [ 173.559 136.764 196.329 145.644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2156 0 R /H /I >> endobj 2158 0 obj << /Type /Annot /Subtype /Link /Rect [ 202.823 136.644 271.163 145.644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2156 0 R /H /I >> endobj 2159 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 364.901 null] >> endobj 2160 0 obj << /Type /Annot /Subtype /Link /Rect [ 414.009 136.764 429.559 145.644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2159 0 R /H /I >> endobj 2161 0 obj << /Type /Annot /Subtype /Link /Rect [ 414.009 136.764 429.559 145.644 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2159 0 R /H /I >> endobj 2162 0 obj << /URI (http://files.kpe.io/md5/) /S /URI >> endobj 2163 0 obj << /Type /Annot /Subtype /Link /Rect [ 338.57 73.5 356.35 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2162 0 R /H /I >> endobj 2164 0 obj << /Type /Annot /Subtype /Link /Rect [ 362.18 73.5 453.86 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2162 0 R /H /I >> endobj 2165 0 obj << /Length 2166 0 R /Filter /FlateDecode >> stream xœÅËvÛ6v¯¯À®Î91‚'Ù¹N=ã»uçt‘dAQ”…†"’Jª~ý\$‘ Ù¤IÎ.x/îûäËŠ"/õO3”îW_º=ŠB†xÐmÉQ™D{Ô­%Ê5–³`ý ~ ,vèU±"è_«Ÿàã ø¶"ããZâw«·ý…üpþ®œ²D-Cë•Ö/ þ…¸uÎÙ)ÈùÇqþÝmr³;†·þ”w–î~ fiô1¿³z«ñÛ±ÓðÇ1'èiõóãêÕD” Ç­óPb½‡#ë? =îч úâzüÏê—ljû°Í&nÔ¼m8bG­ègJÄ(fQH £Ñõ.94Y…(F·ES•›cÚ¨²0z¶'BzŸ#ÇDn{Ìñ:”uÖ“csŠE‹8sÞ³¾{÷ö®§˜: „:RôP"  UÛub—×å~_¾SõÁ!*@åm’fv«)ízV F$bFå¡–´aŒc%X™SG¢‹MÒ$ë¤Îjl÷®ì²8î×à¬.·v}¦²+šD»·¶’bc¤v}ó©n-‰„ja…´[I•Y >eÕdl÷wÂSVdU’;MqwtéTk×ó "ˆsJ(ƒ©ÐËÆb ISF§´–¹rÔÔZo »n\/ÎŒvHÒÏÉ“ƒ³>MíN!ÀÎåÐ^ü£¬>×è®ÙàgÒ’ò“˜CÒð®`ý[ÕMYf ypTvHlˆŒ¯h€é‚é –tmž#–Mmƒ˜ÄÇ~à}¨Ê?³´àoI=¬ë&Ñ6ÀëÓ°üoöUt‡åïP¡ ÈŸ§aÇÁÓY=m5è™``ãT³NÒ4«­L¥=mÌ7l@D\zü²‘ò] sêV-yRØ|8Öªx²`‰˜õ…ðgDÇJÌ=r¼¿¹¹]¨fÇ!ÐBß™’Zæ¹ZWIuÂvçÑ•MªQ¦ ˜´Ü8Ÿ»;`È<ÖÇ5D@¡Éó“Ýv÷ ²ªrŽû{쉑ð÷‰ú©e+9ºÈþJ³<‹÷óÖ¤ëCâH ÿ©Kù@$„=[O©{î] Á=|[ô« ¢`! \§",—}Â0cÝ;¥˜Û©t7@]p|*WÍÉÒ¨fçUwŸüYVVùaÈ•îŒ+‡wÜdµ¡’FÁÝLe{¨/¡ür}u’½ßgÜ7ÁûíШ½úêL^&Ý’a†ÕW'Ùuìla¿ýËC Ûh«²|ãÃ(õ-MlI„)ÞÕf£´bÐTû!­¡kdŦ~~{óóõKte~ €4¯YUb­„£MîŽA}‚±9’tÑ>S¼+tîú<9atñ1!]²TmUŠôàã,B Ó¦)&Kœ'x÷GˆGˆDðNU®uSèÉM3×ÁvÒù¬-u ¦BI^‚÷ÚìM!Pš+= ô…µ› }r±.AàÊåœàÝö"öLú@Ò¾QLS\_ß]ý:?œ øp3X´ã‡qÖµtÈM wMsxýêÕ4Ó$'#Ôr£Àuy„‰ÒîEÖŒ)çXêÁ@°Ðsħ z0¤Ãj\ºR§²½º³¡,eˆƒ8ŠCÑ÷aw†ñ†r“ Œ´¡èûÃÿÊZí‚ ÀÂF²æ'0B!÷"ýxJ=ç-N`”ÁÐÁôË ÷éa¹£rý” ÓJD¤‡° ‡ãv«ðçC†U9 p¦ ¼œÇÖ£¢€ ÆM“%ßa=%ÜG‚Ðsî Ü1ÕSaϹ9¦à;·ýÛïü¥.q’JBáB¶(ûÇy1¹`˜í¨ öɹàcÝÆñÆêÇVSÍÚ¾SuÎT·sõë»[OÆÇ|œfÈn‡ëÑ£~¾·в"#E(»ÞrÿF.åc•Šs8(ü¾K¥›SÚŸjt(ëæ©Êê/ùe]ÂðÛ ûàß&i÷4Ô½õŒ"l%õÿ„œyŽßoÆcG{èŠÙ3²Wß›Lëâw™¸…>W÷©<ÇéÈ#joåÓSÆéÈ#}+n[Ïfh_nŽy?s·ÿ»õvõ? ÜåL endstream endobj 2150 0 obj [ 2149 0 R 2151 0 R 2153 0 R 2154 0 R 2155 0 R 2157 0 R 2158 0 R 2160 0 R 2161 0 R 2163 0 R 2164 0 R ] endobj 2147 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2150 0 R /Contents 2165 0 R >> endobj 2166 0 obj 2183 endobj 950 0 obj << /Type /Action /S /GoTo /D [2167 0 R /XYZ 72.0 720.0 null] >> endobj 2168 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 560.768 250.77 569.648 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2170 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 560.768 250.77 569.648 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2171 0 obj << /Length 2172 0 R /Filter /FlateDecode >> stream xœÅW[oÛ6~ׯ8ÈC‘³FR¼Hà.î°b ÐÚÛš"P,ÚV+KŽ$7ñ¿ß¡Dù"ÓNÓ‡Ì ZäÇïœï\Hß{þ ÌCE ¦KïÞ¾£ Ò¾(÷™€%ر€Ì¬Ú°n„vð¯—{~÷>}ÆÉ<Òß®½{üf†¼8ÿ¾eÿ‹Ɔ&*M\þ+¿ ÎÁ„àäpf/pÛ÷»· aоÃ7-·™Ê¬ÒöÙÒ[ÚçI?ÈÎ âÖÑzøräæÞÛ‰÷ó;”Àd¶Ëse€”ø!‹Ì‡Ád Ÿ.) _†É{o49J€Ví(†{ëOBè[Mp•uªõé:^êÖ)‡ <ùD ³>l“_ÿ6œŒWÃÉðíp<‚¾QI|!·àÑ1ü†1Õ¨s¸*‹ÄYu|—éê'ø–ê|¤y¢uqž@¥ï×:Ÿâ·4‡’ׯ•ö;Ï”Ã3N}$’-Ñ»u>­Ó"ï0§E”‘/hEŠZÇ›¼Ž;`ä £DøB2…Alýj>=)BîXY—hY\ëAçV_¿PºöõUo ³ -êÅs )¾0E\d¿ü OëFƒÀJ®ºŠ–óõRçuÅâl­«Ó&…òiÈ‘(•Óâ£$¦D:`í½ò@…¯˜±ßHt’Š»/zZŸæU¡¯nÙrlãÃd‘Vðbf'z¯³êê…†oF(fðÆNl#ÿÆÿ•Ca¨°€¤Íì+]MËtµŸÜÎR'X{”¢„²Àç–Þ™tã/˜Uã˜éÉ(²ˆbÑ¡S:|Œ‡‡E:]tBVFÉÊ쌹ØÚ=ÆËU¶KKWu3ÅüPI´‡tmî2K«zÐêvóºW±òKèæò¢Þ¬ôm»€öË]:Oó¿i´£Øh31-–«8ßà(N’ÒÌÅ·_Š4Ç.¿pFÒm£ ¦ ÐidgÉêëΖfl¬Ás/FÜüMN9A_Õ–=ÓyšW·ó²X¯ÜT¼¯­¥Úæª%úµt³¢0²Æ¥›Kö%º9nØN`Ø×cÛC–EÏN-N©uýÇŸŽ•ôù9Á™#'Ü»óçFœ GÄÝ{Ë 1WŽ»÷û^îŸ×ç:ˆ0šr…<´íwœ&F³Õ¹þ‹7u_*©PØãñ¯"Ig)¦vnì¶¥†eŒ{ÙcbA*³MšÏ/> endobj 2172 0 obj 1061 endobj 964 0 obj << /Type /Action /S /GoTo /D [2173 0 R /XYZ 72.0 720.0 null] >> endobj 2174 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 515.237 250.77 524.117 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2176 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 515.237 250.77 524.117 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2177 0 obj << /Length 2178 0 R /Filter /FlateDecode >> stream xœÅYYoÛF~ׯXø¡ ‹Ý“G€P\§q¤M¢¦¶hie±¥H…¢|üûÎ?feüPFa /ô}ÖýëØrÇIe¥œj§_÷²Hä® Yä”P)êt4¢Ø%H‹´‚2 úáoù8&)Àªøéž(†ýo³G']`ƒEñnØ$æ»”C¯^£§ƒ€0HrÊ.†nVÜî72+w(ΖèKœî+G¹TVA!BÏç "¹<ÐË@¢`éÑÌЂ² ÛBî@5‰Qe½IS4ìXŸx”A"`ÊüçƒúP?#Dy^.å*Þ§¥7Dˆ=€?ŠØ3D#Ñ#Ö”¨øèÁ„ÀAðáâý°&ƒUºß­Ç ˜z»8àܼÎhè“Íj›ü¾M ¨ eJG¢üæ/¹(‡å¡À†ÓÀÁÆCóu²C÷Iš"ë|Tæúº¾S)¡.ë»1­džxO'e¦˜€\ÌŒ¨ŸånQ$Ûv¤8«–ûÚÖ:FSUª_(íªqUTª9è[ ›òRB™©'I¶Ê‹M¬ôi¨3§S®ªÙn+É*‘Ëzåæ±ŽÜz{n ˆE#ÇïŽÑ¶LzŽó0*M(q0{2’¹*ÅÃôµ÷ëd±î”>å_¸†‰ ¬¹½‰mxiÿB÷Æï¼;¢¯Ù¶Rõ%8T×Ï2o¬þ]IÈu£@ måMà˜I+<ÍÂ\ÇwI¾/ÜÖÆË|[¶ ¼X5㤠‘ÉÎfo×¥ßÙ€çD ÔBV _Èœc„¶g—Qþvjâ{Q“œvÚIÏjuךèVkÙZ¸_ËBÆí#ɪ=)Û[5‚.ÖÃå²GpÕ†«û´gØXÍaT#¤m(ÆÖô¿A+ËK‡k"ÒQÀªC::Íx8߀áP¨OLŸH7/³#Ô|c›BÝÌ+ÐÌ,†‚VOäC²+mÚÃ>Ëö½jñ€w3Ñ5S }@, P{(‰ÂaâøõÏñ­žBnò;¹ó¨ƒûÂi˘¿Õ;Bì2eäÝ”Aì¸Ø W;†£¯8KKYdpcÜÉôñ´å––ÆZ0î‰Pwü›áát”ØOõ^wê4Ú­æUãª&®z'¨Úý¶^hBÜÌ»ã°Õëñ‰ãûÈÔJ9iŽ™L±ê8µ &w즹ìFªvn“ÖLꬵ„,X·&WÖZ#×Ð[@E7Ü,@­ER¦h'Ëg¼1?ô0ö£0ö•èü!ÞlÓæ»ƒë[ÇÐM È\}÷»zòàµlÉòê¸o ‡Nà׫×hî8GÞÌtV¥‡.Wy~í ã¸C‡~?^£Ëdy’¬”·²p*)è(„€ÇZ&·ëò­Ò> endobj 2178 0 obj 1792 endobj 985 0 obj << /Type /Action /S /GoTo /D [2179 0 R /XYZ 72.0 720.0 null] >> endobj 2180 0 obj << /Type /Annot /Subtype /Link /Rect [ 199.72 439.676 262.77 448.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2182 0 obj << /Type /Annot /Subtype /Link /Rect [ 199.72 439.676 262.77 448.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2183 0 obj << /Length 2184 0 R /Filter /FlateDecode >> stream xœÅkoܸñûþ "Úøóø%CÝ^îàÃ!Eb£Ea…¼«õªÕJIÇÿ¾C‘zs©õ—Ô °3”æ=œr÷ËŠ"ÿ.õG¨ZïW_ìE!C\Ú¥@"*0 ÐY8@™~k°‚ó;ôÏU¾"è·ÕÝ<Ü Ï+2e×߬> äë'ä»ËjÀ)û¿h uh¢ÒÄ…Áÿ7Á=?®[ïWܬÁŠ‘­eÖÓöÓ(b@cùÏCMH Ž˜Ò ÝîÑÝ[ÊÄźý}õáv–ßÙk³@jÙ=QlD¡#³šà†Ö(cÓÇxŸ£nb è÷#CpýñæÃçÛËÏþö÷Ï¿Ü CÛQP.°ð¶TÁœöž±pJ |è:¯’²Fõñ%*¶h×1Jóº@q?ÆU‚à#KpkFè0CPLÑb ã_ùºN‹¼¥9í1©p@#¥Bj=vó’×ñ·–P9„Qà@(B¸•†š¿‰å‘˜¿˜6æ^–ɺ(7ÕÔUÒÅúOÿM^P« è2Q‡§˜º8ic.1 Ü!!®ë2}<ÖIuZŽrÐyäpBæï³£G‡÷^%C0‡-_/qZz¤(‡f>)ʡ՗cR¾œÎ*ö:CwÒîOîº yÿ3ZÞ&”s,#Ø'AKwU>÷I^W(Î7è£@9†¤  ‹ažÎŠ¥.’+t9z[AæOï:ôeÿXd-V”ãõtÝâ7ŸþhÁäÛ¡Lª ªD»R&zlÎíZ½KZ0‡ZÚIضPܽ©«TÏ<­4›é×FAÉ™úÁjÊ"ÌB]3Cí4ès?†ÒGý1S " ¢“;ß¹áÊÀ%ºÆw,PºÑÎÞ¦I Å¿D§k‰`XAÎÈ\ëלT†I‚¬ãR¿ùŒrLT&J]õÈiùŒÆe¸áã·†·ÎæS¯É"ðP.X >⺑BÙw–G·Ñ32¸l€Æ~/D†²E(4w‡Ÿ8á>Ò?AHˆŒ„£€»0£¹B ”¯±¤È*9çæ9d‹‡tÁØP—®"±s« u‘]u¶Éy qÈtgaÌ#ÿIÖõi¹Šà,#‚…6ÝîÒ =§Y†6É6>f0\Hq“q?Ø—­ÌðrÿãDb!zô¼K×»6x•ŽÞÉ€ü0L%…ÝZN·»¤ÔýòºtnÓ¯ü¿T-Ü´ô2!x1S@³b¦€´¥Ûbf¢‡`u8(lá$C,\ϸ…¯sÛ-TºE<³¥äÐÎlQ›Û¼ÐŸ ú¨[ñëŽ@`Yç¼hJzç.G¤p*¤§"F±‹‹6¾ëq=Gvˆ Š$ÔÁ•Câ9Jäåðî,-”€‚ ‡Ù(.-–º¦i<ô¯ö “ð‚„Z¨à(1ççï^Ly‰Ê4Ûh¢ÌüÀ}LR Ý( vÞ¦ mÂCŠ{éM¡ï°uœ÷Èã@Éc• ü÷¼KïM“¬sä4ÌÏc%ªã᥆-ÔBØ»ö¼¡á8Ëz¸KÅn)Í;Г[KÊ¡P’:äûM00yhq'þº×¤=ãh¸‚®”oÞ¡%Qu2—tÆ>äDsP0ˆÀÁ¡wZ￸ƒl-2ˆ=Žip]dÇ}o›>´Uç˜#h€£ °µq¦ÌBeÐ=ÔNS¹…iL#LŽI{&¥ƒBl1k=µ'‹ÛòaOÊÁ( sNr¨±\ΘôÑ¿Z&`„e00ârËB9 5± ½Ê˜r6VÆq“=W‚m‚ ;o9£ÔGŠ{év;Ò~,è´´ûqÁg0ÍáH¯"rùìŒ )˜—ÃYZ&+h®Š¹x,í£AÐ§š›œ‘‘¿ÊK¦ë‘‹‡?c”´—móe¬È,_¨þ‡‚X:Øùò*7J¨Þ0{59Ï%4à˜ðÀLúÇ.nkB}ô½ ¦®µº à¶RÔT*ß÷Ù/6éqÑ/4úá¿0·ûÄ ÛâXÖ»wçxE@ßÞC(WÌaÕRŠ á£>O¡úMâŒË¼9:×ý± ]$ ˆ–mø´žJŸz!#éàuΤhú&‚q¯6ÍÆk3ßW!ÃR‚·¨p©ãÝWŠøH_é}OCu§gÂeÕBsâ^âN|³£¬V4¸Î6 æ>ÛÀ殩ÅF×Û–ešSv‹™dE$Y²†­#Ùt7³V³õ#…õexV=Ö\‚÷¨™} ì)Y< ö˜C¤ø•ÌG‹­|Ñ–Û2bmº­w=ºOê]aÚ¯Yð_ŒÀiº§¤á UzP `ÀõÀŦò/¹QŸÁe„ÒåŠÅÊσÐG?ЧLz$O³Wk*H8¨…sMÏ[€ŽÏNIMZ¬½À°`Û fú‘ûƒƒÁ›“À‡±Æ ¾Ašà. fJ-”â£í¥Ÿ0mø]—Y±ßv¤-ýeÖÚª`Ñ2©e>Ö. n¾mä¨b:ö÷›¶zœqû*` çÑŠËÀpùð-Þëß ø¾§‡"€9ÈfLYª{[ÝÐ]sÝv©Cü€î²¸‡“}œfÓ/ó57ÈÌ17dÿ~Ú–Å^S²â%I´Ì´ÏÍ-åÝ{CŸn`|tŠGžŸ&ÙæÒ¤+lÀû µ$ê÷?£®aŽÞ çNÿlýÔ\rööº´N9«Ózp9òçû·ÆxôTÇ|6áùwó…«ŽšÐ¸„©SÞuÿûCœ¿€œ}œÇOI™n\N“ä”Ë;#솨þ9Ö›Ëô zó[ü—iГþR_Ó¤ÆEùôÆadÓðœÖäÜ_8ÕåÓÈußì^ÓмvW4?ú´úRÕý— endstream endobj 2181 0 obj [ 2180 0 R 2182 0 R ] endobj 2179 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2181 0 R /Contents 2183 0 R >> endobj 2184 0 obj 2290 endobj 977 0 obj << /Type /Action /S /GoTo /D [2185 0 R /XYZ 72.0 720.0 null] >> endobj 2186 0 obj << /Type /Annot /Subtype /Link /Rect [ 199.72 439.676 262.77 448.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2188 0 obj << /Type /Annot /Subtype /Link /Rect [ 199.72 439.676 262.77 448.556 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2189 0 obj << /Length 2190 0 R /Filter /FlateDecode >> stream xœÅYmoÛ6þî_AäÖ Ç7QÒ€ËÖ´èPtkãvâ`Pl9Ö&Ë®$7ɿߑԋ-Q”ƒ]:ÀGJϽóî¨}™PDàß¹úñC†æëÉ—j"Ÿ!.«-O"*0óÐU´‡RõÖÁj ~ÌK@¬Ð“lBЛÉõ <\ €û é²Óà«É‡=ùê ùæò÷5à”ý/(tTt\üçcœƒž ‡Oö×ì·»Z 7{°cd«Giåéê×(bHcù´ƒ´f»+ ¿p‚î&?O'?¼ö%hºlóÜW@JpÀBõÇÐt®O)“g7húëärÚK€oìµ^ •ìÆŽ(6 „гtpýÊ(cÓûh£,nb!&ÒSïðé÷WÓËó—¿üöñÕ2ØAyˆy ^ça;cÌï„ €>mQ¨\Åèk”î€Ü,Qüe’Ý¡<žoòEk |‹‚bà) Ï×»l^&›¬Æ ;K†Ø£ ›O+g]=feôPC‹0J<ì‰^ICú¯ct ú/î´¥ç•E]/IëZP££ õ-Êè6•gÄAßý?"‡ &d•ežÜî nƒÒ8±àrôë¾obX†5žÅÑ×óm”äÃR±hæ"ˆE«ûUœ‡Fð§"„ÅÈ®è6*RB›!/^¢ñƒB9Ç2€“âÕ¸‹ün·Ž³²@Q¶@ŸeQìóü‹ƒtí•&Jm˜ t9:- ³»çÍòq}»IëÕ&?ÜOæõúêûšŒ¶y\P(êxüäyÔ…G÷«d¾ª“¿PÙ?˜ðþ’SI¡zù§©Š£š/ "BfîÑå*ÛÕ}ôX4 3§hÒ§J¿ØÂšÄ®mÒ\\šåÒLWšŽ#°­^ä›{Ü,ÞfV)K(øåóféHjîÛ\„!$¦Å#XÀÕÞnäÏ7pßK²Ö쨡Tû²„¦©C^ÚÃTî9P-´û±+âŠÒ'H?[Õ[gÕBÍцr$kÀp ®º¾'-º1œ©QÊÁá º0Iq¨¾40ióËèÜÀIèÂךäqG“þ5I¨Væsfa䜄pAq%Z71CΣ:Œ·qâÚ[Pk³ƒt°dPt=¥MdfpHwÛmšh~fÜ6CGiÚÒM¨›-`†t~8À0Aßïëâ.°Œ8Á¸‘ÿ¶UÅd{etÄlñü5™T³D††žÍe㉮²ÂÁ¡õZëÀ¨¡ôìZ/ô 7ä|“îÖ­mêFXcŽà CO€. ©ÑWf¬šZJ£õ>÷iU³ãL [pqUäÕfeЦM7PT[í5}Ü5éÈœ0Ä\À -¨°è3zÞ™ð]øZÖ®áKLBUwUÃúœœw#QP\Ë6íKQU÷2d’ëìñçö©|=›£ŽÈÝÐÅàIQƒ„Þ#4 ¹…×XæyÌ…n4q}ÛRhÙB$¥ ¿2 [©n‰fêðø–s%ê+Šêíì´s“Ÿ™«ì“ 4`ó¶æ~ù­·©ã3§ò ´&.ů¾´C1Máf†®õHu®JÑ ºN£–Ž×Q’Þt?M+nP€¹¡êïÇe¾Y+ä6Ý<ÆñMëA `õE]¿0ødqƒ¨Mºþåà_ÆB¯+=‰Ó…V¿@Y’ÎÎ,h&:è/! ³Ó“Ïi´HÖI~‚NÞÅY’Áoª~*6_“¸Ä›üîdvfåÉe‡ç¬óµ~Ï%6‹D0`QcY‚ß+UuÄþÒŸOþÜåɉU)IF˜îýÍNUà+–o¢»(û­\ý!ç[¹êB'w†ãž ºÑéy–%VVa7(Í—êý×$éúþ¿œ Ɇœ>~2$Ìë#O†CÞ:úÿS~˜ü `ó0¬ endstream endobj 2187 0 obj [ 2186 0 R 2188 0 R ] endobj 2185 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2187 0 R /Contents 2189 0 R >> endobj 2190 0 obj 1884 endobj 980 0 obj << /Type /Action /S /GoTo /D [2191 0 R /XYZ 72.0 720.0 null] >> endobj 2192 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 508.037 250.77 516.917 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2194 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 508.037 250.77 516.917 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2195 0 obj << /Length 2196 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_AäÃ3Ç7‘Ô€K·ØÐuHcl’|PlÚÑ&K‰$7õ¿ßQ¢-Y¢”t:·€(Rïî¹ãÝ1Šü›Ú‡ Zl&nŽ"Å—n*ˆ Ì´An Ä~Õ°ýõG0¸GLÒ Aï&×·°¸DOÒÝ®_M.[òí ùêòÛpÊþ ¬•W*¿0ø¯p圣…@ã•–ãóÍl%×s0S˶K‰cÚ=kEêamOý´ƒ4f?ί'œ õäÍ|òÝÛQ‚æ«&ΕR‚5 í¡ù]ŸR¦ÏnÑü—ÉlÞ €¯ÌZÏ‘VöÁŽ(8VBè‘Y•s•3ª¶éC´1µQ„F,ÄDö{].fïgóÙôãì§ß>^\¡{@P®°bV0c}ì cª ctaS”›E–/ ´Ê³ ŠÐ2*£»¨0‰Á{ý•GA1 ì(ëßnÓEgé3L• q@u*꨺ڥeôy =Â(8$0ro@õëØ¬…çËeeéÔYÚeIz7ÿæo³C{…@ŽFŒøY`Ì+hD÷Éxº7¹"}˜1!ŠøsQ0(‡S¯1¯@Ï{Ÿr†‰ÊáÎóõvcÒ²@QºD¿GÉÖÃ*Ûh¬$‡ÍEا¾wØ(‘È9:CS&°@§E™ÇéúÛÖÄns—%Í{–w×âE3suù¾y1ŸrSpš¹ÜØ9°¤4³å½i^RÈ-y«fµöP¶EÅÅñ–q:Ì[Å‚Tº®î“ ûGk¬¹‚ж~õ0çè@µe¸!v\8#!)dbÁÂÙ+¿;?³ìhÐÊ­ƒQv÷—Y”Ãr•ÆJYZ™òlƒÑü>.ÐSœ$hiVÑ6)Q™!7Ÿì!A&¯ÜÂt/ó~þ2¨%B@îÌ%ï S,òø¡¿½5K ."”2¾ÚäZØ„‚ m¬×å0QDe\¬v.Në9úõ‹;>õËññ©çÆr¤ÂRƒ‰¢´¯ÜxÔ1iÁ*Ôšù,käWµÑ¯ûáD:[Ì"^ÅfÙLÝí^b× s„ZrîÑe4½ "ǰøøEœ q-öqúìa²a¢Xµ'¦h÷O÷ñâ~Ù… íÍ—0gPˆÔÒfŸ£ÍCÒ_GÁ9a eHr—onN æE‰®Wq^”S›’oÑu5c³‰âä¶ÛuØÝl³u´r¿ï«èäC’팹õ`ƒp[0º~]ããå-d¯xEÅÇ&YVú(“›3Zó ù ðqòç6OÐÉ»hA…„ѺýXdŸbSâ,_ŸÜœy÷ ûô7b=fÌõí.H—îCëqÜ¢v™ý/>|˜äç|,D—â/ö±ºŒ~‰…ô0öáç÷ž/•?Ÿ?ˆx…QEQ¹¾>^4[­€ðb,_neŠ„šk×_üš-!],"[ gA›örÕo›.MžT%eŸ(^'‚@Ãî!q×ÎóJ5ÈÖw»Qõ4Å"¡"Œº»]–¾D¢$‡Z@*å‡Ì´0U•ྗÛÚÀ1áÚe.€Tìû’º³ «0Ï]o¶úÆj\îLóV<&‡¤Z ¦h\´>Ž× `R—1·ÜÚy¤K%Ü)¨ Ò£ùhc!Ãú5M³²y‰ÚÄ´{ãð¸y®wI_b¡JˆA…G©ç‹!Ô…|ËsmW¬ú§R ÑÁÚƒ`[§¢ŒJc¯Op—/ vZ£«|d?8tÐí¾jØ}P¬¡êKo§8£ef³SfÕ,·y À›,K 8­jfqë@—“ÏváJ endstream endobj 2193 0 obj [ 2192 0 R 2194 0 R ] endobj 2191 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2193 0 R /Contents 2195 0 R >> endobj 2196 0 obj 1404 endobj 1004 0 obj << /Type /Action /S /GoTo /D [2197 0 R /XYZ 72.0 720.0 null] >> endobj 2198 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 185.621 null] >> endobj 2199 0 obj << /Type /Annot /Subtype /Link /Rect [ 228.72 553.412 285.66 562.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2201 0 obj << /Type /Annot /Subtype /Link /Rect [ 228.72 553.412 285.66 562.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2202 0 obj << /Type /Annot /Subtype /Link /Rect [ 223.72 529.412 286.77 538.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2203 0 obj << /Type /Annot /Subtype /Link /Rect [ 223.72 529.412 286.77 538.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2204 0 obj << /Length 2205 0 R /Filter /FlateDecode >> stream xœÅXYoÛF~ׯ¤@+!»¹K mÙVŽÂ±‹mDy ©µ¥†"e’J"4ýï"iiI' ȸ×Ì7óͱ¢nþùCº ‚Õà¶Z£ pQ-Ù¨e2VPmóS­ÛðQÂÁ^¢§ƒ·ïps>ȾºBx:xÕÂÏwÈwÇo[À)û!ä6Q)âÂð_šEpîlع»Ó \½Þ¬€¼\Õ;ß +¦«giH9,ý)Ÿ~Æ ¢ç±òðû¸{ƒ_ŸØ@ x×MžË\Óanþaà­àírrô¼?ï ¾3ḵk8P ¬C¡wÜ*‚++§JŸÎý•*ÒÐ`9À\“;?7““?½‰qrñâÅøüJáZ„ÚÌ”‘…¤‡Â3Æä¾€è€É'l2~ÓWgÄ«•Íáãb, QÙ&‰Rˆbøà‡•š;W¤Æ‹šÄ%¨[”ºŸªH%Ëžl¢ [ÆÑN¶›=áš6u\WÒŠ½é6ÊüO;AWJ‰4ÎP™ä•KÅgÇÒœT¥ïFåô>qR';cД=k¨C4émh¨OëD¥i‹ƒW˜Ð¢ýü^m{ 9ÑAÎýÌ¿òSÕ ÆõÄýþîåŠMˆåT94Nn6+e)ä™óW‘(Ý&çл5—®kq§¤ƒz¡Ó£Úlq a SæNR¦E\ø\F¹)jáBh´@¶ð3,–\OÅCQLiæg*g¦*§Ë0¬jJSRzªgl?¸z’ÄÆ}ÑG€_ý­‚¬‡$ì}ÕXLjÔ˜à-–iÉÁ\]û›0ƒ,FêTIÄ×ð°Ú0v˜Íû’QÇtó¾#9-¡NU$ËuÖÒ¼õZ¶É¤E#»Þ[6„ŽðˆÄ g˜›WOò˜Ö“]§¬zƒ°Mnq$¿Š¢~aò3ËíÓò¨±¤Ì¶zºò·Íäªåß Óíê*±YëmÌkÖâD¯)K–ÑÍ^/ÍÙ¶1~’»Žpªë¾.<ŸË[Ü´PU´m&•å¤)§æðÚOZÓë$^µ6›áíF%ÛGͼô£W!®06ëu¸Tóf¥§ù2a jÊ…Ô¸wo¡riõÉ7&Ôñ,§U‘¤-âfŒ5dhØÇ«õ®úÿQh®‹}B¸Ž+í]½ø«uØt{ÝÍñ¾ ˜¨Ä±­ö 0Û¿€áA(Œ1 M¡õcÆ7x0[® ?™ 9™=*¶ª‰ ³£³£C¯¹M:°ë«îÎq È3Õص¦º]¬âñ׋%ÚäA^²X[uÿé·“3,)ãåÅÔ{z9Áᨧco|<žNàË!ÇìXœþûøÙ¢]œ"2`Ï­+õ›xiÐëCŸ$ ¶¥óçg#˜\^^\ŽüUiÁ¨OTèç—ø!nÍ·hï2ÍR ïJˆmá§Á&IÔÜÔH[_RËî é¥Âî—d©ŽÙ2‚·ãã‹Kï*)¾z`·ðâµq†|„:³Š5ÇÝŽNÕÕæ&/Ÿl»Vð ®1: ®u`“¯¢ _L‚·¡t?8>$úèóløòŸOÆSÏx1ñž]œÂ.åý·®ÙÐMiäiùYc 'ݶ`Õm¢Mªæ†ŸÜh ʶØ7ÛÖ=ÂþæÅ×¥Aˆ¯Ò  ì‰Å4Þ$–ßlX”$üÒ&Ô(×Fu謹ɛ—HþôùÅ9˜¦©…u{h'ø¢(‚÷m‡ˆ¦ÅÏ“x½×¸´½[°. µ×Œàz¶Z¿}¼üT0¤ù endstream endobj 2200 0 obj [ 2199 0 R 2201 0 R 2202 0 R 2203 0 R ] endobj 2197 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2200 0 R /Contents 2204 0 R >> endobj 2205 0 obj 1354 endobj 998 0 obj << /Type /Action /S /GoTo /D [2206 0 R /XYZ 72.0 720.0 null] >> endobj 2207 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 560.759 298.498 569.639 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2209 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 560.759 298.498 569.639 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2210 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 527.208 298.77 536.088 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2211 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 527.208 298.77 536.088 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2212 0 obj << /Type /Action /S /GoTo /D [2027 0 R /XYZ 72.0 386.781 null] >> endobj 2213 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 484.106 309.6 492.986 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2214 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 484.106 309.6 492.986 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2215 0 obj << /Length 2216 0 R /Filter /FlateDecode >> stream xœÅ]Û¸ñÝ¿‚Oíæ°ËŠÔ'S´@®MWW¤ÙöP\îA¶éµZYr$ù6ûï;äð˭쾤›ž!9Ÿg¨Ï+Føw§~JÁÉæ°úlÆ)9I 3”„e”çä@ œ“V­ n!øÁEìÉÏ«n•V¿ü “[’Áã*¹d§‰?®>òÕLòÍ凤Œÿ_4P:è]ÑûÂáIõæœMäYr>lœ÷£Z`Šc0‚²ÕTkH4*↬"\ФÈÕú >üóí?þMÄ-¬2*2dzlNñ‰óòb½XZOÞ~‘›Ó$IݑޓÏ'9<²%ƒœNCG¦½$ÓéØÊ‘ÔðŸ´Í8QkD1"c4 H(P²“C³!ïNÝfjúÎÒ^÷[!hÎ*!Jfüöñ©›ê/–PD„²$§i•&IÊSc˜þ›¹.²R›|±±ØJbU.t`<¹ÆúN~9rÛg&pVÄäýî¿òiA(Ïy„j[OõºåUa°øeÆ¥IL;°éÔNwÓÓQŽ×e•ÑÍYÝ£][OÇëðÒÝÊ¢»µkd»½ëà^·'«¢õ§?tÇ×£›¥)MóBˆ¬0Ôo†‡ÓAvÓ¨ÏÝ¿êöäˆèÍKÊÔËx±h³,Ãò,Bþ¦#¯Èœ\An,i1#…sÉR‘$e^FxŒŸ[Ïäšp^ÐL€‡‹pó¬¦}=ylбv–«íUs&3‡>î›ÍÞ£Íx¦¯ÜLrˆíC¡:z—ÙB9UyçÌ„O7Ç\°nŸˆ<§§O¯LŒQúß`‘Ђ4ÉR?Ôñ‘½! Û™Ò’«å|A é×ÿ×,ncY›Œ—6”ÜïÁÑMÛ’­ÜÕÊ|p­ºU~SNúùÎLÜY™ß-{‡3N¹P+ˆœ§‡¨kæ4oÈ÷}ßJžÇ}vZíP-W“µ`Ô8ŽEÿôãû«ª¤‰X"ýŠÝ9*ð¬Pùîj Ž›?#}ndÌ)uš$J&áÔ4€×Ã#-i¬’‚EX©è𞟿®OSÿG9_<‡¤+rŒ3M¬HáH–9eäæxŽjÝÄ•ƒ§=žuÄj“nýH8»©O!›«NJYJ³„ePJÍ•ûË{ÈD×à bÆ€¼ŒYhÞZŽýhmR"˜¤ª,7 wiŒ9²(Ad^¡®&%®é´˜´ Ù(ì}3 ˆY`4ØPà  º3à8 M÷0RƒÞ£ß5…Üž6rt$Ò@›~œ¬ˆê¶í7õœbê—âBýZÍ9ñ7“T>ª1éãªäquÅúõBˆ\Ýj^pˆáv ù¹üå­†N – ‘@±0'öâ!ì†ñ÷oºMßý&»Fv›@KŒk„õ‚a:³vpmÏã¹ã kË6»Eôþ#ÉöcìBçD‘°Ì§˜c´$7˜4ŠJ"¬´Gõù=~Ýëyú–BäsÉ_qy•ÀÑ,ÁÒ©—j¥t<@Èm öžeÑÁ~Àœ9DðˆyÜœ#ËÒƒÝé.æOž«æOpÌûစÂá¸I‹ÔÇc š®[IíÍ…ÚljP·3 1I±ðnìЉ繨Ê<Ÿ«¸x·UÕ¥ì÷_›Ò¶Î`çM…M}ÌciqÎt–U”Û" K8©GÛX–?ÔÃÚÚ`̸GÃ&5 bS-ÎÀÍG=úw• ›1X^{PµËkaXrF#«ÎÍD£ÔƒTPÄ"ºG#©=([iï8€x fë^èµ7böŠÃÒ#xDT¥Oý ô0MÈ<³³HÎíl¶ ²®' äk÷¾[]™QV”ê&þ¢”Цg¯I¯í Åû;c-·-€ôÝ*íxmÇkó;6›^òA·Ý ýÁ€Õݺ™,­N (²px+²ÛbÎVøéh›¤@ž\ |î /}Ó¾Õ‹}³íOK:\✡|pön×öxK\Ÿ±ä¥â§k‚ñȆ²â,µÜR¾€6Dpó°õ£>ËÐbÛpU = Ƴ¨ q¯¤~=6”´æ‚4XïØcÞºPÔp9øœ2¢J=ŽPmï>v“g¿0ÖÍJš…¨ÇÑŸ-´Þ@Ì´Ã8Ówh«%3=öœ‰w âýîBtM„R~™†:@1cZ@ ˆYŸgÖÃÙ졾\nž²² IVA•Íò«Ï=ñØšQê§âªÌ^›Ò <6ÓÞcµƒ{\T ŠŽCx¡õ,¨*C«<Í#ŠÝ/4ž|‰zÙ?ïe÷ MÒÚŒ”‰ 8¾L“Œ-ÞzÙ¶mClgÞýÞøcÔÛ£„‹i ¨RÎ%º}Ðhl]º A{Xæ‹Üõ‰¨(êqëOÄeÍR躋*¦äbáÅÄé­—n=j8¬éž)ê6\7 b]{ž¦6cÓ]hm\±‡xã§ÌŽ#¢œsë0[I¿ jÙîZŸÑ;¤Vè*Þ ”~|‚+|­¾.Ù4c\Q¿J;Ô¥óëOéyÁ 1‡ÔV¦¦‚ü«7Csœ–žU°U9œ˜2a¬4Þ4ŸÁ”jYá¯*„±üGؾ)#æß¹ÝÐÂ7"õ.`H•GTxö>¯  âäò"ÂæÖib7±CíÕ^{Ûê.jfÄ0þ†ÈAX¤ÝFγ(/ÃD“ªo·¶@d<©†«Yð!ôóE¦.2Èus_&‡ž£€*5)²2BïUp}¢æözG^°ŸcLÊ ZŸdæÊ<ëuWuÝ <¼M {íA{¯!†÷šÙ–§Ãºo/“lm‘ˆ )è,ß*š|ÄWbÕzꄉ7¥kÔ׋ß6‹’ªGQýR>—øìÃ’BR]้ è%DUвHÊ —Hur¾®p©‹3؈"Âáyõ¼êçi„‡ÓSõ™:³r‚¥‚V,ǯþs^Kå„ú·@êd›¬Ün^¯ZßgvÎ=̘I¿Î?Ë ®ß¹‚ys+hØЈۺ ±Þï‘}qDìåyȰ¾,)Ô–CGunåYë×rþF¸éÇ“êUÏ£;lW?¬þZ†À endstream endobj 2208 0 obj [ 2207 0 R 2209 0 R 2210 0 R 2211 0 R 2213 0 R 2214 0 R ] endobj 2206 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2208 0 R /Contents 2215 0 R >> endobj 2216 0 obj 2512 endobj 1047 0 obj << /Type /Action /S /GoTo /D [2217 0 R /XYZ 72.0 720.0 null] >> endobj 2218 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 560.831 298.498 569.711 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2220 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 560.831 298.498 569.711 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2221 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 527.304 298.77 536.184 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2222 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 527.304 298.77 536.184 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2223 0 obj << /Length 2224 0 R /Filter /FlateDecode >> stream xœÅZíoܶÿ~ákØ*ER”T¬Å<ÄÜ¥^_S ¶1Èg]N‹tr$]œÛ‡þí{¨‡uE{:î!¥çíÇçwý´ð …§ê#ŒY‹OzÏ'!#\ê­@_x, Ñt@rõÖ€`øòëb» äo‹ë[xxO(0<.èX\Ë|µx;ЯžÐ¯®h÷Ùb²¡=•ö\üzíá<=|28¸~ßì¶ 9îÁêVr´þDCDðsÖjÜ vµ‡_O9%].¾}Ÿ’åÚÄy¨}êE,VŒ, rýÂçÁñ-Yþ¸8_Nà+£69H¥»÷‡6¢”únµ‡j§Ð§Ë¤HÑ) "",ö¨ Ôû2üüîâryúö—ówÿ$ÈØ¿îƒV_‚V.å”ñ†±pÌÀ\ äç*Û65IH“Üíò¤"UúPV )×äÓ.­ö°®wyS{¡Åá{4¦ U¢Ô×»íªÉÊmÇ3•Œ½Àâ8ô5VWûm“|éc‹2Ÿbåku¤ýù Ë›ÊÛÓÖ±1LµIî ñ騒6“& ­èÓôËÀV˜8ÂfÓ÷§éÞ¡”E6ÿ›¬ÉÓzVg6(Z8·a±.«"ijB«G5¡Í™:ûÃA­0¯Dø6çë¦J“b^Ëÿ  ÷ $UR§³zj=™ï OgŽÏ¹Ç!ëh ä;«>ìŠ´Íæí=yŸä;¤Åd2€ÒàƒÎÝÑ;)Z~ ¦Üg[rLN¡ÄäEÇ)'œñ>®0§"êO¹‘ñ ;“žˆ#ÞT˜‘Ôl’Ƭ Âܨ~/Ø~õöY`ì—›lµ1ˬ>07]5éý@m9TÚ쪒dRb3ôàæÅC Üå{’ÍþæX—cR§ç>Û˜zR@©—4¶G£ýP'lgÄq–Ü ™ŠMÆ Iy÷o@Æyˆab -b<²ÜÎYž“ût(÷Ùf“’Ï*ÆU«z©œv:_ºÑa>óüƒJ?°ÕP+6S¦3’guÛ+¡ dÛ5)+2_ò¡û²PõÞÐfÁåÅ›yˆDèb%–€’B¥©Eç  ˆH5È8°Vy;® '.¨ Í=å„G.V7ú@8á]Î+ "ãïÇ><× €[Ÿ÷‡A}»+îÒÊzdru,ÈzržÑ¸¤ ·0žp:ð–rží÷£‚‡I3²v¼Ç<ÐáÊ]ó°kr»Ý烲6åð_0ßs˜8…» ”F¡®®¯ÒzUe«Ë|Â'À(¹> }q€†&´³Žè®z©oz‘Ú½Æ÷¯´ ³TÛ¨Zßí-<ºE+²oÐjá6)”ŽPÆQož=ù@Ð!礳¤Ô¢Hz ïÒQãWà :ÓÂPê}qWæÙÊìhçqaL6{ee衤¶4Ÿ˜lÀã¸s@½–*f˜Œ-¦>9V0¹ø =d¸Ô±]›œ§¶t|óp‰‘‚ A êÐMÁiÎ÷W{SÄ(Är‹êqå¸B IÀŒú2°èxªìÜ~ Ê,ÜÆ€,\n’í‰!»ÑoàÈd¼ZO}²ræEê†"¬.¹Jyäbœõ¦H“íÀŸn|ÇÕ˺ûMRÝŸb-~i pW§÷žYBH8û—bd];κÚX@œƒÐW±“~§óWƒØÆ6¶œ=?fžà0}H!-ÊMܧ.Vcf’çåãÀ¬6‘®áz“­³UÒ`±ÁÝ6€4oOµc‰ånJ¶x Çe™7Ve¾+Œ¶á”~pzÐ&G¹ÜÖ¶P}%Ü5½0 70Š<³áÈmhé‘ïCk†R>ÕùÄ'ÌF²Z¥X÷ô†!5²ékC÷HéukÌÉàÝí„u9 M0÷fä¤y­ÅìÈOa%8Üs¡MÆ,fw±áZN2·Ôç|AmŒ':ûy×9ÆHÓ ¤ñêÓ@„7ƒ—¡ƒØZ<³±¾~X{ùaíåƒÚËI¯ª¦ Þ>¦>Î×^×£Q=,¶ü Øª‡Ù6+v…ÙÄøÁ7Àt2ÂTÊU©³¸€Ãz,Šœ­^¤¾£¹oûäýnÊöÞ€¶UȾnÉaÝ’¦n!‰Jû¥)cÒ”1$ïŒÓª %ôt;Z`”á†N@yXñ´.“~ZÃþ Î,Ÿ÷yrŸYEÞ¤ãŠ1WÄ_êòs–6^Y}˜&ǧÂù±¬ÓµzÿªIòVZ݇Ò,ÂÂñÁp•­=dY•MýqOHƒÄ4‹°h|*‚ËìcÖ$ ìïÕ®^mÒÏä£&†Ò,Ââñô¿ _“lŒÆaé<Àx:i“à_*ðOT Õ&i£¸ b‚‘ˆ\ä‡ïIpdSÎaýÿG¡cD‡QHLZ‘ þ‡‚·‹ÿ߬q endstream endobj 2219 0 obj [ 2218 0 R 2220 0 R 2221 0 R 2222 0 R ] endobj 2217 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2219 0 R /Contents 2223 0 R >> endobj 2224 0 obj 2182 endobj 1025 0 obj << /Type /Action /S /GoTo /D [2225 0 R /XYZ 72.0 720.0 null] >> endobj 2226 0 obj << /Type /Annot /Subtype /Link /Rect [ 242.16 559.076 302.99 567.956 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2228 0 obj << /Type /Annot /Subtype /Link /Rect [ 242.16 559.076 302.99 567.956 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2229 0 obj << /Type /Annot /Subtype /Link /Rect [ 217.72 315.844 280.77 324.724 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2230 0 obj << /Type /Annot /Subtype /Link /Rect [ 217.72 315.844 280.77 324.724 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2231 0 obj << /Type /Annot /Subtype /Link /Rect [ 217.72 271.62 291.6 280.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2232 0 obj << /Type /Annot /Subtype /Link /Rect [ 217.72 271.62 291.6 280.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2233 0 obj << /Length 2234 0 R /Filter /FlateDecode >> stream xœÅYKÛ6¾ûWð”&AÌ’EJZ`S$E‹E‹ ‹öæ •i[­,9’¼›ý÷’z­5ÒÆ=¤›RœùæÅ™‘ýyÅ ƒkû¡cAÒÃês»Ç‰$PíV¨—T„ä@Z:$¹=5"DGÁ‡?Äžü¹*VŒü¼úø n†û;ç˜?¬ÞðíöÍñÇ\ü/X\T\\ü×ÔçуP²ÇOFë÷‡]ø=ØñØöQÞzºýôŠxÒÛã?gí`ƒ ÷cká·gd·zs³úþ]H8#7Û!ϵeäŒF"¶‚ÜÈÇç<Ð/>‘›_Woo& ð½6 ¤Åîí ‡ÀFŒ1þÈ,\Ýåmú-9oâS¦B{>ò Þ^¿ýé†xžþd¤)Wö×S–¿„Ðgçã¥óä퓞S“„|>™êì²;SfoH}:óÌlHZuS%YÑÔ´3@#HNYÌ@¸òÂߊ´ÉÊ¢ã™÷•ŠiÈ£8Ö¼õÕ‡‡¢I¾tŒ1ÆYHc)A˜­-îïÜ[9Y›Ü¤ÍÙI.&ôYeê†tšpv® WaË6¦h²mfªzÖ!P+žýcð„Â,Jò|'Â4\‚ˆ0Å6YÝdEç6'€ætN 1ŶUy˜ÇP—bh cW•§ãúöa>Áðd˜Ç‘SlŸÜeÅnÍ%…E&ÏÙ|XdŒ¦ÙMÀ”¾Ðu -7÷{S™YÍ/´H£¹ eê”7ëæáhæKŽ)/ÃB“êZ¾YÐÏæ¡"´N-@E3k›'Íq$Fƒ»3,ë*³÷íçað~³bƧIº_*¶q^ÃáV©“&¹Mêù”Ôo?üH|=ݱy ©Ôàÿ æžûªÚÐõ`”(6ä$? ÙT2ðhÑH0óuSÒ5'ƒ·]fÂyEàF“rÛ;KMø`ÐäP ˜k!õ眘/G0¿†Š0/Fc0›…2FÄ1¶zÜï3 ²b“¥‰¯Ò2?`²*ý E—}L“šÁ¤Ãã>™p\‘7e™›¤X†,€± b¬ÞèQ¸ ××¢‰ È[¦4Ÿö{jÂò{aHY‘CYòáýõ(p¿–´iTì\ƒÜÔO($5 „é"À‡\© ÛUq¦Ë¸0óÊr‡ÉpÔ Ó¥¨1§¡ ã¨+y4<à ž+R”ź0;hŸw²¼1;S-#< *„~‡Ø@"OxþpR /@QÌ8>dàØ¶ ]„šF£( †|Â{)¸Ž¡L €aC:á¹T2A¡«Ä‘C¼¡¸S¶«…2.!,Â6$!Iyû·Y(a‚ETk#…FÄPr³ÏjrŸå9Ù˜m-ÑnûV|g›­ð/ÛëóåÞÊ$³f ™mp×Lxú2 ¦;;í¼Z óük hë8Žþí—ëyoAX`}Ân© RÂE‚›ë”Ûi'†©sÊ<Ò¼iy8–ÕHk[OúE&UY:l¸ ì‚_bn…Yç1øH’ˆ¨"ϯ³ú8¬|5¨‡ ¨ÁP‡u³‡կꦂN\Óaç¦ FËm6§ÔÔcv3,Ò²nFÐÛ†®„qÐŽ&ÃÞHŠ9¬1kcqf-¸4©€R>êÔí—vüîh¯˜§ç³²]3 £#Ô¿)ÚrV Ì0|2„¹G‡­êïú% ˜eqgŠÌé ¢s–'ÝãªA¾uA›]D¢É29M+§M ìÞ†BÑ0”Œ+ÎûÂCÖÌFÉWÚnåÃëHWú•»’u¿œw~Ài$áVI.Ü'œ¯€λ·°)s>ÒË*y€L!m½·ûu{M=\J·´n¤õT{1gÑ™^Û²là •?šô«Ä~ëœÚÉö{¾jzº«»Ýº‹‡_ù räü—ˆj“PÒu„h·Ô ƒ@-±öØ}ô[›`ŽèèÞ~éœéÉÛÁŒÊ4§ª0›ABy6dg w^K@Ê.©6ð Ôm8ïXÂ×KùH»=è´¥·åñ>«»SIû™g®¶Y2ë„Âx÷Èéj—þÍ×Óû¤>`rcÛfŒÓ4ñïÓmïÞCÎt½»vØO[7™Úo²¶Á¾G Ie^÷?%~³ˆ:»ÿEÿmŠ‘Èµþáw©×™kÁ ÉówN«vá¼á)×ñLÿ$éŸ$Qg»b8оżêÖö…¸££õmÖô\®8JÉG6æhН•nãt,‹žkoÎÜÍ`þ=3l(úÛõLDûkSžà&ï+pRïÄ~'⟮·y ¡õeyž‹Ká›9`OÆX¸H‡ª”b> endobj 2234 0 obj 2055 endobj 1027 0 obj << /Type /Action /S /GoTo /D [2235 0 R /XYZ 72.0 720.0 null] >> endobj 2236 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 536.832 298.498 545.712 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2238 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 536.832 298.498 545.712 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2239 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 490.687 298.77 499.567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2240 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 490.687 298.77 499.567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2241 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.675 468.542 309.465 477.422 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2242 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.675 468.542 309.465 477.422 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2243 0 obj << /Type /Annot /Subtype /Link /Rect [ 411.625 469.022 441.625 477.422 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 2244 0 obj << /Length 2245 0 R /Filter /FlateDecode >> stream xœÅkÛ¸ñ»\ƒÝƒÍò¡gØöÒ6‡Ü]“l¯(Î÷¶¹»jdÉ‘älü%¿½Ã‡DÙ¢¸É—ÔÀ’óàÌpt>,("ð·R_iÎÐv¿ø`ç(J≊D#Ìb´Gv£Rí X?‚/³ èß‹jAÐß¿ý‹;DáqA.Éiäw‹7#þj…|sþc 8eÿ ” Ú*Ú. þ¥Xçl!ŽÈùÊÈpü›Õ ¹™ƒÃ[-•VÓöÛb†æ<æ{öăøõhOøí˜t¿øËíâ‹%èöÎùyª)ÁËÕ‡¡Û=úíŠFìúwtûãâåíľ±Ö&†T¼‡ópDÁ°!„žK7µ‡2gúYì¥9”G Q†XŽI«ý™Aøá—Õ›½|ûd°†½”0œµ‘x°ÖŒ¥—4„€^u²DõGÙ Q–¨{¨;JÙ¢ú ôá(›îeO=²G“\qH ͟Ķ©{„y%9Ži–ç)µ:zwª:ñ©GÌ=œ(‰qž&€Ã{ùõçâÈYäÙ¹«Wú(—êáÌGv}µ¾zÞȶC½< Í…@4K<¨¢¹ogÏÀ4•K”õu€ c>õQVòÓdl‹ºšåÈ©WmÏßËS€)½*؈VΛˆx•9Ï'">éàLDz[u§ƒœWe”ùT‰žoê]èd±W i–SùìŒþüAŸvuÊ!/EÜ:šì›æþ¸—U×"QíЯ¢<º£zÔZŠ3€’²©ŸM" Uö»Ä¸Ae ·ú£h ±)%ª ,µ8Ì8£˜Òn7caßóK1A¿©Ð5ZAÐÈÑUšLP!:Pžƒðqê¡Ñ~(‘/„±G9˜†R5Gª{ƒ©k+ sb$ý»7¯ µâÀLJbûàÀ¢=“Wn;¹±­ÇL»c3b".–RjÎ/ް¾:Ô ‚M©EȠܸ’ûCwR¡ÅÂÆY°•Ýrd#¦0¢k@ç‚zí0 ÷¢rŒE×5ÅæØIïÖ€³ÁÕšžìîXmW0¸‘ç;» /¦™uâ=ˆ)úÛ¾ LÕq Ü(åþˆè½S´p|ŽS¦bÈ8ÏÕ›ÿ‚>M"K=d0º}—|, áïäPŽNø½¯z6ß?¡(ÇÂnšÌ‡n¿R&¨ ¤Ê÷PPà8IcB8‰=î Yîz"J‚~ÜÂ}+`µ™WOq”@€N¸O4ÜSº}ˆöj³ ¾àgâO“žƒM€ Ï=<~~õzV<‰esî”O ÁyŽæSߨ:ò‰Ìáõ,ïêfP¾SS+!6tÅvP¤ŸaWÑú.vBCšgyËî §#@£_@!ÍcnѹI«´—ÖZbŠ Ì[Æ8´¸¸ÒQ N  iZ ”mmF…),Âc£6îìde·›¯y7‹ Xb¶T›Ê÷5õjÌ0ã¶p›R2r(g[ša÷pŽTÖæŠPÕNmKшËN_©LrNTUtдwÚm']¢*@és‰¤nø€þ &k0ÕA6(*Å òÞhª£¶Gì_ÄZd°Rdà¡"ÇÚP’PtÁImŸG öQc(¡I¥ž8H<¨êÖBÓÒ§-;n¨ß ÈD736eÃkxë²ë¶Ýí°Qd |-™FÝB¦‰´@_êÙ%ÛÞ[p”ï쌩ôÌ8d<æQ‡©Ï<Î!å|ç—Ôpć¨W¯îúQ `à'T¥¿$÷Ðú2Ãç1æê))UGžÐè…0ö‹3 $Ã4ÊõûÔPèåB½CÍcöŒ…É>jhN6ˆ$̳¤Yq×KÃ&Så ~Ìt«Ö÷ÔнÙhPei9µ9ô/r‚÷ÿI!t쥀ȣ_‰YíÉÚH ª¶@•UluèÙÖûƒ®•OkWÖ¾ã1§˜“ˆÐ„Ò¯í¢Èƒ®Î Á>ïëF ˜oÆöI[ͳ¢ƒÝ«¶×W–xé&¬r `º¯¢Ñ^VÝT#ïd3¢P»ñ¯…|tÐ_KѶ²]_ø•Ç^¿8´ H¦x›ÕváDEbs‰ðÏ+4 ájgØÔÇj×§÷ƒª>¢>äÈ]Õæ×Þœôvk…º)@u0}þìüHœRœš§il –—ŸÄ^±f ÜnCÇó¸ÿ5¡/4õ¡­€Ô|Ò™q}ž3#3»T³H÷m¡X=[_OM”0rÁeU¨›„ž}æäÝKp“ï>³eüÝç?<Óì`\å®ÙV¶™5|××êÏà ú•sN/^ ŸD±Dÿ,dvñ| cè^ÇC|oBóbû^6KôVT;8üØGS=”“Ñÿgx³ø…‹OI endstream endobj 2237 0 obj [ 2236 0 R 2238 0 R 2239 0 R 2240 0 R 2241 0 R 2242 0 R 2243 0 R ] endobj 2235 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2237 0 R /Contents 2244 0 R >> endobj 2245 0 obj 2420 endobj 1031 0 obj << /Type /Action /S /GoTo /D [2246 0 R /XYZ 72.0 720.0 null] >> endobj 2247 0 obj << /Type /Annot /Subtype /Link /Rect [ 199.311 506.902 256.842 515.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2249 0 obj << /Type /Annot /Subtype /Link /Rect [ 199.311 506.902 256.842 515.782 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2250 0 obj << /Type /Annot /Subtype /Link /Rect [ 234.0 473.6 297.05 482.48 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2251 0 obj << /Type /Annot /Subtype /Link /Rect [ 234.0 473.6 297.05 482.48 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2252 0 obj << /Length 2253 0 R /Filter /FlateDecode >> stream xœÅYëoÛ6ÿî¿â¡«ÄI½´@ÖvņîQ$Ø0Ôý Ût¬M²IŽctËß¾ãCK”R`@çâ½?Õ» ‚3ñðCËtr§ç(ø lOO¹PÇb.¤ Ç.$bUkÀª>Ô"là÷ÉvBàíäÃG|¹‚ ‡ 銓Ìד÷-ýâ ùâúÛØ”ý/dVd^þó-™œ“®CNß´WÏ7³R¡­æpFé¯iýT†¨¡òG=ý ÄGíá—SNàvòÝÍä›ï] nÖMû‚‘+`¡ø1¸IáÔ:ÎùG¸ùqòæ¦W_8j½D ݵ?6PLl@¡'nÉäúÚ)åÓÏQÊ•S†08°Ð"ž+ÖŠáÝ/¿ü Š£ —gyµöæŒùõÁØzxóPòmg[(3x•¥)ŽÞÅÅ*;îŒP+"ìÐ`p–í=dÌæúã’çQÉ!»ç9DIå†C¹ß%¼€l Üíy~„û8Âq‚ª`™Dû‚[•JßT‡Z$$¨ÈkL„W’¯bN¡Z.E›}ªSx}Ü–ÑÃ`pP_h[Ôvažfùð7¬³üŸ:¨ÈÕa¤L=Îû(ÔDmÖg€#ƒ†ò¸ã³bÇ—ÃzBƒKaÁãí-|âÑrƒÎažþO9_fù I5^ËäUÏ×Ä[¤²õX(åÛ²€h»‚ߢdÏ‹ak±´0…–ã ^œ^…ô¶•HÙ市s˜ùˆŸÓá”3jaë!°Ø7HXÍPëIÑôU£.kpkTÃ_Ç[¾ªi¬”j(` ßæQšFyMã¾zÚ#›–è„õíIÆP˶ÙïLAPñ”ÝW?_ÿP×%f<ÊWm/:°-³çzm-„¶àf&³C!àE¢å¾ØG‰ÄÆYQqï­xQæûe¹ÏqÃZãååû–ïàöclÌ5Öe»’À=âÂ4Û•x¸ IõÌpÙy¶xX3®IèÓ¶0ÜyÃü<Æ@å ]Ä©©ÆäÖ»&z|uÙL«²­–Ôu«&â–ûºÑ*]5QgÝ áDž:1Z¨¯=Žº<Ñ*aŒ,úüDÕ´Kj´<Å“ÔAhs¨kecmôyTq¸¡E›Rðú„»‚â¡íjQÜ%þ°Ëy!Z˜8r¬À¡X¸úâYå&**çB²èz.j™ýþ]C¨Ö¤&›OÆšŒ‹ƒù²T£Õfm¥Xl-%Q3œOw:ºHެ`Ìî¸ÅÓ]yœŸ#¿Ã,OH.öIY“//kâ€;‚×”<Õ+Bᵑ¥¯Æ­amÍ|Yæñb_rãÒá³]j!ÀÊ×àÏz¿]–ci¶ÃpŒ¿ñ(ú«mZu ?Qýˆü¶«Úhc£`®ÿ.–‰ƒåï8+}-þÄúí²‰`´‰Û—¢OCŒÝ5"W$*ËO@ýh@DŸ}¡_Ì*•ÖÓí ó™EQ¯ØµJÕk^,óx7š2yéq-/”gœ>䤅XõØD0˜*kèö;µõ¼¼<ˆ›L=µÊã{…ôŠÖ½‚"Æ:^+´ñ ñÏ`Ý(3ÆÆx/õÔ(joWEûeËá[t¢å6_q´HZ \h¹Þ:¸$T’³- ÁtØÄï½Ì¶_îK4Clš@CB¡‰yu‚ŠòjQžé今%‰‹²c½é·jhZ–c¡ð+ЧªT¾i4T€H8«§‚ÖZG=àÒ‹í­ÁivœZ$¾bž)´ºW÷ùŸ:G™¡9Ó SçöȽüaQO¢³ývW¼Žùjñ2da³hk›.lýo>&Q™ž#*3Ž ±àÍXmx5V8ØÐõ ¬Èù4¶¸uÙLèM¥ˆ‚'|Y¡…–]_Ç꩜¯~h Y3þ-懆z•DE!ªµ¥/nÉ®ÛE.£‚Ÿf(I—uÂSìw»35 .²=Þ5‚7ŸJ¤uÒ(lü l÷–8_o Üb¹`–Çj—Ê~ÔÛÁ&Ó'$dúãÍ›‡HôÐÅ ¦Êï0že{Töçúc•èѸH³Õâæk¶Â¦çóéÙ ­:ƒ³-?plÑq¤'äc~>?ïÍaAGÇÙOG¨öÀ™‹ð”áÅK¸øéÙëï. «1']äg¨^) ŒS>÷èJŠ]Æ Û¥Í¬”Éúû¡¾zÎïð†f4«áT:€’Ìñ(ÿ“h¿{-NÃùTX­ Ôª¯:§¥t¦¶ŠtïR.ù]%ÉnM ºšÄzä> ¶'}–UfXH»áñþ]®ñqËKii;Ä\,xø,qÊçv†Ú¦(ÇØêõ:v±Ú1DJ¨_'x”ͱ´ŠMvÐçÓ¿à4=LŠC g¹,×G÷õã³3  ó ÖÊq_߈½ú¾}|ö¢ù¡t£Tߘº“¡ûêyˇ&#Fi1]Ÿ½‘‰0˜9hghHˈ­L›Ãé‘Ìé»Û\÷.íì5ŠeÝ,½| ­œ8ìn£‡Ó2r¼†Ïüa±¹6­ÿ˜y?ù§hÎ endstream endobj 2248 0 obj [ 2247 0 R 2249 0 R 2250 0 R 2251 0 R ] endobj 2246 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2248 0 R /Contents 2252 0 R >> endobj 2253 0 obj 2006 endobj 1029 0 obj << /Type /Action /S /GoTo /D [2254 0 R /XYZ 72.0 720.0 null] >> endobj 2255 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 502.687 298.498 511.567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2257 0 obj << /Type /Annot /Subtype /Link /Rect [ 241.139 502.687 298.498 511.567 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2198 0 R /H /I >> endobj 2258 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 468.542 298.77 477.422 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2259 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.72 468.542 298.77 477.422 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2260 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.675 446.397 309.465 455.277 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2261 0 obj << /Type /Annot /Subtype /Link /Rect [ 235.675 446.397 309.465 455.277 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2212 0 R /H /I >> endobj 2262 0 obj << /Type /Annot /Subtype /Link /Rect [ 411.625 446.877 441.625 455.277 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 998 0 R /H /I >> endobj 2263 0 obj << /Length 2264 0 R /Filter /FlateDecode >> stream xœÅ]“Û¶ñ]¿OÛsbü@3í̵u:É$i_Óéäò€“pwL(R&)Ÿõï»ø ’ %÷Á3#,€ý^ì.Àû°!ÿ­úÉ8E»Ãæƒ#(£(NíT’"Â"š ²ã•j—7 ý~Ì&<£oª FÿØüò+,î„— ž’ÓÈï7ï<þjqþ¾1¡ÿ ” Ú+Ú/þÏ"íœÑBÂðxÅsÜ0ïf5ÃØÌÁŒá­–Jkiûk1C£ù]Ô;5pØŽVÃ/Ç£§Í_ï6ü:A£»Gç™B$8Ê)WÿQtw@¿¼",{ý+ºûvóön_Øj3G*Þƒ>1"àØcLFjiçfV)£Óâ R3°Qá4QûsƒðýíÛwÿzûÓA6Ì#΀'elŽvOi6E kè{qD=žª]WÔª?ʉ²DݳDÝéXÊ=6õö|8ÉæÜ+‘”`$ÂíÔÐþÚíq–í•ò(!9ç±öz®:ñ©Gäf<Žx–Jl59ˆãÖÑ3oF=i <¡Mp€x}ꎧnÛrÛånQ2ŠÙgq£Ïö?N 7ç’d\ã’¤ÒÆÚÊOÇF¶í·8 Ȉþð»<¯°Œ! fH{щÑÊeDzÏ3K¢>§Ò8«]ä”ÐPXüù/È`_ŽYBi”0'‰dû¶y:dÕµHT{ô³(OŽ@ôÒD Ägt=Ìf)ƒ$lŽ}‹Z N­vprRŠÇtÝ ª(£uaà’Áé¥4†a)fh·è5ÚÆ,JÑ@ÁÍìe[ŽÒ,Á8ÆI€”žrßÑÉŽ‡Â´l»8‹X Å5C¢E=¥»çhoC ê‰?ï¢8“˜xüðÍw‹âÅÐ,cÒ½—ò¢qÌ£”†Ì7ê·ç"¤Kx=K“yñ™ZyUWìóèämwmèüæñ„C_£Énˆ@ˆ„(å¿s /tç[¿Ñu„Ãey¥%PAGh<@âêŠ&À'¡˜0’è ‚˜\¨‡bÙ`6€k³ú™ìí HÓÕ@vã­È*@}èâz!óA ŽeÖW6%YÑAF©êN¶ú§’奀t¬hcR¶ÜG—[Ü:Lè ÀÒý=öï²Ý5ÅqµçRQ7ûŒÆ€†û¦ðx, Óðl½çË¡¯Î᎚+%g„.7¥1^Ãw˜:fǦO3@{ÚíT‰þèÍÙ«ðÕ²-dŽ˜ìüEc{7ópvcùIîN4g ¤m¿d?C)æ¶çÀ4D“ vFiÂ!DÝÚ«ÆÙ#mÆV¬pÈýq ÁepNüúÇktœ(戛q>‰«ùŸ \{ŠJaº) ú;Ñ߃æÛW\I°*°œ³< ¨pñ,°$_Ã÷MÎ&û÷E»Í^ ª;MµÆ‹5Žà,Â)´Bªùœìäå&fpgX!0H`ÎW;ÀêÒ;.ö3Æ¡=ªõ§µÌÐzÓ£Ü`M0òï }Å»G \pÈÚ—½›#†Ó –f’ë[]Ùwî ÖK „ýõÊŒµÈj`‹›®R¸´2j#k.Åõ‡4ËÖèÜXA^Àu½PÆkjô[÷Ük+Ki/åZ×v¶wðïHWå»3dÜÕ®š‘üs]ÃÓ–} }é±ãቀ¨'‚®)NÝðAúTØlÕï—T…r`Q-`¹Äe`uårпÕ¡a·ëM,£öJF=æ ‡ÅÓZµÓ/Ñ5ZÌ,d¯þ¦6G¿"±P¾F Ð಄Fyšó<ÇlèZµÞ‹!zeˆgЮÏѯóK³(WmËCb¨ÞN öô Ï/[½ÑÜhѬ'ôUóAÂ.µÒ Ì ±yÇð:r{½ˆV´¥Q¬Úsõ¨:'èÝGW:¸H€W’'‚ <3nØ[`˜¨=>B8×ÍÍH©Ê#¹¤nq8š3”q3¿°—lE%ˆ¸Õ¯Vy!Ï&:÷7 }ÿYÍ–‹Vr6ôù˜B½‰3àr•kà.ˆ)†{9æ7 2yšÛUë¡Ä{? à‘lGl¦DÓˆ³M,¢†y,>h0 ‘GR¸ê&! ŽOØ{åb^’¸º|Pø²ŠéX¹žó †g9…Ó}åÁ6œ-d"¸ßjV»4‹a»`ƒØB£(‰n‘nXDŸqë§jÍvöÞ>:[ðÍýë›1¿¹­BlÕ'@—úT™ÀYº¯PÝ·‚7t—MÜaEš(‡«ñˆ\&H—ª4ɽÔ³«mR’F9Uoi€Âuos4 Sh 2h#Å™÷á1r’˜OÁsZk/^$ÉÖPÞª`÷c£Ÿ“Kè®_nÂvÑík¡ªž¬›?oÝ„Ÿ»W?÷ŸN T;ýIœt×e ƒ•O0t–L´TŒ¡tu„Aµ}Õ(Õ©œÑ®>@-­TzÖ÷ýºþh›@]1ÃpÉ!ŸûÍB9c†®Ncê9þ`R¥¤Ûzlž±ì¾ hðþUÉèÆMØÓo€VªÑæK{ø :L5òÑ<ˆY µÿ\Èý­m+[{üÍ\Q|“ñ‰ÒîFe*§µÒA½ÈhOú-jïfüÏ”fÆ~Ñc1ÝnÅŸSvD65ÇŒ=5¤õôØUm' «ö¦ü§"3cžŠlýï##q21RÝà :þ”¶ò‡êG0áY–Ø6óí'¡êHëý‰Î»Í:uüV endstream endobj 2256 0 obj [ 2255 0 R 2257 0 R 2258 0 R 2259 0 R 2260 0 R 2261 0 R 2262 0 R ] endobj 2254 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2256 0 R /Contents 2263 0 R >> endobj 2264 0 obj 2476 endobj 1215 0 obj << /Type /Action /S /GoTo /D [2265 0 R /XYZ 72.0 720.0 null] >> endobj 2266 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 553.412 250.77 562.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2268 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 553.412 250.77 562.292 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2269 0 obj << /Length 2270 0 R /Filter /FlateDecode >> stream xœÅWÛnã6}÷W ö¡M‚ZåM¤´@ ¸m¶Ø¢Èb7Fûä–åµYÊJr²é×w¨»%Z1°@jEÎpæÎ…þ2£@ð;7å3v³/õÅ€ËzÊ•@…Ã\ØA=v!6R½kFø¨„p°…¿gÉŒÀï³›;\\A…§nW*_Ï>öì›òêöûpÊþŒå©”çÂð§œòp\AWz×Îw³¥A^ÍáLeÛ,Å5Óõ³r¤VxªçQ¤ƒAì<Ö_Ï8ϳ_–³ß¹@ ,7]œ+£H‰ã1ß|,wpsF]z~Ë?f—ËQ¼2k£ƒ4¶[<(¬G¡°ÊÃU5¨ Ó•Þ…( Âæ;DºFÞ«®—‹OËùòÓâêzñëòý‡+¨Ô[%ôÕ!.ÚæÄ«ß2¦† rJ><„ h(2ä:(¢4Uœ÷Nã¶²¸-¨C|‚»Èj—wû¤TmtŽ3$}Ç¥žï+Z3týœúk£è[ŒQ¢3ÜLñÚéò3Àé ‹d^謘÷À Éñ¤mÿïîÃgh|BN1Æ,Zk]è•ÎãX˜"6c?ý<„Â|–«÷¾Ì/å2·ðê^dŸ÷»0)rÐÉþÒñ>ÌC3|K¬¦\ù¾àžÙ(’)‘µEK¡)P×Q5T5éêŸ0(ŽÛUž£n#˜²lãÀråðÅ1¬ÃÞÇ)Û nà¢^˜76/œXö…ã›PœV¦~ ó ‹úI`ÍwF¦!Œ4 o"4‡s˜ûXâÎt;êgd3WffûÖ[8~ †æùˆAH‹ù–Q6¥ßzð´‚mûV“ÚáBÚ›á˜ñ=F¨}à MŠ(ÁÐmgö8OÕ ÆùÀÙ,ã•î‚Åz6Ö‚4ƒ£v(Ag¸ [tƒt·‹&âW¸SÚ ³Çáú„ d’cNIßó•[é_~Õ»‡¸KwKœ0‡ Qâ¹¢î!gQÒ/™ó‡ÛóA2zØëõ°Žµ%ê@’É‘…<Œ1¯áæâÞn²'7ijÆQ¯ç vÍ’(¶Æ w¢a—Œ ‚Õ„rR™Öi#ª†4œHŸ7$M,-rþ­Ù?Di¶Îám”`vÕêÇùƒŽ²¾¿EÉ›•Îî€ÞžC9þ÷Þ¤IøæöÜ|ÇÆ6îMFŒCæTpK$ïiç­EKŒ£ªÉo«¼k>5Ž›SÎTxö°±Húã¨ù]b &«a¼{9„cßòˆå.5U]\á9Brlتn\Ñ:„ËÍΧZž‹¢„‹7>ÙÜ öEZF,æå¤³]Š›5/QÞ×Q®WXþÚ‰ªCÔr›v8Ñÿj黿Å,¾¼Üÿ›Ò·9ì³ /\ñs;óÛ(i_ͤçAúн¥$݉w÷C·ŒwšÖ`¯ËPEæÐ]C_“%°MÓû¼ì1Y¸K‘e³lœëß=âð1ŒAçyDº@!fârÌ aÒüßÒâÁ‹„sŸLéÑaZœÒ%.PÓ…¬oj‹2dÇêy*l¥àŽð(Þ&esÿÆbäôþ¡~œý6€7 endstream endobj 2267 0 obj [ 2266 0 R 2268 0 R ] endobj 2265 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2267 0 R /Contents 2269 0 R >> endobj 2270 0 obj 1204 endobj 1218 0 obj << /Type /Action /S /GoTo /D [2271 0 R /XYZ 72.0 720.0 null] >> endobj 2272 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 556.454 250.77 565.334 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2274 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 556.454 250.77 565.334 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2275 0 obj << /Length 2276 0 R /Filter /FlateDecode >> stream xœÅXßoÛ6~÷_qèÖ3GR¢$Ø€.k‡k‡¢Æöä–éX«,¥’Ò6ûëw©‘hÇ@Ì ’ºw÷ÝñxΧŠß¥yÄ’Cº_|rk bAä–D,$\ÀÜX@n¤FÞða…p°ƒ¿Å‚Âo‹Ëk|¹Š€/ :Ý®X¼é7oè“ë[0þ¿X`lh£ÒÆ…ã_LÚàr 7‹_V‹_ `VÛ!Ïcd”$\š‡Õ.ϘίaõûâÕj–OÌÚ,FwïO ›PJÙ·ÚàÆÎ)ëÓ;µ×Ö) a\ #ŸXÀÅŸoß¾YÅô’’‘ˆ¡>±9äŠóx"Ïè1\”û}ÖÀ¾ÜdÛ,UMV5ìÕFCV@³ÓÞU•.h*UÔ*5¤s#ö¸2B%E ‘Õðú®hAæ0c‘$‚%RÆÌ1öá¾hÔ×(=ÊHÂÌf±Ã@û™p„É´õ|ʧ¾M¿û¨ï¡3„Ñ©%íyš¡6ªQkUëƒpê³ ~úyj?ç>Wß½ùãqRYL J…½¬nîöÏT±¿T~§ëÃŽŠ#FBQʹ߭Y.£¥sÔËž¾h&ω¹±…ªƒrýN›ÃZã„Äè' y<ß…Àj—Õð%ËsØè­ºË1£Ë6Á? ÜÂs÷bÙ©|NNàWR"ƒ³V¸„ÿU×i•ÝŽsÞ{܆R†± Í›-œz!àìpDDDÌÑ'„%<ý¡×ûe—¥»~æø¨ûd¬ÎÉvÉ„«ùý "kvXZú-1ݸNËÛaVt¨A|¨Bƒ>{’ëÉ¡1ódâjºSÅv®ÎŠT·90ÚÖúF'Dž‹˜Da€'+ˆí毾ªým>œ'_Åâ2$2d2‰hW³Ï²b92`y{u>w%Àãÿ‡e¢¯$Y2ÓPëÏ\>¿†ÛªÄÅmYšq¦óͲÀ›©†"˽ŠzªâÏ7ªjÆÞyUˆ)'VÅ´ ÑhJÉôÅSRPÅÊ#'§ÞšýkNT:-«M /²Ï#P}^Þª¬ªáû+”¼\«êØÕ9´ã¯áYYègWçæ;WÒ)aóÒßÞ¨ó”ù†€†Ü“IÆz6XëAó¬²çÎ+-üIãó.šgÍ) cÒx$“yÎ| Ò“Jò'Ø”‘q§r¬ÎàÏ  œáÁv}Q†ÅëÕv‹ÔÇ® lý°Ì]ƒ®üÃ2$„³¶ö³¾6»¹-ÎnÒUg7m˳O®k‡·£âÚ/ªj i©Ñ›aé wÅFWù}VÜ k}0l_l<1ˆã ÓÚŸëÏ:7½À‘^Ü$r›Ìw|üNä1<àåYéZ7'Ü@ ’ræz¬6%Åõý±´ˆN³!—®,ÁØÌÃe-1ýÔߎQ%H"Ð×0 > endobj 2276 0 obj 1272 endobj 1109 0 obj << /Type /Action /S /GoTo /D [2277 0 R /XYZ 72.0 720.0 null] >> endobj 2278 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 556.454 250.77 565.334 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2280 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 556.454 250.77 565.334 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2281 0 obj << /Length 2282 0 R /Filter /FlateDecode >> stream xœÅXQoÛ6~÷¯8ôaK‚Y#)R” l@ÚµE· C[c{Hò@Ët¬U–RINêýú%Y¢%Ú1P ³˜"ïãÝ}w<žòuBàwj~dÄ ^O¾¶s$?h§D”{LÀÚ±€ÔHY¶áO#„ƒü=É&ÞM®oqq2Ü®ž|´ô›òìúm |Êþ Œ uTê¸0ü“^œ½ÁÉþЏn¾Ÿ­úÍÎ4ºÍRÚ2Ýþ6†4ÃÆŸæ÷ ¤wƒ¸yl=|>åî&¯f“Ÿß  fË>Ï¥Râ…,2³5\ŸQ!ÎoaöûäÍl”ÏÌÚ(FwçBèž[upeëTãÓµÖSx,òH Œ|Ø>ýyuõêòõР:YJÐúÑuØè1|ÊÓæ*þë|‘,“XUIž•°V IÕJC¼) UP*+Ul¼3Òá §‰* %o7Y ÚaóDž h¬¤-oŸ·Y¥¾í€‘C%R³™l1P4„Ü!Y óÆ÷!e>smûý…)hÈÀ¸ŒY¨JÍU©ºÀhàRö˯C'Áﯞ¦•ú‡™Aˆh@—ÅÝf-Ae øK¥]vÌPG!Œ¹Ýå4Z:F]vô#y*<ÉŒí(|Päót\Ö*CO¢Ÿ„39ÞŃÙ*)á1Á”_è¥Ú¤˜Óyâ†È—pÑ.Lw*/¼øˆùóV´)ÿ›.ã"¹·³Þyì)†øQÄeš÷K8‡)7…éìpH„ôD€úÂÀwìqBpâ2ùÿSoÂã*‰WýcKNÙÏ Ýx̵SbÚ‚’n-EIµÂrÓï‹AéÊ8¿·s‹#eAúòdé5g¼%Ã< ^×E0^©ìN·å¯L²X×éam s}§²’‚aîã¡óe£áÍ7µ¾Oû£æ*g,â^Ä)F–ìjúY’M-¦÷7çc|¬ û8¬ ]qØ“¤áHC©SÂ)ç¶UJ°d½Y.Ñêò؃…ß (vg‚¶÷âë¶èaÍ”¦dÖÅo÷ÐfiÕe¹W–e_•GB»æ±[³JénN½|¡ð4éE7q@ù&[è"Ý&Ù]7Õu ݾÙÂÆ:ø—rÀ…m^Ц¤¦)8Òôá«&>ÂwìöôM,…GyӜဗf¡K]pÝDzDD„Ѷת3yœoeCà3Ï7²Èo€³†dì ø(ZÍdÃK÷ؾaŠ /^¸Ø³Œµ>ÍTäÃ÷&t-Kó˜d óRÓ¤÷NBc6ý„zÂᕲÐs­3{û¤JT›¯­ÀÖ¹s¬R‹´*?Öœü]”‡‰Ä·š™T•ÔÖ˜æíà{‰|›Dã¡ËžýW'‡,¤ÇðGtG›3< ”lœ¯×Éá—ß§ÇОõÏ…“ÿK~a endstream endobj 2279 0 obj [ 2278 0 R 2280 0 R ] endobj 2277 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2279 0 R /Contents 2281 0 R >> endobj 2282 0 obj 1295 endobj 1223 0 obj << /Type /Action /S /GoTo /D [2283 0 R /XYZ 72.0 720.0 null] >> endobj 2284 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 558.779 250.77 567.659 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2286 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 558.779 250.77 567.659 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2287 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.1 222.0 82.5 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 2288 0 obj << /Length 2289 0 R /Filter /FlateDecode >> stream xœÅWKoã6¾ëWÌ©È.j–Q¤-àm³EŠÂ}Äh›=(2«•%¯$7›ߡޖh'ÛCjErøÍ÷ÍpHòPü.ìC…â½÷©íc 8ˆ í’0Ÿp {hÛR;kÔà] Í$lìàO/ó(üè}øˆƒ hðèÑérµñ­÷ÛߎÐWÇ{ ÿ_<°>ÔQ©ãÂñ§Hœ“éÓÓ‘Qàúþ¡·Mö4Øv(m•nŸ#M³áÓ<Ïò  êÖ±eøzà¼wkï›÷…õvÈse %š‡öÃa½‡WLª7aý“w½ž%À+«6 ¤Åîù`XM)e'´êખTÃiíMCÊ!ƒ¯‡„ÒÎ×ÁÍj±þ}¹º]~¿¾ùeµøëÞ†ùeCh%øÜúŽs55— ` ‡Âl’8ª ló*SVIö;SíLTE”•Q\%yI ñ±(LV¥Odh›?¦,IÇQ98úŒÐ"fÐ`¾?fõjÍy9ƒH¦ÃP±VÎÛ§¬Š>w†¡ŒÑ€P߆€«–bý™¨¢}ÇÌ$[ŒÈ.S%5u-ÿÕßæ :—úÄYà°ÚDUt•æ,¸<„o¿Ôû˜VϋDŽO¥p ”õ²x8î1v%DÙþˆÒ£)Ï;nÅ”!aŠQ*¹tû=ËiôÙa¶ì fLeó“q~òû¿L\ÇUšX²¨—r,C`½Ãä}LÒ6f¡‚På€)ÿX ßÂÛv`Ña¾%—ÕÑŒ»µ„jwÓihÜÚÌŒ–ð.ÏSeäù˜r,šÔFÄ~0e\$‡ñ~rÖL)0“û@`ëàÕPºT¦ob=è_º¢Ð½Ÿ—‡II8oÂê68—쿹”Ä»þ­`éb2ï°J2X õ­‡HªÖº~ÉÝ Tç3)Vm?˜8ŒéuRI_k…RŸ²zÈ.rý9ÚÒaϺêŸ` ·“Âb«E{&ÌêÚÝ›¹Ë‚‹‰–šÕÍÏŽ™BÎÊ**ª1ˆÂWNˆim¶Sqÿ'jÊ!ÖŽyzÊöî*Î÷û¤r®NŸÓƧSŠ/óÛgS¾gÄ”áø|»”OX6ˆf¥lóé6Ù¸Þn±®–—Ї¯}¢¥ µ’mÕYå™yA K&ˆäõ Ô:»¬ÑÌîŸ.!J¡ e"ÄŠþ…ˆA`½PiÉ»M›º> endobj 2289 0 obj 981 endobj 1112 0 obj << /Type /Action /S /GoTo /D [2290 0 R /XYZ 72.0 720.0 null] >> endobj 2291 0 obj << /Type /Annot /Subtype /Link /Rect [ 205.72 536.148 268.77 545.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2293 0 obj << /Type /Annot /Subtype /Link /Rect [ 205.72 536.148 268.77 545.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2294 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.104 156.0 94.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 2295 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 168.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1109 0 R /H /I >> endobj 2296 0 obj << /Length 2297 0 R /Filter /FlateDecode >> stream xœÅÛnÛ6ôÝ_qÐ[RÌI‘"lÜ&ݲµ ¶ÛCÝY–c­²”HòÒ`Ø¿ïP7Ë­¤/]œDG$ÏýJßOPüLÍCy‚íä¾^c 88n½$]`‚p [¨a ±9Õxá£:„Àþœ$ ?M>|ÄÍPDx˜Ð>¹ùfò[‡¿Ù¡_W‡ñÿE#Cé•Ò/)s°!=Üé8®]߯– j W*Þf+®-]?+A*°Ò§zÕƒîÕ v;Ö~=æn'¯ç“ïßJ`æë}œ+ƒÈ(ÑÜ3?æ[øpʤwöæ¿L.æƒøÊV8Òðnõq€¡c5¥”¨U:WÕJU:]ùÛ°RÊb¡{„ºÒœ×Âìü|:ÿ}vu3{3¿¼¾š¾¹~ÿþr>ýùúúW¨µèœsâz(bHhÁ¹ê#8cpsÑú6iú)‡"…eÙ.‡M˜@n·QQDÉ-?¹ sÒè¥,z F¨G‘¸[»K‚"J“ç¸ ]H¦=O±Ú„7Ián= 3F]ÂãnJPþôÔ×ÂrÒ_­¦Eæ'¹_Ê7­ôœô­'\§F0«'—Ü‚0``ÑÉaV¥¾ù>Žðs¤MÁ•_øK?ÚÄ„_A滸xÚeÌDk×óÁê(ÎnwÛ0)rð“üáÇ»0?.¸q¡ôˆÐŽ\8Gí4H Æ…s«0n¿H3XãŸë:üà!*6¤¨Úý.ÊÂø¤d\>͈¦u÷¤Ý®váh³ÖîÁqˆâƾœ0„tùWÇùz.Q É®,dÌ7Qކˆc´ÓÚG›\/6!ümüé^ÖÓ†çËqëp*c ³×ás:VÛ ‘æ(Cå…!Øeº%~4BF zª ˆº:·ŽdãÄ1ÕGaaòyÒuŽKÇðÉÓ)aJíaJœ‡yEwÝ"hmRõÃyµÊá MF<8=®³bˆÇ0ƒ5³yV69jŒÄw­›(Ø´où&ÝÅ«öÕo¡N6Kë¼?ØfgËÀdió‚ÙÚ€mÖ¶4šìÝ W웘nà2®š—tÝ«íÆðn¿ŽT‘ÖvÀ£”™áD™hÁ bH¦2ýq«KŒ5BBÛ„ÌÕÀcT:MÆš ¥Ä3“wmdž y.ô>T>¯ëB9Œ‰‘¼ð4ÎY²Ò¶¤|ñÙßÞÅûö`kðNÙ`„iOõP°8Í ?+º­{q6tª#Ü"¶µ«ËwýÑÀ•zÀcd8€“o§±¿]®|Xœ.Îðß]%¼¸ÙA˜çë]ŒÅ«›Ây±83 cœ†2.NO~¸LŠ0»ËBĆf~Âw³÷¯Ïgp'Èõ¡/ø…«½_Yik>PªÉzÚë›ù¨2 j·µå$뛺;¯…Š`ö´Äa®š£Uë5vÄñ C(N8gžÚý‚šˆ·Ç!¦IJŒ ôKÝ9Û®õüÅ•‹Tën?dñtâb ÿ¹(MÉ0Cºrš±­´#ªµ|ëQ’K"=㾆ÛUš„Ïá(±RL­¼&ûƒ°ì‰>^½¢bç8e®°PI¤®t-õå ;&ºkÒÅ«ƒ2!ç!‰ç ›|ŒD+ÃÆÏ[Ͳ‡³ܦÙ~½ÓÔª…ƒ¦V/%-fY‡R9Æ5/Ë=Ѳó–]£=Yö°ž†7²HO»ŽsÔNÇÝãÐ1ì–}´·PÕÛž;.U8»žÆ¡¬Ný0„Yœ§í—û;;ƉËb®Ÿxq//íU)hâ|ÑÕ®÷„!èÈ/%˜¥q¼ôƒO’æóÀœm endstream endobj 2292 0 obj [ 2291 0 R 2293 0 R 2294 0 R 2295 0 R ] endobj 2290 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2292 0 R /Contents 2296 0 R >> endobj 2297 0 obj 1378 endobj 1228 0 obj << /Type /Action /S /GoTo /D [2298 0 R /XYZ 72.0 720.0 null] >> endobj 2299 0 obj << /Type /Annot /Subtype /Link /Rect [ 217.72 536.148 280.77 545.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2301 0 obj << /Type /Annot /Subtype /Link /Rect [ 217.72 536.148 280.77 545.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2302 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 156.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 2303 0 obj << /Length 2304 0 R /Filter /FlateDecode >> stream xœÅÛnÛ6ôÝ_qÐ[RÌIQ" lÜ&í²f ÖÛCÝE–c­²”HòÒ`Ø¿ïP7Ë­¤/G¼û•¾Ÿ0 øLÍKjÁfr_¯1¯^r=`‚p6P]ˆÍ©Î€7#|U‡p°†?'Ʉ»ÉÇO¸¹ŠÚGW_O~ïÐ7;ô›Óïrà0þ¿p`x(­RÚ…ãŸ$¥qö6\A÷w:†k×w«%A§ZÃ•Š¶ÙŠkM×jXÉS½ÊAwbP»k ¿q ·“×óÉo]`櫟KÈ(Q\›‡ù>3|‚ù¯“³ùÀ¾±Ö†4´[y`hXE)e{b•Æ•µP•L—þ&¬„²¨A(àšPÏ5çU0;=Î?Ì.¯goæçW—ÓW¯goÞO¹ºzªw\"¤áƒó!ªç² Æàú. ¢Õ#¬ÓôsE 7!dÛÖaYÇQr 7~ð‚µŸÜ†9id“Ù#TSDïUèßn“ ˆÒ¤9¬FO—)­%«Õxý˜þ—P[ˆ1ê&÷jw‚òÓS€–“þr9-2?Éý’¿©‘ÔH95zèkеÒjXCÆz¼qÏFÒBÂ"—#¸ØwŸÃÇŠŽ´±¸ô ÿÆÏÃÃJäžØÏ¯ óm\¬j'„‡¨XC’¢p÷Û( —à7¼’q#Šr”^»vÍÚ™€ÍZz SÉë0=LÒ›¿Â 8H—SE¤‰vÁ¥ ù:ÊQqŒzZùhcóÅ:„¿¥ ]ÁËzcÚÐ|9®NaLbÌóÆÓ÷œÇª›!Ðyˆ£¼0,Û,C³Ä†É(AK5.Qç)cØ‘hà&Ìqš2 ¥'çH1Ož îð^Xœ†yEwÝdh-®ì;ôr™Ã pF<8>,³dÄÑN•?‡HžQB!ù¡eãaëv–¯Óm¼l§~;êDb³´êŒwÛm ˜Hm&±Í°ÜGÁ;æŠÝqã×ÍØøV/±}{ý‚îWùX[¦OÆ]ÂMµÓÔ†©Qúa}K‡p†îãIfŒÔÀc7MÆÊ wˆ4E]¸64Oº;Gß‘²¡¥´±QY»Î e0’"FbB+ì·\LMªn>ξø›»xWlEÞ) Œ0å©n ÇyágE·|/N†–u„×IJvy~ÑoÌQW hŒ6pôýâ8ö77KÇ‹üw—EI/®·Aæùjcò20h<F^,NÌc!Žñ€ÏÅñÑOçIfwYX Š¦Â‹Ùo¯OgpGH÷¡ÎùÆaÿ¾²âV| X#ˆõ¼î+{D ‹"= s[_V¶‹}ÅwOŽ9“’`BÖÊÅö®ê£eg«VÇñ~CHN8gZ å}UvÄfik‚}µR×Ѧ†}UÅâša.ܳ1øtÅrÔü3¢ã’hÓºK§iäJ]s?ŽU,“ « j—i>‡¢‹<©¤nòA–ÒÇKYTl}3ÎG‰KE´‹Ø¥ª¹>_aÆŸbìë±jéïAÒ {Þ!ŽçöŸ."1W;.Ö~¾› j:“l7Þ¤Yg§SçꕽB׬%»q˜e]te‡×În:¨Ë’\†ñîpYåúZfc¦‰iŠ4×cZµúù>T[ãžá12 1U(-ë~ö: açiû#ÂîÔ<´¹ŠâE¾¼Ä$¢ ˆ³÷ƒDn6QÑùMÂ<ÿý­’ endstream endobj 2300 0 obj [ 2299 0 R 2301 0 R 2302 0 R ] endobj 2298 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2300 0 R /Contents 2303 0 R >> endobj 2304 0 obj 1379 endobj 1231 0 obj << /Type /Action /S /GoTo /D [2305 0 R /XYZ 72.0 720.0 null] >> endobj 2306 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 537.964 250.77 546.844 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2308 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 537.964 250.77 546.844 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2309 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 110.098 222.0 118.498 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1215 0 R /H /I >> endobj 2310 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 98.098 156.0 106.498 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1218 0 R /H /I >> endobj 2311 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 86.098 282.0 94.498 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1112 0 R /H /I >> endobj 2312 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.098 216.0 82.498 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1264 0 R /H /I >> endobj 2313 0 obj << /Length 2314 0 R /Filter /FlateDecode >> stream xœÅWIsÛ6¾ëWàÔÚ™ÅJ‡vFnœN:‰3‰Ôöä“ņ"’Šíßn¢Dж/©¤ Þö½ßføÎýŸ2 …ÛÙ·f"Åš- *0“h‹šµD‰?Õ[°võ!XlÐ?³tFгO_àe„ÜÍÈ1»Šx9ûГïß.¿¯§ìÑÀëPy¥ò ƒŸÂ•s^HAßô×íïw+¼ÞƒZ¶•4H7ÿµ"õ²¶§þ?iÙ›AÆql,üq º™]¬f¿¼–ˆ´Zïã\yBJ°fÆZmѧ3ðó/hõçìr5€ŒÚÀ‘^vgG« !ôÀ¬Ê¹ª1ª¶éÊn]mÔ B#f0 ¤?¯k‚ååj¾økõþ÷÷ïÞ½Y¡š¶£ ‚`a@°fHû™1uL §Ðj—§(ƒ_޲õÙ]™…Ùv—h [E¶´×¶p¸µAØ (&†× æúz—†eœ¥-Íi¸ƒ%ÕÆ(ÚÀµ|HK{ßša”H̘hŒ¨>Gvk1r²på|oâ1RÁ(óVÐäHªÆd|·ÉÎ4€‘1ôÓW÷0!‰ 2BÕúæ´0=jѯ¿¡Ü»¤|Ü?”sl„7´¦^ä7»­KËÙ4B{c‹ÓŠ{I)ãämš 4È J‚šºÈ²ÄÙ·.Œ×qzƒÊC‘+âÜEýȽvû=Îvyç•ãBcB a|Dä1¼M¹ ¦èñ4,Ê`£!™àO”W!3 [t*±bÞ­ŒMDÙõ¿.,OËU€“6‚©6­6qîâ$o¬-*³Ê9•§¡° Í‹y+óÅ4:ŒP¬D¤jÀ< ØQh4+Ðà6w>Š~|ÔZMÇP™´/i\ 9?ê*fÔ9~<ñ'˜ÐHoJõ+W„y|Û¯«£ýDB£$ *|ÐTc_â tï%4½³Ýž/ýÝCLû0Qý$ÇDBÕZH}"@e‚~¯B¼~Š:Œ2,°ãPa‡ì¦k“Ä=]Š¡.ò „¤/„p»zóö´" P´Vc ¼ì¹ªïÞlù] ©Üm•‡^?ðvŠ÷ÝÑIŸ·û£IOJÈ PSÊÛÊ—‰½Á#d &TÊÛBòº <™Ï>¾ºx·ìž>Ÿ»pÓ=Ú¢[¾Ïm˜¸ÏçÝÆÝ&ôçrOJmm‡6IºÝ^2T›Þ¸âe·áññݦÏ刨v¹é)Píæ„ÙíÖk(¿¾LºûÛ$ã´«%”^p£ÚÚÈ¡»KÝw—£å‡·¨(méšnœ; wá®tÑÚœ1L8ä3Ͱ؛Qí„. †\?´Uü eŠÃtÉE` ¼5!zyo··É~&ḰdИ8Uýn0Äù³Fž}\7Á¬ èÆäe ^VhOÏ,‚ØHjŒÔò‰å fß!•GÖEÆà§Zd¹©úb=ÃćcË6‹Ü Ѐ!å *°ff^T³ë‡©Î Ç‚R£UwWYú’S˜"ÀÇFÉÖÇ¡«‘…ëR\î¬_“²¥ÄÚ"†éç ×S­¥mó\:‡I‘u7ÅýE ]0êúÛZuS„Aóƒ['$Q^ÎËܦ…í][Žî ž7´˜gòî_4F2ñ\†6ŠúªÎkóM–}=)…Ï•âõ"þû4LK« endstream endobj 2307 0 obj [ 2306 0 R 2308 0 R 2309 0 R 2310 0 R 2311 0 R 2312 0 R ] endobj 2305 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2307 0 R /Contents 2313 0 R >> endobj 2314 0 obj 1313 endobj 1264 0 obj << /Type /Action /S /GoTo /D [2315 0 R /XYZ 72.0 720.0 null] >> endobj 2316 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 562.187 250.77 571.067 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2318 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 562.187 250.77 571.067 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2319 0 obj << /Length 2320 0 R /Filter /FlateDecode >> stream xœÅXKsÛ6¾ëW`rHíL„âI™I§nê´î¤î¤Ö4Ûˆ‚,6©Týû.HФIˆR.®ì‚¾}cwÁ/ŠüMíC …ëÉ—zŽ"Å÷ê)é!*0“hê±D±ÝÕ°ýÕ&¬Ð§I2!è·Éí=,.Àã„ôÉ•à›ÉÇ»BžWNÙÿ"•¡ôJéÿ —Îy² yºÒq\3ßΖ y53o»×–®Ÿ• Õ°Ò§zÔƒ´j·k Ÿ9A“_f“ßKD š-Û8WH öY` ÍÖèöŒzòüÍþ˜\ÎðÌV8Òònôሂc}B}¢Vé\U+Uét­×¦RÊaá#`âI»ß¯Ÿ®f¿Og_\ß\¼›]ýu*tƒ¡’`¡`¿T|ˆ¾cLõÞ]~3á¶0H£yºØ¡t‰ÂtaÐcT¬¢f‹L'¹‹(Mð^åPDPL„½ŠðŸ:ÌÒ=à°Á¼KꢵÁnvI¡¿íƒ%ÄŒ·W¢üõôö…c§UkÚQ©o+Ÿ¸È¿ülvh/%}™õ¨….ô\çæ *ÌsIˆ^f&/F¸qââfwçNµÞþ„€×6.Ž»‰r†6ªF_dÛµIŠédþÑñÖ䇅¶n“+q¸-48Ôª:€]4Æñ ›™•Ÿ±†(ÿkÂâ0_åc¥,)Œf«(‡#Çha–,ˆŠ+ƒ¾Z;ØCôª^˜îy¾ÂãÖQö9S%ÄУnË Íþå›ò á(PÈW‚×n}n¾Ð 4¯€–·)3J”<ŒBp°OJC‚£º3&ưøx43&±¬«³Õ¯&³hÓ¦„ÙZ@`®d êtUè ÎÀ9l€r†Ît;줙v2êŒmÀ4/Ml63ùÆ„Ñ22‹vj¾kÇ#ÆñPœR‡ÄGOó}€HB â_·"<®¢pÕÑ­c‡aü»µ¨·uˆB:éeekx(bàrЈñJŒ*ÊŒe ¥GŒÙÇæBÑó­>BGΙ?†m˜×årÿZ¬tѾt*h3yµª‡ƒ*~}õÁ±S¹‰¡î¡[³ÖQ|Þ,³tmß6qº3&Ánݾ­&£Å=¢v[¬‹ *`™x1M §ÍQÅN xwö"6I”üœ§_#Sà4{xáû| s¿ebwçýfÏbƒ¾E¡'¼;Ûn Í43aš-ò®²C‚ô‹†¿7úët££,G?€$g¥)Q¥Þ4Ió^?ÕÒ¥§ }߸¹œq€wÝB -ü Q!dß9¨pšÍAÃë{ç´#—ŸSôÍØ½YŒ% e”Cß¹ï "¸D].—`Ø|¬£€¥"Ïýº»|·ÒÉX²-ÿ¶°̽”s¸FƒHŠ3µñê&Õ­õÍ <@—ºÁÝ& “Å;ÛÝ5K´»®ÀÍARà(õ½òqéamš†> endobj 2320 0 obj 1434 endobj 1380 0 obj << /Type /Action /S /GoTo /D [2321 0 R /XYZ 72.0 720.0 null] >> endobj 2322 0 obj << /Type /Annot /Subtype /Link /Rect [ 208.154 491.377 244.264 500.257 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2324 0 obj << /Type /Annot /Subtype /Link /Rect [ 208.154 491.377 244.264 500.257 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2325 0 obj << /Length 2326 0 R /Filter /FlateDecode >> stream xœÅXëoÛ6ÿî¿‚@-)fQ` Ðvé°!ÐÙh?4ý Kt¬M–RKNêÿ~LJ$ڢ䬺$ˆx÷øïNü<#Ãï\>˜¢t;ûlæ )b™â"¾G9Ú"3樫¬mGðЋ`°Afå £_g?ÁË a`xšáÓíóböÎ’/ßào.ßÖ€ú¿h uP¨(\(ü…žçè÷ññ ¸n¾ŸU™žƒ-[¾*Œ§ÍS+¢‡Úýµ÷f`·…ßN8F÷³×ËÙo9"-×}œ‡’‘`/¢±ü¡h¹E/HD.?¡åï³›å ¾±×@JÙ= 6“#³¸¡1JÛôG²Ú(‡üÑØÃ—ë#ÍpûÛb9sûj±¸Y ÍÙ­' 6d –AJpÞQž2Ð)t›× J‹¤®EÖÕ5ɪ€a^¢Å»[”%@'µðZB‡>ñpŒaÓ@oúv_¦M^•-ϸ¯‚Øã$Šã_-e“|ic‡0‚¹1à "ÃÔωّïXY€±scì©›äÉnýÝßâ€Zu@™}Äí«u3j%NAã2(uÉØU•1e\Räbœ’¹ÜÛ†À¨X9?_£#WOži7°áÕî~¿eS£¤ÌÐû¤Ø÷û 5—qÁ#ócúCçŽK‚.Ñ{ºX›î&öµÈ:¢©ú…yш]ÿf#ºq-’]ºñ:úõ¡fbì‹æ‡nbÜ6†‡pb:TÎ3ðRÞF-eÜŸâï4Èk·­O›<ÝôT^±Í~×»()ŠA¶/ËL$Ò„…7gL=.s•Oƒ±w£:`¬Dš¯s¡ $œBiq2”ÜÚ"•{q5Êialf4ʆ°q6SHÓÀ‹9‰cq— …d—ͳռZý%ÒñèöáÁûŒƒÁ8óÂØ>7_’íC!Æ;H jŒ=½}Ä™IwGmôÝåIÞߘžð@/xwñâ§´¨?óúP_]ÙÅLCºÊï¯Ñ™5ô­BÌ“,ÛA,_;„Ã÷×±pùupfßv»sëÒjû”—X¨ÿZlkεӋ|ÚóèJ zñ=L'ÛU–€‹Ó»Kø/]ˆò¾ÙÀ >lWU1/á#T.¼š€µò1ýt(| Œˆžë{‡áW@ÙBôß|¹ÐDèü)ãòŠÁ‡L„™ù¤…ݬ×LÇsÈäPl#H;Ð/·U)žq°y _Ø"_)i5W‡î6¥¿Ì²"&¯:ÒíÈå F‘J0ýÅÌ•ðìZŒTRu©-GP…d*T5Ç”ϺÎ9sqPìá#×Ý|I…ªÛIy³OäxÒ‰ï{l̉J‰w³7(¶ endstream endobj 2323 0 obj [ 2322 0 R 2324 0 R ] endobj 2321 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2323 0 R /Contents 2325 0 R >> endobj 2326 0 obj 1399 endobj 1519 0 obj << /Type /Action /S /GoTo /D [2327 0 R /XYZ 72.0 720.0 null] >> endobj 2328 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 526.52 250.77 535.4 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2330 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 526.52 250.77 535.4 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2331 0 obj << /Length 2332 0 R /Filter /FlateDecode >> stream xœÅÙnÛFð]_±èCá½—K*uJš"M[hl£ D*bÊÃ!©:úûÎÞé®ÅwX%i`´l¹•O›¯VDƒÚý=iîÌÀv? œpŒ¾Ì^®fço8"­¶]ž IH°ãÓ@þ(ZeèúŒbþä­~Ÿ-W£øÁ^RÊníaˆ@`}Œ192KW£´MÂ,ÖFYÜàúˆö¸<ïk‚«Õ‹ËÕüêÓûùåòÕÇË×ï>¼EšAKF<ÏÁ¤3ÌÇ n(C1E€®ê°¬QoŠ2Jò/„£M‘eaU¨(a§Ú§uå4v‹.qp€©§™¾Ùç›:)ò†æ´Ë¼ÀáÄAŒË®y~o‹0‚¹Ã¹2ˆÔo`¶ïZNVÒØyõ-·½X%üüw|@V Ó@-ÊlÒêÃ]|ÒÊ­‚&dx6QX‡ë°:-GÝŸ±œ‹_ÑÃÑ!Œ9Œ]Ì4Ý‹òË>‹óºBèÏ0ÝÇÕi•e´¸˜ 6öÊèRìYH>æ1z‚æŒC8+¶\ïzÛ"M‹{™Ã- ¢vaîÕ![iµè0‹&ÙŸõp&é{BËÞw½ÓQ¼ áô‘àº8–0¦™´’ÿØN¥‡3íÏ€8®¬1Ôóí`÷éˆìEoD@¸#¨ÌJ'¢bý5ÞÔ§å ßÒ<— ­vI…î“4EÆ…ÜöÔÀóFÌSçáD¥$p<ìaL}“à¯ãjS&wý*d­À.sÌ…HÉb.D`±åÁÔ`›¢o¸ß%›]³0ñ©:¹-ÝÊù€•%¬À€t¶RwXBÚ£J*ûún_7‹¼åO dEÙàÖeF›°jȪºŒÃLÝoÅ;Oê$LÓƒYÝ·'ŸBÈ£°ŒæZîÓgÓ<10MVBðu¯­Hz±5}°êP'ë4¡Ø!òÒQÁmB¢Hõ-mÌÉ€Rì:†ŽZ¸tz)}ºIÁ>æpm™vQœÆuü½•CÃ0&°I½²ðÐ-Ö=_î«¸ïæ¢gJÔÛÐLÃZ½nm©Ã2 "h“çø]åW ¾²½e¯6(ŒÉ4§EèÜÖpSãšõ?²yvb¶-85@E…9Ó€Yôžì¬4 S´­tuõ4¸è×5…i Zeq˜w{õ.ìŒ3ÅQÁ'Ü aìvÝr…Ó+¢zeª‚O;ZãQ¸EÄã ·J‰Í$p1µÐw*„eÜ-t"đӡÞm£.¥Ôq=hh”ÙÄMÇÓõ¦h;ñIϧGƒöë.λ• [cÖàl¿GiLÓ¥2Ô¥ø¿„Ò„áaS’®ï<þf±î½"/n£¶¬$ëî(ZÐ]XU꾞n¨ ª°'eϳȞŒƒä™ EúÂÃEWä#¦Æ<(¡?»ÌÌLËïav—v#·í}Ä ºúÔŘ3VÞØÞ=h!ѺÜ<ßO%â˜Mûd8:QIƒº»©Ñu =xžÃø-T¦\Ç }qˆ1æoŒ'dù-îw1$Àõ…f–D·ˆX¹Á ûnÛ$N#¥c…ò$µð¡CoÚù¤a}‡j›#]6täóçЧ±;Çbe†x —. ]GPðÎ븪Ï%$_hWË÷ËW+$ýø—Ô½¹üøjœˆ>ÿ¶¼\¢›3ítˆU>Fèqò¹Öïã<É­\½a´@ß›³ŸÁOV aÈÃ÷€Cf¼GôžD1Zn·fÕTõà½@x˜0bnéÈÜw‚vnïG‹®Ý7ë^¿×¨þ¨iPfèñ¬ªb“„uÜc}ŸÔ»n5UŽ˜Ãe?cDXŒyx¾÷É}OÉ2îjfä¤*=+‡ô>æZä0[FiVšMRÊj}<¤X3/="`ò!œBp×¼_UôU]ŸÌ{÷1øÀäÎý‰ÌãàþÀïßM¬”aŠ®’zªÑ~J¸çºƒŒ‡¹Í Wçü4ûI‡ endstream endobj 2329 0 obj [ 2328 0 R 2330 0 R ] endobj 2327 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2329 0 R /Contents 2331 0 R >> endobj 2332 0 obj 1670 endobj 1529 0 obj << /Type /Action /S /GoTo /D [2333 0 R /XYZ 72.0 720.0 null] >> endobj 2334 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 533.128 250.77 542.008 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2336 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 533.128 250.77 542.008 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2337 0 obj << /Length 2338 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_AìÃ3Ã7‰’» èZ·ë5kb¬’`m9Ö&K®¤Ìõ¿ßQ”DY¢å Å:'€GÝû£ãÑŸFø«/é3´ØŒ>U<Š$CÜ­XŽ‹¨ÀÌATÑŠÕS-‚Õ|釀X££dDÐÛÑí=l.݈tÕ•Â7£-ûj‡|sûm8eÿ‹ʇ²*e]üK\ç`Ãäp§U¸†o¸¥A®yÀѶÕV\eºúÖŽhRÇ£¿ÆALÄžÇ*Âogœ ‡ÑϳÑùQ‚f+ƒs©)ÁóÕ‡¡ÙÝž1"ŸÝ£Ù¯£é¬€oœµ^!•í&Ž(Ö#„Ѓ°ÊâÊ*(Óû`ê ,ib>&®£ž÷´ÀÍìê÷ñ͇ËñõôÕÕõëwïß"-ßHQÇÃWÆ=Þ—¿cLvÜ!tS¤[”…‹4[FÉÛh‘n6A²ÌQšÁNþ9®£–(ÅÄ' ÓÕ:ß<&‹"J“ZæxÂ\;Ôó}I«„Ýì“"ø\ úc”pì•d¯¡üt¢ö„åÉbçŸâqo7WF‹ïÿ÷¨v \êxŘͭb¿ «¡ŽÍÆ2(‚y·Ã‰k³sñ:]Ê æ¾$„S©å^f›0)rð@ñc˜wYËaX:”I,Yé½TyÛ¹JBô ¹=à,]ºX·6Vi§;á†UÛA™ #ßoæiœO gRcý‡¯Â|ËhÖڧźõô2\ðôá"=´0îÂLÅéŠNœ¥x8Ÿž€®Éq·#ÀžÓžØË¦þnO€:X2…Æ ¢tþW¸(ŽÛ•–"˜´¨Áh¶Žr´‹âU)D¶ç=®Í<ǧÊ(Å\@WãDhí¯Ã|‘EÛv²¶_α«š¡ë;UÿQÞ—ØGg¦/6, @M«fÙ,š®ÙprxUÌJƒBÓðܹUm§A\Í(³$\Î*K7fu%ìz*ÕÐûžÄ ÷ù¼qa·Žk³¬ —·îÀ^e\yw ÐRq¥Î†Îfú ׋& ãÕ€ÌRWFÓ”ªn( >8®úî ö'Æå¬1冞´¡YMêôrIk·X­ +ŒéE_U±J4lÌ‘Xê7›>*ОTiÐÃ"Qïo³JRCÇiòff= ­_«p‰ ëÝÊÐC'-ÅŽ'‘Üâ×pñ ^²Æ|U¼’nŸš‡NbVuuª°:϶ßbÍ©ßâS êc8¯a8†‰ä Ê¦Š ÃÕ¡T],ΰ[KÓ¦Xz­‹¥éƒbiÖu»-jÖ&ØÛÅÕ̵Õ)ÐŒUÚ6‡©Yµá­9jÎhybÎe-ݲ¹ òüÀ£ä aÉÎ xT>=Ú‘ÐýÚN9<á âÄÃŒq褺ôL?›ml¦(ÛÄËÄC@••á;Èj‡£,š¨´/wÏú­—;¢£¦™sݾµ0†£ÝÆA^Œ¸ÓÜ£I‰äÛ¼O÷!0,š`8Ô„ìŸÉnf!º½Ðú¢å=¢V…>y¢ÂUÆËÒÓ%QÜW%H7§GUÅA±E…-£‚v3úâ‚#ÆDŽ¡ÂÔ6ëëšôyæÅ¹¢Ôô}3½œ¾š!•Ð?•›èÍõÕo¨Î&úøËôzŠîÎt:ТVû¬[ª§ÙÿñT_†I”XµònÙÀß»³ïJï¬N·.w–«VÏê-¶*r»U±BTÈnÞ¿¢Âëfð+!*ü§bþ$Dánðõu˜Ê¨„ v}ÃîCDL(ý¯ êpѱ LŽp;:ÊÓÝÕ‘SBáÔ”õ4-C4]­ùPkw| G] ÜJRžjÂkN¥fݦ5˜[Ks0jÎ> endobj 2338 0 obj 1551 endobj 1522 0 obj << /Type /Action /S /GoTo /D [2339 0 R /XYZ 72.0 720.0 null] >> endobj 2340 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 519.516 250.77 528.396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2342 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 519.516 250.77 528.396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2343 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 141.786 234.0 150.186 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 2344 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 129.786 228.0 138.186 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1529 0 R /H /I >> endobj 2345 0 obj << /Length 2346 0 R /Filter /FlateDecode >> stream xœÅW[oÛ6~÷¯àӵƛD1À¤kZ´(Ò¦1¶‡¦²LÇÚdÉ•d¸þ÷;Ô…ºQJö’9||ÈÃï\>’?aø[ê/!) ÷‹µŽ Aój•ë!Âê¢=ªeÅzVG _Õ$vè¯E²ÀèýâÛwÜ §.Wß/î:øz¿8~×Fèÿâö¡¬JY ÿÂ)‹Óp9ît gô­¶d•4¶ŠëL×ß•#•XÅS}OÆÛ0°=u„/ŽÑãâÍjñë;ŒVÛ–çBìøTêE«=úvA±¼üŽV7«^8k£BjlC ëcŒI/¬²¸¢ªŠé6Ø«*(K¸¨t°çêù~ep÷iùõæÏ_ß~¸}¿ü‚*ccB˜t$dÊùØøR14àsh¥ò"G§*v*CŽÂt¿’MŽÒ e*?Æ0d ­U”<‚&L³Ú8MPÂ'–P¼ åÝ1 ‹(M›éüyÒq‰/¥ uþîÏIül ¥Œ`á0¬ƒ5*?ƒ<øÜ23ÿ/«ˆ ¶åa˜:a³A¿ü£Î¨ñü¸DKÕЪ8Ôd”Yf0¸ cÁ:Ègp|kº~û½.ôÓõ! 06IVY_gǽJ4I’ ú3ˆ*Ÿv\×Ë£Žô`mOqnF{„`Ïbò9Qè† q|t‘n;?€È_Û4ŽÓ“fn«ƒú äM~Þ¯Ó8¿ê¨®š}𺫬7DO·N‹]×™¬;¨¢rcµšÚ°x4d›TðanRdg4ùA…Ñ6R£YŸ8Ó|s¸,eœŽŸÝÌTŠSƒ ÅoÄð˜eÐ]âÖ1•ë¸ãó6Ížá4“sN?¹S8iÏpü´‹ÂÝ`_ëêúr€W19/ûuq+ÑBs36Ÿ˜¦$÷-xóEÁdÆÔ`‘×ʈiÒ‘·F´ÏRÕkž¥Æ´ÎÒ:kª¶ÙΜìš]þ÷£íôÌ×(Õ+"èJ“ç"qqÛFËÝ~ø4Ý2<Æ‘3U³¤sašîŒ=‘Ð\y½ÀÍÏ`ˆÛÕvÿapgêèydŲw»AWšmb.-™ôÉ`)¸X¦Á^!öoRÏAãØ£­,óÈðÆ2 §ùd…¢Ã”©ko&¦`¬â¨Î&h"2o˜îÕuŽ*\ºƒ{Ø}´Qèf»…s7Ÿ;i\ŠË+%RÔü†-ü vº°I|_`ÊÌÕ¯DƒV¼>›w[ûlÒX°;<¿áíT¾›FôÅ&ôÞ€æZß„zuÿ÷ÕÓÃäâO<í<â;®ÀÒg¾lvg¨Ê“=€gcT-Ï&ßãðŒÕ«›²u’_:q·øòòÕ endstream endobj 2341 0 obj [ 2340 0 R 2342 0 R 2343 0 R 2344 0 R ] endobj 2339 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2341 0 R /Contents 2345 0 R >> endobj 2346 0 obj 1194 endobj 1541 0 obj << /Type /Action /S /GoTo /D [2347 0 R /XYZ 72.0 720.0 null] >> endobj 2348 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 536.148 250.77 545.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2350 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 536.148 250.77 545.028 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2351 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.104 234.0 82.504 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1519 0 R /H /I >> endobj 2352 0 obj << /Length 2353 0 R /Filter /FlateDecode >> stream xœÅWÛnã6}÷W P Hk–¤ndÐ.àE³E‹mŠ]íÃfd›NÔê’H2¼ùû%êN+éKoÙ9<3>.Pü-õ'vÉâÑŒ188¾ò|`.á$`ÚÄzU¯Á›~êEظ‡¿é‚Â/‹/_qrN :Þ®^/>õôëúêúû8Œÿ/hªS©Î…ã@ªÃLx.Îô®ïF+…N=†#µn=¤Í·6¤nÖþÔß³~ÐÎ jÇÑxøzÊ)Ü-Þo?|ð€QØ:žZQ"¸Ô6 |¹àŒ]~…Ío‹ëÍ„¯ŒÚä µîÖ¬ ”²[ÕáƩڧ›0QµS\\ê{z½¨ÖŸ>.×›Ï׫ߡ–kW3æè•Eî–ó`,Àçà³*yZ@y¯`›gá~%e®ÂŽ…ÚÃ!Ë!W»,ßGé e°Ë’$L÷T3Å1. Ò¸XÜs¡’¢R¿Vúá˜îÊ(K™óHú’xLH0ƒäú)-Ão ´(cÔ'ÌÅ͸oÕßáZVñ²v} ¢k[ßÿ£ž 1MYõH•O꬜Z×Á™MÇ>,ÃmXÌèñ¬HýôÎèóG×áK鸬–^åwÇD¥eHø3Œª8o¸>*OW ¹ëL±™ Úkù#U*þ²8ÎNš¥x.'$,OÉ6‹‹+¸êsöÊö-ìÕ!Ä–)³n™7[0"(GH¤g‡ÛnúDlÕž«?` ¸†ó…mÿV»ò¼Þ@ Àm\X¶!°¹ 8EqÜ@¡qxcÚËFÍ›y@´„1Ì1>7D’È ÇTh5M@xXg)̤O<Þ$¶Én7¿~<«ŸëJá¼(yžýÜá#öÿ¬Š]=ôóš5Õ{ÁˆÀM¾Äap¡©Üv:HÚ!ƒMÛ¯²tÛÓéºíty»Ò ¼í´QÑmŽÜ3%ëÚÃ}«êh'väYÏÆþ86P4ó–£$¬ÑóÇá?vxcO%*£<Š•ÄÅé>ÚÝ÷ú†÷EoÈ Pw,Ñ›IÒŽC$—È#áY,šÍzÉ…XÌ:“ IêîVõ:Y:èz«Ì‚¼¿ Í– X–3Â43ò¯ÆPö”½mFôUaš{Uª<‰RU4#§{…Á7Ý&0ä äˆ}ØŠN$,›v'²‹9ŽÙEˆŇÔÀXü•ÎÈßqMt>8œcÁéa~¦ »þ&qwqÚJǘ|\}q›²è ór© ˜ÎŸ+M¬îV»½œï`>Ü KË2Á§ÛbéEФ;UôÝïÛô¶®¶z7•t±Ly^·ÁܦÚec¸Pu{= V:c4úµãÜAºX—àýQŠ…e]©F{ׇ^ÏÅÜ…à |or&…+Ly|ƒÑúîxŒ)å0¼[UÚäÛ§9žOj'ÿ«Fß'Ž–lغSÕ•â›)*¡nϺ‹âDz¸{ š²1•çµEt‡[ÅèBt˜+¬õ‹ÂÁûÛáÒ²ã|é{s²ÚŠ4+!«ËJkÝø¨|&±~󥩵ÖJÁ*.²öqÛ½-ßñˆ~á³z\Nž‚ Îà¡l‰øÞÃYÿþÕº=R endstream endobj 2349 0 obj [ 2348 0 R 2350 0 R 2351 0 R ] endobj 2347 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2349 0 R /Contents 2352 0 R >> endobj 2353 0 obj 1250 endobj 1544 0 obj << /Type /Action /S /GoTo /D [2354 0 R /XYZ 72.0 720.0 null] >> endobj 2355 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 490.252 250.77 499.132 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2357 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 490.252 250.77 499.132 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2358 0 obj << /Length 2359 0 R /Filter /FlateDecode >> stream xœÅX[oÛ6~÷¯ ú0$A­ò¢«‹ KÛ¤@×ËÚŠ$d‹ŽµH¢#Éu½_¿C‘ºX¢íô%s èâ9ß¹*#‚0üˇP4OGz "æê-ÇE͍ƒR¤i%òT‡ 5uˆ%úk”0z;º¾…—ÂÀ°ᾸŠùjô¹ƒ/ßà'ÇïjÀý_4:TQ©âBá¿gUÁÙyáØx÷M'pÍ~»[2µ; [¾J´§õS)¢Hezîµ·f`³µ…OŽÑÝèÕtôâÒA£é¢ÍsO2lù4?Ц)º>¡„Þ¢é»ÑÅtOìµA %vcCëcŒÉŽYUp=m”²éc˜re”Á ¶h`aבç}ÅpþæÍøêóûñÕôËÅùtŠÆŒ‚²'JHÃJ˜o9P:rC©×g°1´8çQÔ.–œ‹t%2ž•íV):ô’·‹Y.Âh³E™ó0-ÚuÁ;@ ‘·‹œÏEÅÙ]»ÙQ% ³¨èYÞ´ Øå‚¾v?ˆÍy±Nʪ£à¢à0 Üá*¶Ëu6/c‘Õ<ûîË´À#ñj›•áš10€⃖6Æ´NTýzæø¶ádEãâ!+wöCì…׺€&=eˆgÂèÊ6X@¥œ!Ê/÷|{ŠÚ®«Ü®ø~ ÏtÃ3aDaÎÂb?£&/ _Ó©s< ˆíZžÌfªâünB±} “5/ö+.“Â#e,˜ÃLaô‚]Ó9RlHÖÓ>ƒ‰ã€º`‡ëƒŒé~L—b´[0Ë–ÅÉl:Œ¾Ù¾˧Lµ¦Á‰X´tݪÅB$‰ØÔ ¤Ú‚ìÜ@Si7Šm:I1iw&u_yÞÙÓÝ£šwÞÎD¹ìœŽø"„Ó;ÀºI6ã~Ñ‚;=;+=ûZ¼å´pì˜3ÝèÓ!Ûy“)î€@¦P¬‡Æ^@$fÿðy¹×ó-Ï16õ b,4]ÆÚÄI‚´ ¸íLÓãæìˆCìÀ ä쥮žj»õkvÇ€i ™m¦“*%ëxýS°Ï%v`ªKá /æy¼êÎÓôg˜Y„IÇøõø"™lðN§´¤Šõj•ÄÕ¼¬–ªÄÕâ@w—¦¹ºZ‡HÇú‹ïâÖè7ªºŠ û8&–LnÌ\× i»¡Ø;ĨqgE eæÑX¬ËÕº<»9ÕoÂÚ§¡~vo3r]µ’]§wo!rÝ\j†×ebr.pÊ&Yë¨h… hu­QtOŸ„þØ,ŠŸÇ •jg¶mÈ3‘1‹¹Pm.TðPσ-˜:ðú˜Û3ð6è"{Œ"pçl¨4F\ƒ°£½‹Á„>Àßh°YÆóe³Ò-¤h}*ògû ƒÆõÞ“î9 ˆkt’®ÕõX­f¼¥EÖ],Zzw@é== :[jBé×Í„RëÝ ¥öÔ„ÚñÏ¢–*âšÞ,9¤tV†a¹D ñƒ³ºç.ª{] ²>ZêY G¤YhÌù–OࣇÚúbvñ#LWI{3]Ðm ›ðuä;LO¨Ð6ÌËêêÝj7© ´qÙÍ©éƒÄ퉂k¥áõˆ›¸\êF6.…¼ñKLÐDvµ¡÷$ 8»û¹€ŠG©ìPƒ¤ —ã‡5Ï·èºà Œ{tÍÁ•qt‹®q^”ã ¾ua‘„-ÍÓ0NnÑd‘‹T[ÎooM¸}¯£Ýߤ¶âæÔ¨·ß÷áË—0B°=ÆÞSÈ‘ ó'¶WŒ¬|Qò¢|!)yÏ¿ºxñzŠ”9Ï+cþ–<—¦(ª2]~ùôÕV U€D{L´Ò÷ð³§W•ö½Múš„QœÆ98û=Ïâ¬r{"©ß ñ=æ¥%ò;Ó·jõ ÝÏtŠÐ;Qð…ŠÞU&JbQQ=‰v?žLª%2Ó\”Åý¨RQ» Ý~tl„>Æ÷qVÿÈ×Å|É¿#t¯©‰^?ŽŽÒ0Ž*¯rþï2“gš:&ÐïÅEèÛ:µÉçY”‹•¡¦Ž úAñÀN‘É‹ ô7Ü‚îš×TWâP ‹ûAñúß/eÊÁï­ÈgaåÄ»š:"öƒ€ãDc¡ú}ãÐñ«¼Ù*êX”]Ö 4øNbÿ¹.ub¯$ÕOìg‰¶¹1uþVùyôѶ endstream endobj 2356 0 obj [ 2355 0 R 2357 0 R ] endobj 2354 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2356 0 R /Contents 2358 0 R >> endobj 2359 0 obj 1644 endobj 1547 0 obj << /Type /Action /S /GoTo /D [2360 0 R /XYZ 72.0 720.0 null] >> endobj 2361 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 472.898 250.77 481.778 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2363 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 472.898 250.77 481.778 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2364 0 obj << /Length 2365 0 R /Filter /FlateDecode >> stream xœÅXí›6ÿž¿ÂÒ¤ézZ˜m°Á§­ÒMM'u]§k¢MS¯H 69 Kóßï16Á€C²MºåNŠmxÞ~Ï«óknÍÀvµ…/'£§É‹É·o"-Ömœû’`' B~(ZdèÓ %ìÕg´x7™-ð¨ )eŸìqÇcÒ1«v®¯R6}³XeÁ æL¾(‚7³÷³Ål:x?/>ÎîF¯Ð”Ð÷Fñ9Qæ9`{Ôòy¤Ôïð1‚VÎÇ8ËÿŠÛ}Ø.Wy¶Ë·ñ¶jÖEžµ»jc.‹<ŒVai¼]VEfe{°/ãÈ`–í¦ˆWy%Û§ö`ézLáàŒ@ƒZfá6*p+ârŸV¥Ó8Á·8¹ àŠþí~»ª’|ÛМ÷wZXá-z~ÜVá—†PX„É‹IiÓÈןž]gy3ŠÓ¸Š§ås:U@ö=pÿFP¦§Ü˜¼-FPjµâëŸf¿ˆ¢ÜfQuÜÅçVA#2„µ° —ay^ŽëÙP@ß¿ÖÑs9ˆÇ „\Œ©«‹Ù}ñ´Ï QJ‘ˆ~ Ó}\žW\Æ_xÄ·¹aP=æ¢{¤ÈdìŸ5˜0æøìà>±ðXœ—ÉÉ¡3n¡€K<¨?Œ^oá€è_X8àq­…Âq )!w¡þ3N†ñmµoHò˶.¡.ƒŽw“¯Ûµ®­j³ÎÓ4?è⨎þŒ(˜íAyÌ–yZÞµ'wMiüÆ8Ó%ÒZO—yµ1ÞŽâuowWyW´_–¤ÔíÙYëqO™VŒB¾‰3¹lÇt@vŠ> )Tæ4¥#Q¾ü#^Uçåú >ÖÍuÀÆA‹MR¢C’¦HCˆ¶[½ž6bn/¹ãÉð \Å·[ ìhôiGaAßU‰ä\®oPX¨’"ð±î‘oârU$;³MÚæ—d&®§¥«é¢Ž6œ‚Z.Ëýn—&j¨÷*Íõn¤‰q¡%¡l/ŠÙu#¾sz:wfyЙy†Vè§ÇÆš³ Û ÒÁÕÅ}3wñ*Ykøˆ¼Ê€2Gc3 &ŽÀ`µÎÂy¼†Q6FkÈÏ·×)ãQ‡s¡ºÊáå5{„ÞÐá°IVc¯s±4ŽTeÓK²^e‘˰ì“ÐR\öOáu}oŒÖŸíUÌ5®;Ðwvkcc«×2¾À ]QmÛ`ÂlÆ‘ÞE·o¨}·o¨3…®~¿Ó™š]¼:$*ˆÔú°‰!‡ ™Íå£Þ´y§öIi¼4hTU> endobj 2365 0 obj 1431 endobj 1550 0 obj << /Type /Action /S /GoTo /D [2366 0 R /XYZ 72.0 720.0 null] >> endobj 2367 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 507.516 250.77 516.396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2369 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 507.516 250.77 516.396 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2370 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 141.786 204.0 150.186 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1544 0 R /H /I >> endobj 2371 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 129.786 222.0 138.186 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1547 0 R /H /I >> endobj 2372 0 obj << /Length 2373 0 R /Filter /FlateDecode >> stream xœÅÙnÛFð]_±@ *fO.i´\Ô)R¸) íCœJ¢,¶<’ªí¿ïìA-¢@êÐìpç>÷ó‚ ÿ–êGÆm‹Åg‹#HRÄB‹!"< ÈÂåêV ?æôÇ¢\`ôóâã'ø¸CxÌN¯ï{òÕüÕå÷5`„þ/(tTt\(ü—Îàƒàxø¥¸Þaµ@fp€1²Õ§ÜzÚþE hì1¿gíÀÎ ì÷£µðë Çènñãzñê@£õÞå¹T„ÕEë}¼ D¾ø„Ö¿,®×“øÊ^›RÉ>ÙÃÀFc20KWZ£ŒMï’"5FyÜÀ#Dã‡BÝ ÁÍÛÕz¹z³\­?\_ýºB/Ð2ŠÐ…ar"%œ$ XN™ÜR*ÇbŽ “r“5m·‡´·Uq_•iÙ6¦Ú{®mê*ÙmÇ¢ië4)NDÇ&Ýuð¾ª;°N·U½ËÊ»æ÷$/G–€×8ýÁY7I¹k°¬Ó昷MÐù\z|.X€c Ƈ†øÍ±Ü¶YUv4çÑ@€ÌX+wõT¶ÉcG{„ +_K+é¿‘Q÷ÜÌ!Ëæs¾´~‡4Â>ößþ•>¡N%Ph¤%¡‡ª}ºOÏšA¹WÐŒ KÚd“43rbŸÐ¯mXŸáq@1ØÆÌP_ÕwÇBg.¤ú=Éis^q0ɃXJ(ÉÔ7“&8ôüVê¢`º–­Ûj1‡}•çÕƒM|ƒ‚Ø=@18DóTlª¼¹t˜K¨ ïßõp6ï{BëÞ×MÕz·wé>ÛÁm5”0®:mgŽìÔz³þ¤Ðç9ã Éýyàõé”ìê”pá„€ˆ@R•”ÎDÕæÏtÛž—+£@J`éô° Ðú5è!Ësd]ˆÀm/-¼ìļ|Æ!Œ1†ìå]†³ÛïŽ ÑRí!x¾&hÈ‚ˆñ8&Ü’þ”6Û:»ï÷<ïlŠâ@Ä, ݇´=Ö¥iç2à®÷ëCÞÍ}²BçñáPýÉ Ý<˜òN•µ;'ˆFu3¤SÀLÇa I~ýWÓ‰Ã0ú¨ ®è¢W|B9Ê ;ƒÙ×UáNçóƒpH©ÌY<ú|åÄb†Ü)ðpȶw´ܳÀxÄÀžÿSÌY»P 9Õe¶©2)gHðâh²Âœ6©ƒ«²Ø;Ø×ÛT|  9uX £®Á:ŒNû±ë¯æ8h¯¥Ýi/÷Û·A©ÉäˆÛ´.²2mN¨‡C áÄ™ê0°*ºÔQ»²2çmûIVöH«.{ÖS1´Þ”ª#§q—é`¼²ù ºÀšÄЙ¹å}ý˜÷¹›Â¾­‰Ål´ÜN¶!t©riçß¾ð,‰XŒxÀ"ñîío”iM›ÔFœóÅséxužk°½þgÛÄØ? êöâ›ïW¦3ªnº³]@ùÿäåŽ}×ßZçâÍ¡ 7°U¶KÑõ~“·™7‚b½]PKûx‚*þ‚^’‘Ä”–>- êbótzQº’F#\½êô‹n’ƒ°ëëä^§Én׋÷¡ªGøß2Þ¥9Ô¼Ÿ÷3ÏÍD8ŽX÷º~ܦz°'ð”ÍÚc¢àY·‡ð’dŠ»[™K”Ö5ä,;Mv¬rpe¶ŸYø‰z‘1° Lópœß !×fh•÷I£žŽ ú[íï¨Òí°=$%êuÓË^sºìu'íÈ÷‹M¡ endstream endobj 2368 0 obj [ 2367 0 R 2369 0 R 2370 0 R 2371 0 R ] endobj 2366 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2368 0 R /Contents 2372 0 R >> endobj 2373 0 obj 1336 endobj 2375 0 obj << /Length 2376 0 R /Filter /FlateDecode >> stream xœÅRËr«0 Ýû+´lqec^¶wÚÎÜ]æ2í¢Ó§á;Mó÷5˜òe›3ÒÑãHÚhßE-É!Ù‘}kcpð–­É_”û°ƒV÷!¯Q…kV8U¶ðL ‚ðH^^­3´G‚çéšàd5¨_{ðâõÞÈ]Dn|`ѦÑ)çBÊPRËúáíàåê1/µŽ«Óõ+DÉ}4"â1þ DVMMçÍz¹ýÚìxäðŽ=ƒýwöÞÚôœÍZ\íÚ•· k¥kĩޓ³<°§Cヸhñù[ê@†4]þì\xj“EÖµçùà䢟2utd:b»…kàœ2¸2ñ:WÝ_šé÷<>uÿÇm©{¯6Õ!1‡ª·ÄEÚéIYU˜Þ7À¥ªÊ>TÝTån¤SÕg¦MV¼Í´÷‘Å?ãxÆ.†ýAU'z†Eœz"²ÐëÇòXëòNÐÑVARƒÁ¡oäùF,–Jiƒ|!§ ´±‹«t‘®åú¿JÌw¢Éj¹dT†–rošÊ ÊBA¹ÌhЇuÓ—ÒtpÉ+òDÍS= endstream endobj 2374 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Contents 2375 0 R >> endobj 2376 0 obj 441 endobj 1356 0 obj << /Type /Action /S /GoTo /D [2377 0 R /XYZ 72.0 720.0 null] >> endobj 2378 0 obj << /Type /Action /S /GoTo /D [2374 0 R /XYZ 72.0 686.0 null] >> endobj 2379 0 obj << /Type /Annot /Subtype /Link /Rect [ 377.19 688.884 421.92 697.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2381 0 obj << /Type /Annot /Subtype /Link /Rect [ 377.19 688.884 421.92 697.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2382 0 obj << /Type /Annot /Subtype /Link /Rect [ 279.98 560.579 324.71 569.459 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2383 0 obj << /Type /Annot /Subtype /Link /Rect [ 279.98 560.579 324.71 569.459 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2384 0 obj << /Type /Annot /Subtype /Link /Rect [ 434.69 561.059 518.69 569.459 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 2385 0 obj << /Type /Annot /Subtype /Link /Rect [ 238.238 538.968 274.348 547.848 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2386 0 obj << /Type /Annot /Subtype /Link /Rect [ 238.238 538.968 274.348 547.848 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2387 0 obj << /Type /Annot /Subtype /Link /Rect [ 251.91 441.399 296.64 450.279 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2388 0 obj << /Type /Annot /Subtype /Link /Rect [ 251.91 441.399 296.64 450.279 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2389 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.089 204.0 82.489 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 2390 0 obj << /Length 2391 0 R /Filter /FlateDecode >> stream xœÅÛnÛ6ôÝ_AlÀ–3GR)[,M†½ µÑ>4}P,ªfK®%7 †ýûIÑ’-ZÍ6 ³ƒ˜‡ä¹_¥Š|§æG*†ëÉÇv"ÉP$Ú­X Ê1‹Ñµë­Ì­Þ‚ùü¸K°X¢·“rBÐo“wïá0Cî&䘜EžM^õø›òÕù÷%ˆ(û_$02X¯X¿0ø“Ø:çà æäð¤ç¸ý~·kFnvos´j-Ýþ:AÜÒéã~OêA:5HØŽ­†_9A&¿Î'?^Lj4Ï»8—‘œ0e> Í×èÝ•äü=šÿ>¹šà+[màHÃ{¯O„(86!„е¬se«”ÓéEºÖN©€x‚˜ÂDÄæ~â.__]̯¦ož^½^¿~ù|zùìb6CŽÆ“&+0·4n“Çj ]nuÚh”¢Ù«g¨IoWåÛj ^xq,|DbLÕ)Šo }‡.Wi]ŸÔ>â +6Œx4$€=ž XSLËÂ]¾Þ•‹¦¨JsÚABá˜&JIÚ:hv_6ég¨Ì((ÊyÄd‹ƒìçÈ Ü\X»N?5¦Æ ÓEg’=&£"ÄÄË Å X&–þ´ìEÝ@%›NCvßý¡ïGxFAKd)KZ0SÿP7NBÒ5Û´¬Sëãú´¯dÈè—ÇèËqA£s) ‰ÖÅöÃn­Ë¦Fi™¡7éj§ë¡Á6±Ä‘¤lÔƒ4 !äùR#ƒ…ª|,‘XIȃXFC"ÈA3lPˆtH5Ë´AË´F·Z—(ÓyQê ÝÍö¸`Xøº0 4¦eNWF.FˆàqOÈ«„*ÅEŽÒ°hÆ çpœàô³b Ê׿áÍÃ\°,€Þ P”ÝúnY,–ØTÝÚUœÞY_ SÝ»SæqÏ—EÝcQ¬VnKw«&Ìò€Å'“*XåÇȘZ‘#5µ ¦Þ\Æ}Ì(ñ‚4g;]!‚~¢¾]jc[Ʊèü<ˆk*9†VxBˆ¼xúì4[ÅÆP÷¼ë^y¡ëýŽM@¤Ý¶íÐ{è~Ó>4”U=beÕѪw›Mµíà¾ùºKËj·Êdp~¨Ã­F»ZgøË•Ö” hÁ¢mõOt½Ø›~ŽJRà8†®ÏÙÎJ6Ö¡D·# *_£nï‘ Ë“Y+aø0…/"@ù!¥ÓØ(2K¤FÛ·„p8‰ùÐÆ…)å" ` ÆévÎúÃ×ù‹U+’r ÿq°åJA9¤«Ïéz³Ò# >1F÷HY­Ûa÷¨§ ¼ªÐÍÙ͹ù9ó“M›³ºÙå”›s÷=ŠkCBó8Ìßþ;;Ü΢*Km›^üzçœé eú©‡Pïò¼Xð`°Dû¡=6z».êÚx$/:óz'= BcNY!}‰\hÛ(!VfE³KÇç#Dyd^IÄ‚¶QŽ@í¬°bC2É…ŸI¥Ü¦R+*Ä¡þsª ¦á’03<¸B 5ºXÕÕþ…O÷¾®ˆH`B©yéb_¸ :A Ž^…,ì{$óýÎûèŠ endstream endobj 2380 0 obj [ 2379 0 R 2381 0 R 2382 0 R 2383 0 R 2384 0 R 2385 0 R 2386 0 R 2387 0 R 2388 0 R 2389 0 R ] endobj 2377 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2380 0 R /Contents 2390 0 R >> endobj 2391 0 obj 1507 endobj 1320 0 obj << /Type /Action /S /GoTo /D [2392 0 R /XYZ 72.0 720.0 null] >> endobj 2393 0 obj << /Type /Annot /Subtype /Link /Rect [ 162.537 379.622 207.314 388.502 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2395 0 obj << /Type /Annot /Subtype /Link /Rect [ 162.537 379.622 207.314 388.502 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2396 0 obj << /Length 2397 0 R /Filter /FlateDecode >> stream xœÅ]Û¸ñ}…žŠX«â‡(iHswEŠôÁ.’‡Ë=(6½«;[r$9{ûï;ü¦MŠëmtÀŠó=ÎPúz…²þ­ÄOÕàl½¿úªçPVáŒ0=U² Ñ—Ù>Óã2Û‰UÞ›ü¨E0xÈ>]õWEöÏ«_ƒ‡›¬„ǫ✜D¾½úàñOŠïÎß—€ ü‘@È ½"ý‚á•Kçœ<(iqúÄsœw³’!Qs0£x‹G;miý«QC¥ú]Ô£pjq;j ¿ó"»¿úÇÝÕ_*3Tdw[ç•@DE^ãFüáìnŸýú UøõoÙÝ¿®~¼ à;[-p¤àmõ!ÇÖEQ µ¤s+­”ÒéçvÏ•R3Ð:ÃM^°R¬¯Â?þ´úøîÇO«·ïßÜÞf ×b Br\cŠ«÷3ÆÕ9M!d?ðm×ó){ûþ—Ûl½k§ €Çn~ÈöíáÐõ÷ÙÍ V¤Œ©%5Z ‡¹úe–”DYþíï™çÕäN%8ÇŒÁVÀ:êÞŒ÷Ç=ïç)kûMö±Ý]CáE–e^–b?U,t{°Ûœã!ÊÝW"g9O3¬X^2û‹²åˆ3Pc=Ûc6ÃäFæ„’ê𠍂b‘@‰Kà8lÅ¿“îOsǨÎËŠE‰ˆ;ÙYìD¥qÿæ²– ¬ÚgžfàÜ-Ú{9r1«ò‚4ðÀ¸òV˜í—g´–‡M‘A7Äž岚e åfóeõG×o–5-X-{­JQ¥½Z¹átàënÛAðÙ)|4lÝØœGnÆXvâñ¡[?8°ó˜@ÔC´ï¹G\D¿'„¿ZF¥…Z_$ð]{Ü;üCÒž¤Àçöj,³Ž¡n˜æ§£Á\ݺ•=ÕÔüÐÎ>Ä`ôRØÏGܸíÝx7]ߎOnf=ìŽ{Åvï2ý¸ý²ã¹ƒß¸abïá"fÅç¢RØ^‘'XßD’¦e×Zr5\fß ¼FTÐh"oþàOË•)\ËÜ÷¢šÑN4@çžhjD7ߺbµ; ë=õ•qÕä¤"P§C¥Ñ9À¤H"Ç1a­ ™Zâ^†æ¹–6 cºó*Ofg¢ ½DlªQCÃj|컯G‚³' ¨âxa¯Ѝ¿Ž®5ñ¨ ”GêœUuSCß*róûÐõ ‡¤p-s? ´»0ò”z²t2S­ aœ]{“O|Aê31Ú~»ÈŒ •3 ¶#trú,´ È|„2ßÒxûÌù\æAœ–$FÉR±WBkP¨íúÉN„-4|ù¯çéÚNè“DŽu¦”c§ªGêg’Ö %ôt‘o¾uã|lwË‘P³¾•àäTQ’ÛÑ4ƒí¸‰8µßµGë‹Ã?N|{ÜEÌýü©y•#h¥zmnljwPÀ42´!Á‹G(",º¦Š°2HEÕ°uRv=ÄÚžo:(Òí¤ñªYâ‚톡 © mqÅгoû§Õ<¬ÄïrJ¢(/›R椔J#ßµòæò¡;xÊm¢>h‡èE`}è˲ gLÀ\íZô@»§L‰O3Ù`ŒtFFU•W¢ e@)${Q®Ã´IшT%œæ„AH E]–‡C”›‘ÏcÇ¿%ú>„cˆÂÆ9Nå`Rä´¬š—eîRG'¸UâÒzŒeÞ+3¸S>C}Åj@ÓK@m_êÈéJªxØQsy>Ž<ÑAèÒ×ÚÀÀµ‘À\ ¡Eù­¡-¤T•p%¨ó¤ë¼(ÇÇ~îvn?Q9îP ŸÊb²ƒ²†$=ñMngîÌ6‚±¹\Qj<èèVz$&FE^Q‘ÿHDª›n¯sS¢HS×P°"XKHßâ; gOEñÒÚŒ¿¹¼±6DL‚?C1‡[ÄÔ´>é¤o%ñÈAA0÷»^×ÈíįŸ+ü0TmT÷)!›‰§ÒK•Â2µÇyØC®\ËüÄDƒ³ü—@¾}RI„àÏïÞ§îÖKeìáKsW€’T¸Á Qü°2§©B(ûJ¡—΀@Š#*XŽ™@mh’÷Ê u-¢!Q>ÃΛyÔ¯cä¯fhv6Þ³Þu9¨Sj4H ¹Ïß[éR§ž°7‹!û帀®‡á2b€»ÄÍbµ€ã‰úIW¼ÏøâÂ]̾̔@ê†M‚Žùþ…† ”ÂA@ T¢X8,[ƒ–E ѱnÝ-]`±aÀ§¨õ=E“‹ïšU²}P/'7>öú­ôµ›3=‰lOrò&QAºƒÐk!ôDë†ò^ÊBº—Ño2]£yœÅ6†0ƒÜv¬Š úìW,¢c]Æ¿H2¨! z`$&Bò½¹x«“@öÌ1^"‹è‚Ô¨‘%uÊJá^;þî{´05Î4 Æ/Ž!‚R¸§AãɾRðCëTëaÙ%ô„¼58@O»s[@¼6=a:ª/”=Ôwbü¾›v4”'’„| )—š…6¾¿·‹„ ÷²iSëÔGr¯ìÇ¥¹ž”ÿzRÂ7>Î|ãÑ,ÆA¼wõ5’œ‚6J)-¿Éþpõæ'Ç endstream endobj 2394 0 obj [ 2393 0 R 2395 0 R ] endobj 2392 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2394 0 R /Contents 2396 0 R >> endobj 2397 0 obj 2930 endobj 2399 0 obj << /Type /Annot /Subtype /Link /Rect [ 158.84 464.788 203.275 473.668 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2401 0 obj << /Type /Annot /Subtype /Link /Rect [ 158.84 464.788 203.275 473.668 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2402 0 obj << /Length 2403 0 R /Filter /FlateDecode >> stream xœÅYësã6ÿî¿‚“i¤Õû‘ow›ìM®™ìmã6sSwnd™ŽÙ•%¯qs“?þ@‚©—“ö¶ÛlgŒE€  ûea þü'Œ’î_ä˜MB‡¸òb{¦ã“=‘´O2>K#œ–‚œÄŽ<,ò…Eþ±øùø¸!0ÖPœ`¾_|ÒÖç_¬o¾¾E_.Þ}ð‰m‘åV™È ÌÀö-Ë"™®ó?‡,÷ä糫ëÆO7ׯûÛ¿ÝߟÿB–ÿ\\/{Ûqmç/ØÎ'¡ƒÐ_8ÙÿBSxº÷Á÷¬þ- ºq5*tq Fpmþ)“n“¿¨’¸ü݇¥¶aé»è‡Å7]|>"BÎh[fÔ‹;ôfàäH¾öü~¼q`¯ÇÇݼû³ þ˜ár³6Ž%«iÙ²–±í19'†c›193y³Ut¢Èª.Yþx¡êÍ:öPI“ ÌVOIÖÐJámYì{¢´…²¢Ö&å̼MR'뤢sr„š†,ËZS´”nUÇا©è†³„¡tª Hzãû¤VX³Y½SH*‰ È³g…„•\S¹ ÆÁÔb;3[ÓTp©+iÕduo e´Vu4Z«ÐØh®cº® :rûF³c3;UŠ–Š!H‹¬Ùç wBÈò¾Öí¦ˆ•ë)rÛäiÍŠ¾ ±ZÑí>å¼ä³¶b‘k )›=Íë‹õÛ(¶½ycóyÞÀ|ÜaBxàCž9Kò%­›2WX®Œ [¹ý†1‰¨ÚM¦IZk36‘åu1³@Ïò8„–—šj«=ï×EvÑ“3§6Î5Zg-ä M¹d$Âs°vf›ý\bCõŒ8W/ Z$âeÚ‹ã¶ö>KªŠ|<ðÅ«Ùì IÚ¶"Ó²A¤MÁÛÒô˜å’Ð;ft>S;Þ'·˜ïBK€¹Éê@S¶e˜YqHAžì5„Á81íþÓ­­›µ¹\]Sá¥Î»¡Û²ˆèâ!›Ó-†ï©j޽oCRîâ–ÁáE‚³Td÷| yE cpù(Vl<)ù-kHI×M¾¡e•||—”I ³.Ê]íÙ¦Ùqìî[]=b¹Ìy]ÈØéæ0ïkך`§Ã2=ék${¾Æ!(º°åR Ô;¦}î,ŒNˆ†”vjŒå ÕIžR5Ø–jD0j^Ö •©F®¨1áFpr"jÐÿ–¨Z…¢s†É3eðá·"7úºãx•îè>©´™2éHùeC5¡mÈ Ð yœÍC^×NfSDûä0­xkD*„T>aÈ‚}Ãtv"Q'ÑÀæAÝÒ¿,6@(J’¬ìСdû¤|îðgú¬ ý‘|¤µ.¡£·¨Ž*m’È(Hj6”Š‹¯ÖÁö©ΪþÍ.áÛ„ éÛiO!݈,‰jU@m_ÀþÀ¬8ÁÖF¢Î™Û†ANÕ'†)eŠNt¦ªY+ç¶ô%4¡,¯ ‹i¼ÅÜÎa‰ ëEñ\”Ù¶êQ†XÉ$ïHТM8 ­€`—<©/hI¤+¬BÚòÐJÔ9DÈ"R>CŒ.“ò ù+UW‘Úº´ª«w› rÄÒRƪÃT£?̸¼Í*ŠÍ>«ó× Ç“ZtA$Ÿ#h•–ì º˜é>ÂThT4¸8b ×¥xÜvRHµr‚¡œ(0#.*ëMü‰Ñc'C48' m:!4Dn\¡CkjKš6…¢»]èûÔ€~c´§Âò¤Èý+Ûjô,7H$…ï±Ý¢ÚǼ½íÓß’ýßÔÖ4+Ž•Ï ¡+öy m”öÀ_c{n¢_š$ãïPBÈJlT¾j¬Îµ7=zŽâ9 P[]¶E:@l\ÎV0Pȳ<ÓõcPW¾@­øŠñ=›!/ u=Ú.´ÇmnÂgžÕ¬†öà2ISZU`y‰Yú–äRâúùÀ%?%%ÿ Žg­ÎñßÄRž5XŠß™±¹ûxu}9Á•®Ïòío~7øÖÍž ÍöB>0 Nx!K¾«öï…ÜñÛê ùn /äJ>O½ëßê2!/¢Ã¡M¿žÖQ4Òzy³¼½}¤Vg 0ðïë{®¾ÜÄ··HÉm…CWõgéí;¯iR%«SÑã»ÓÊÙ ¶ÑBµé‚UŽLõ†æ$ÚF7Ëkúªñÿ%ö™Áµî’_9J ¸¾– L¨@ȵ‘C¨LG¿ Kør–~ÖtGØ)ŽppÈoþŒA‘š=c?Þ_ÿ0qÆüx.Z¿‚ßk¯xÊÈÿÎg.^¿†æî0õ¼ þçæ tŸ¯ÎlŽY«ûGñó¯nºvò¬Þ8ýÜݼÿÙº£Ì}MÞx”Åÿ¨þ´ø{µñã endstream endobj 2400 0 obj [ 2399 0 R 2401 0 R ] endobj 2398 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2400 0 R /Contents 2402 0 R >> endobj 2403 0 obj 2313 endobj 1350 0 obj << /Type /Action /S /GoTo /D [2404 0 R /XYZ 72.0 720.0 null] >> endobj 2405 0 obj << /Type /Annot /Subtype /Link /Rect [ 287.76 563.636 332.49 572.516 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2407 0 obj << /Type /Annot /Subtype /Link /Rect [ 287.76 563.636 332.49 572.516 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2408 0 obj << /Type /Annot /Subtype /Link /Rect [ 220.0 543.044 283.05 551.924 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2409 0 obj << /Type /Annot /Subtype /Link /Rect [ 220.0 543.044 283.05 551.924 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2410 0 obj << /Type /Annot /Subtype /Link /Rect [ 253.22 493.124 298.768 502.004 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2411 0 obj << /Type /Annot /Subtype /Link /Rect [ 253.22 493.124 298.768 502.004 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2412 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 136.004 252.0 144.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1356 0 R /H /I >> endobj 2413 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 124.004 204.0 132.404 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1320 0 R /H /I >> endobj 2414 0 obj << /Length 2415 0 R /Filter /FlateDecode >> stream xœÅXKsÛ6¾ëWìøÐÚ™!ŠÁÇ¡q»ÓL×¶Æ>Ä9Ðd±¥HG¤üø÷]€O‘ ìôàÊžá Àî~ûÀîRßg (þ9úá‡âõì{½ÆÀç ¼zIzÀ\Â%¬¡¦%¤úTà …ê+¸že3 ¿Ï¾~ÃÍPdxœÑ¡8Ã|9;ïé×;ôÍõ÷Æÿƒ‰Š‰ ÇŸ˜àìlH—îîô×®w«F¡¨Öp¥Ò­·ÒÚÓõ³R‘•=ÕsÒÚ™Aí~¬-|;åîfïç³_N%0 óe—ç¾fd”<Ôó5|=d=úóO³“ù(ÞØk£@jÝ­=6 ”²³Lpýڨʦ/ÑZUFYÜàÀCB=©ÏÃÇ‹³¿œ«?N®Ó‹³?Ÿ//¡’Ðò1ŸŸkõœ%Üpî‚} ðQ¥ªTPF·©‚å&_ÃåùgXD¸Š4ø} ~—R”åU²N·Y\&yÖðL»Ê ‰dAú¬vÕåsVFO chQƨK\îR*jm`>cw|p±Éï‡D=:Ú<'N£¢°qjჂàáfipÞ¨0Ò¬ù‘1‚Z˜á§ÔóŽ-«£4­Êæøõ7x9DL0â Œ‘løŽ7wÛµÊÊ¢lWQºUÅ4`2‰—‰žˆ .³rÏW 4äK(‘nؽqx$ñu–»’Yä\! øÐ¥÷(qÑøra‘@öÛí»$¤¥2˜Ô1ÛËùíß*.§Ñ2¼‰ƒ(¨´ˆ!0_%<&i µŒ¶i en\ø £¨ýù®ÞpïÈË9Â)#¡d”ºTÔLñ&¹ïWkåã.Ö¯Çx¡Öùƒ*àœ€‘£Ž¬jSû‘&™Zt ·Ï½³«ÞÉiwã>okâŒIVÊ ™Â=â{è)|‹¨1K5”Ðó5®EÄk/à{ÅtHL•.áz„y, |a‘7Ìé1žÐÝÃÞx\%ñj'¼:{©Pæ{¯Þ@ö8™§+ vÿ±€×ä¾'Hàcîóz‚9yŠÖ÷iWmMŒ‡ñ}ÔDÛ†}˜&Eé˜/nŽ} YŽJ»,X¾oNÏÎààýñÅ•‹ó‘"[„Ÿ—yn Ü‘ZË)̵G]PÙ3i‰?´¿ßø÷EH„>ñq> $cõ”‘,œ,—XK§/´lð&y8&uœÕ”„¯?(éZc–¦1¹.bb´º£UW5p°œÝ>ï…¤ÇæærÆë•Bƒ¢¸Wq²LPJO=a H²ÿ„ýæaÚ1Ö v'O±25=Â9)·‘¦÷zP¢%E2WÖvâ}‚08Œól‘h íÊ:zné[Õ’Er‡SSê«•dÙ’U¡¯éºATß¹é#Õ—,/[Úx¥“•Yeigµ’šþÛ,ä›— ôÙÑÐLÅ;–jlã—‚¼¥a¯¢Œìv¹LâÇ.¸W›uRÚõº}/zƒ{ñаJ‰C76k.E3t+Çi‘·/^Ý{…s ÍÏæÅgTÏ(Dì¼ÄÅ•Ê>kÞë´‚ÀûQX×®ö¿ðjæqfu±êÿ%/ÕÞö\œù\¯Ï‘5—Çh<Ÿý 0`¤ endstream endobj 2406 0 obj [ 2405 0 R 2407 0 R 2408 0 R 2409 0 R 2410 0 R 2411 0 R 2412 0 R 2413 0 R ] endobj 2404 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2406 0 R /Contents 2414 0 R >> endobj 2415 0 obj 1227 endobj 1463 0 obj << /Type /Action /S /GoTo /D [2416 0 R /XYZ 72.0 720.0 null] >> endobj 2417 0 obj << /Type /Annot /Subtype /Link /Rect [ 495.835 511.321 540.0 520.201 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2419 0 obj << /Type /Annot /Subtype /Link /Rect [ 495.835 511.321 540.0 520.201 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2420 0 obj << /Type /Annot /Subtype /Link /Rect [ 408.0 466.73 540.0 475.13 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 2421 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 454.73 156.0 463.13 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 2422 0 obj << /Type /Annot /Subtype /Link /Rect [ 161.0 454.73 299.0 463.13 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1421 0 R /H /I >> endobj 2423 0 obj << /Type /Annot /Subtype /Link /Rect [ 312.33 454.73 456.33 463.13 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1424 0 R /H /I >> endobj 2424 0 obj << /Type /Annot /Subtype /Link /Rect [ 120.0 74.096 288.0 82.496 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1416 0 R /H /I >> endobj 2425 0 obj << /Length 2426 0 R /Filter /FlateDecode >> stream xœÅWKsÛ6¾ëW`r©í1Qÿ[-*´(T\%y†(Âŧ˜HÊC£üs\$Z{#3µPâ€FR *Ñt§Ðôi{4v’áHpPGÔež§*Ξ·GÁ\ B8FôC–TIœ¢Úp£@:lRŸcPB±1¼ýpó‹‚b&|)¹EøN•‹"Ùê ƒH¥C¦Cc­}Y« "aTë¤l;6Üí@on‘ÞOœè-!¡±é¨k’=.×Ú;_“¬¬âlátOï<µì-í!ìômÚ˸ŠçqÙM>îÇE½Èn½­{†çOÏGÌçCýim oâïÊ;(A]å$Ü_×x5`(¢ï‚˜ëäý®ŒÅÂvÞÔ¦o·E¾… Quc½˜™B-òbYvBE7·Û.mhL_ÇW=¨Âi­LóªS“¯:m«âÉ8Ž8Tõ?'ê±Õq•Æey”Liä3ÒÐ6ù2Y%j‰ùᇚCì×…t]¥Ùn¿ÖìÐÞüx½ù ` ê°Úã’aÉÑ1ÑóžùÇu²Xùf‹Ãö–jïÒjPà¹Ì uLH,˜f;Æ]Ý@ÅŽÂá„5yÃÃ!ܳ?WëøAõ!¤É÷>†«|³É30ö[³M}éÈv@¬Õ[Ö‹€£¿Ùr¶·Ð{Î7¦Hl§#.ÓÏ‹®ÝU0´fÚ6 ¦c‰ÍtúÌf•féS×kˆÎôF7‡KçñÉ3…ï­Š|ã%™‹¯BøÊ™ÄÚoë3tù™s4ê^$ëÞif5 §‡¤“0f—Aýq®×Gü匓à\ ç½( œ¾èݲˆÓ´ec‡&!§P R{"¾þ'ÞlSU;‘pœI@œ1¬ÕÙIª*ø?ëpf>Mmÿ—UžÏNõo˜}ΣCì§lvÕ×4F4†ìPãÛ·hIýØ%@8*«P•;ä¢#ØÎ–s/ÞU¹W>e‹3T˜–N0îh Å}¸¥ ÄíãXÍ8ípãléñí3;oø}æ’ ˜Z©RU+ý‚ëÕdŽ:œó¸˜¢7óøß7N´bíl¬:Õ;ëƒÒX`÷q ¿ìDÀ ¡¹"tnýÜ~8ÑôS±sªö™Sõó•@Ü)¡p¬–©/V+¸xÁçãò騉'ûœÃyØ!òL½€kB¸IÄE|{ºS ]¤eÞ^Á»0 yˆ ñõ5¸¾˜ˆ ¨fÂî:Œ/z÷|ýû³¼Wy endstream endobj 2418 0 obj [ 2417 0 R 2419 0 R 2420 0 R 2421 0 R 2422 0 R 2423 0 R 2424 0 R ] endobj 2416 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2418 0 R /Contents 2425 0 R >> endobj 2426 0 obj 1290 endobj 1403 0 obj << /Type /Action /S /GoTo /D [2427 0 R /XYZ 72.0 720.0 null] >> endobj 2428 0 obj << /Type /Annot /Subtype /Link /Rect [ 184.05 562.217 228.78 571.097 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2430 0 obj << /Type /Annot /Subtype /Link /Rect [ 184.05 562.217 228.78 571.097 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2431 0 obj << /Type /Annot /Subtype /Link /Rect [ 160.754 499.351 206.421 508.231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2432 0 obj << /Type /Annot /Subtype /Link /Rect [ 160.754 499.351 206.421 508.231 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2433 0 obj << /Length 2434 0 R /Filter /FlateDecode >> stream xœÅXmoÛ6þî_qH5`¤H½m±lq» m×6^‡!ÎÆ¢cm²äJJÒ`hûŽ¢Þ,ÓNŠn@GŠ÷þÜé¤÷# ÿÆú⇠æ«Ñûz‚ÏÀõê-áå°‚šèS=‚5^Ì!$–ðû(x>:;Ç›d¸‘¡¸Šùtô¦§_ß!_]ß—²ÿÅmC••*/ ÿ}§JÎÆ ÁÉæ^âÚýn·Rèš=Ü1ºõ­¤Žt}5†Òøc®;ý ÄÇÚï§œÀåè‡éè»g(é¢Ã¹¯)qêƒé ÎiÃô—Ñdº€¯µ­DjÝ­?.PLl@¡nUÉõk§ŒO¯äJ§,aà°Ð!žÐçÃðó«Óéñ«'ã·“go'§?MNÀð·\ÔÓÖo1Îó‡'}ëIø­P9,³ì/(3˜Ë$,…ìâO5/!W‹\K§1Ú·Í©CB‚=#ð¹JUÏaq•ÎË8KÞÝqòBGÐ }ZÇéô6-准1´(¥„;AèâR¿ö£ú |¸ådœ¥Lçj\{§¢a¤ƒ=hÍÀ Ú,21ÜésmÆÁ“§pwĨË7àaÈ5|ÇùåÕJ¥e2àL®T±Û`A!ßuQ¶Omöná3äžéRµæz[a¡Ì!Íw‰°ð¾‹Õ ü˜È¢Ø©KÑñ} VßfqÓ›e<_B\À…ŠÓKhóêÜ#’‹¥N ñI]'ª˜çñº]k­Ï!¢6$uÇzg×q¤ 8Ò-âPÖת´ iì4tÜœÓ%§¢æD\.㴑е›õ"1Ï-GU±†Äú5Än̅Øc •ìC€ëò}Ü=!H³tœÆ™×œ3‹É¬2Ï¢¬ÎñÞ Ñ`Àt³T:¤ãÐu| —Æn³Ø â p|ábs² ¬ ÜʸË=Îi-Û¢:1MÚ6ÎÒy|®û9!Œs‹Ð;J­ÙÇݰ”E·¸Pý(^­#iÐXo,òlµ#ÈxR^ÈB9ÝÖqG®T¹Ìz‚еšÇ2‰‹¾ô¦(7í’!1€‘Ì£qt1n‹g̰®;C®MÁFíFSŸfU;]ÑiÖ’j±@y…Ón¼¬ìîÎì®ö²´Ó*ó2ž_%2o·U‹ Eª7—6—9¸|¡ã,‡bJŒf³¨š‚!+÷íZ¦­U.uÏ+:Î¥,ÛEªì2{jW2ê•Ƭ½3‹Î;³nÀÞí4I0«¥¼V=eª[ÏÁ±ÁŽªÛd¡'œ½1ñ‘ª#7´ˆ¸£5R&öqßãAÄæPœÑwë)hòA®ÖI÷·ÍA878<ÄA@ÐZÕì°H²rlš¬BÙ­Rª•Œ“ÙÑv¸\ 7Eàr¨4N¿/°@Tédùå…'¿¡îH-ê2Þž²`†:›fGVk„;ŠSÝìp‘å+Dc Ÿ¾9Q%ºRîÁ§cý_¤GÓª&¤{OÛrlxb[WóÛŒ#<\ÄyQŽSœà­fûÃ<ì…%ÐHÚ„À’’O›®f:XÞf‡“—¯_üúÇd2;‚¿y€Ï‡“ðäãÓmœlgÏ€\cŤá3WpöÎz.t÷+*ŽÎžÃ£E"Ë5”6‡8fš>xÜX[ÙŠ÷Cññ©U¦j#¨3ì’9|‹>ïÆ9w‡)º'Î9fcV7Äö<˱õŸ5Á0ÈëñZ"Xà¡ÆûYeÏ9\;[ªtò‡o,ZŸ7Ì ~½´t °úì[ân9X¢ûŸa!´äás° Èv>> ‚ C|O,wÐ)Rð¨î“ö  >ÌP¿ ¾Kd¯â^hîÕ-*Ä—æÅûò¼¶¼XJÇÂZí½Ÿq€…>m¿?àT3çí{Ãð8wð…úžèÞ‡¯Ú*Í'XÉ[œ@ðZt3Bö>p½ý­B„ endstream endobj 2429 0 obj [ 2428 0 R 2430 0 R 2431 0 R 2432 0 R ] endobj 2427 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2429 0 R /Contents 2433 0 R >> endobj 2434 0 obj 1490 endobj 1461 0 obj << /Type /Action /S /GoTo /D [2435 0 R /XYZ 72.0 720.0 null] >> endobj 2436 0 obj << /Type /Annot /Subtype /Link /Rect [ 424.94 688.884 469.67 697.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2438 0 obj << /Type /Annot /Subtype /Link /Rect [ 424.94 688.884 469.67 697.764 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2439 0 obj << /Type /Annot /Subtype /Link /Rect [ 233.76 560.768 278.49 569.648 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2440 0 obj << /Type /Annot /Subtype /Link /Rect [ 233.76 560.768 278.49 569.648 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2441 0 obj << /Length 2442 0 R /Filter /FlateDecode >> stream xœÅXKsÛ6¾ëW줇ڙ’@ •ÇŒËi2iÒXšäçIÌF"’r¢vúß» HŠ¢ Y§TvFË%öoŸñ·‚?ŽþƒÉ²÷­âQ ¼ bùPî2–PÑ>,ô©Áj ¿Ì!$îàS/éxÕûü_N À÷éª+…‡½-ûú ùéöÛx”ý/hʨ”qaø+Ü28;/|Nvß´×ð·ÜÒ gxÈ1¶õ«E…tõm1¤¹ù>x²½±ãXÝðç'0ï]ŽzO®} F³mž -H‰²HŒ–ðùŒFäü ŒÞô£½øÉ¨íRÛnîãÅÀ†„ºs­2¸¢º”¹Ó;¹TæRx,rIàë󡸼ŒÎëwÃÑÅ»—çfðòýÍÕŒ’F±ry„ø<ÚWr˘è0rL®ÔB †ÞB¦&i6Íñ{•©\%…šÂxê{Ý{x>s#Žºçûº?Æê;¼\ÈÊÅZå‡Ö0úÂ¥!&f€HYüÝK“ˆ[d.¨Á„tv,Mi@]¡‹ûÔ¢è„ç‰\,Ôô„‚`¼D«Ò«úïà‡\®ÛÞaëÀ,ÔI…^ R<ì¬3çkØ™èt nÏnÏ»]¹ºAGôÑ3 ý8‰ ™Í¡t±Y)ì-…š« úÓ±ó5ÆÆÖÿª6V­ ÷´¢ÚqKé¸RšYœÌoÏõE#EØ‘y6Ä7•ÙÔ¹;e›‚ÑÅ%üãKBCîÿû¢Éc{0M2…4HͲtYÁõ+âeu†w‘nÆÃÎ1¿ i{™éé0`¯*1~Œ8Êu‘:ù&™<†âËÖçöl)¿n§h齎™¯1~¤;€øÑAŒC Æï/ßXNFû¢Õ¬pòo‹j|£¥*²ýqZÜÙ rrŽœÚp´® Xk"rÖïéS½ÿq‡‡âöDûDôqÝ™¥é“±Ìðßßzè›Õ®oÞÿQVϧß7M¹žƒo1Ä» ž`èÙsYTù]”íð]Û›×±>Ãuy…<¬ï0ž*ÌfØO|´écH!"úlwòê@gœÞë~xBãó±°ÜJhµÉ”¾”ÛöQ°6|Š#Qõè?U¶Œó7ˆ晬7ö®SP¤%oc?Ãq«éæÝ$MU®Ì§øŽ ]À%Æóê¦=Qå#ñ¿Pq±–š> k€]Îã÷ÇzϿЀOÝÎT­®á,妡Ǫ!ͨ)g¹aij†4‹€¡[{€alïÛ°J\´\­Ìƒ€5}'ï[æ×³Y<‰q«jX¸©ÜÇ œ[qĽ¹F:g›ýİSï¢Q­1qÅÖ}wË*Ѫh3y›G³ ºìJÍ“nYµ.§#ç­sõo½n)=¼ŠxÄs}âcm—z`ñ¼è˜´ÝWœêaw»3¼z»«N´p“˜÷Ê ¬Í]ÓÂ.ÿBñ¡÷<”Ó endstream endobj 2437 0 obj [ 2436 0 R 2438 0 R 2439 0 R 2440 0 R ] endobj 2435 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2437 0 R /Contents 2441 0 R >> endobj 2442 0 obj 1463 endobj 1416 0 obj << /Type /Action /S /GoTo /D [2443 0 R /XYZ 72.0 720.0 null] >> endobj 2444 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 557.675 290.49 566.555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2446 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 557.675 290.49 566.555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2447 0 obj << /Type /Annot /Subtype /Link /Rect [ 178.0 535.096 241.05 543.976 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2448 0 obj << /Type /Annot /Subtype /Link /Rect [ 178.0 535.096 241.05 543.976 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2449 0 obj << /Type /Annot /Subtype /Link /Rect [ 215.079 481.202 260.55 490.082 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2450 0 obj << /Type /Annot /Subtype /Link /Rect [ 215.079 481.202 260.55 490.082 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2451 0 obj << /Length 2452 0 R /Filter /FlateDecode >> stream xœÅXKsÛ6¾ëW`rhO„âII§n¢dÒ™8-§ÛZ¢,¶©”ÿû.¾DB”O‰_Âkw¿ýv¹XúÛ„"ßSó¡4C‹Íä[µF‘bˆ{Õ’ô˜I´AÕX¢Øœê X=‚{kôÏ$™ôar} ›KD@àqBúêJáËÉ—Ž}³C~¸ý.NÙOA`0”Q)ãÂàGá28{RýNàšõvµ4Èí¬XÛf+®˜®>-;´þØÏƒ~Ö âæ±òðÇ'è~òç|òë{‰(AóU›çÊR‚}¦ÍCó º>¡š½ºEó¿&³ù ~0kƒ@Û?Q¬O¡{n•ÁU•SÖ§ó`Z§41‰'Íyß \ýýîl>›^ÌÞ~¾xw9}ñùÓôãùåüìüí YMôêH pFF„Ý“´h'ßé"÷–.¢¢CE0¤·K“ÞeiBR ¥} 7o ¤XWVèd*^·Ó ÚÛ¸ïIeaÓn&í¸Ž—U¸Ýfé6‹ê ÙušÛ©­v<Ű'„ö5T»¡[GóÔ„gD¾…°«+ž–…¸ã{Ùˆ¹Íã*œNÁt5z7ÿö!É786”y]^û#EŽH¬á "L¸Ä]gÐRŽH£;È™ øÜÉd›À‡£*$öMª íj<U¦ù˜ü3®JN(VÊtÞªj¡f߃Í6nÛ&W»Ë¹=h¡nªªÅ?ÉÃÈC×á&ˆâ[ô[™)0ÛÆéSÂÂã:ÌBtýÆ.FË[Dͱ(Œ—Ó$0Ä%Q qPlQqójø8sIzf¡M¼9y‡I”ü‘§ð‚Pà4»áöØ34A†NCz z0lüxY#ï7)>µ½I»ÿrϽùv€€ëhàÁé Ì;ÎúÞä@ úeɶӒî‡, ™ Ú'ÙpR¬ÐaëèÅ~V ëÇÀ€r;DyŸ¹›Ñ7§¡ƒèÓÚ¼kì“?%Å…r§øs öûw^CÇꀄ–ÙS.lÆ«—Þú‰Ùjn<Á¤„ž ~ %ª*;ŸÒ¥mÌõÐÜÔÏÀàI,=(FœVïìg¥y¨£wO£4ÁÂü¯ƒyU;Oá¢OîŸaÔƒþOÀ%i]ÿaù¢Äè2*v2÷*æŒkzª×ºÃ ³,ÍrÜùgÒ—Éÿ °÷A endstream endobj 2445 0 obj [ 2444 0 R 2446 0 R 2447 0 R 2448 0 R 2449 0 R 2450 0 R ] endobj 2443 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2445 0 R /Contents 2451 0 R >> endobj 2452 0 obj 1426 endobj 1421 0 obj << /Type /Action /S /GoTo /D [2453 0 R /XYZ 72.0 720.0 null] >> endobj 2454 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 564.587 290.49 573.467 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2456 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 564.587 290.49 573.467 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2457 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 524.037 250.77 532.917 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2458 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 524.037 250.77 532.917 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2459 0 obj << /Type /Annot /Subtype /Link /Rect [ 131.155 462.751 176.21 471.631 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2460 0 obj << /Type /Annot /Subtype /Link /Rect [ 131.155 462.751 176.21 471.631 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2461 0 obj << /Length 2462 0 R /Filter /FlateDecode >> stream xœÅXËrÛ6Ýë+0Y4ŽÇBñ$ÈΤS'¶;í$q+éÂö‚– ‹-E*$eÇß ‚/‘ånÛcáuî¹/\ú:¡ˆÀïÔ|¨€¡ùzòµ£H1ĽjHzˆ Ì$Z£ª-QlVu¬nÁ‡]ú{’Lú}r} “ Dð8!}q%øjò±ÃofÈwçïjÀ)û!ʨ”qað§pœ )ÈîL'pÍx;Zr;#–ÛLÅ•§«O«ˆmZ{ìç^;Hkqû±²ðû‘t?y3›ü|!%h¶ló\ %Øgùah¶F×G4¯nÑìÏÉùlßÙkƒ@îÆŽ(Ö'„гÊàªÊ(kÓ‡p­­Q7±Ošõ¾|þëìtv>ýtþöòÓÙôâÓåûéջ˲B( 8ö¹ÑÀçC!7Œ©€‘1ú¼Y„…ÎüïÂ\£e–®Q§zã­ÆµÊa„ ˜¤yVÚÅ6™QšÔ˜ýþò,©ŠVþºzJŠð[ d”L‰"„±Š•?={}áX¹-­œfzžf‹©1qjL컊1K­¨ÔÓŠ1—ZéÝ?z^ì5…y. ÇXqZý]“ã§õÓç.¢:3ö’qå Îë_Ñá< ŠP ¼*#O³ûíZ'EŽÂd¾˜Ì÷«lòBrÌ=ÈpHlW»Ï:MP”äE˜Ì5J—(l”÷xű2›HHêô%Òèmæù^ õ±ÀR xÜ^ ÷¸q¦†©à¶v™­4J DYSËí%#©aÊ£ ÀSÔ!î€ÇÔô{: P[÷Ýé¶y; )•X1“Ÿ¦ì%D‡2KùX)cS1ÍVQŽ£8F ½ ·qŠ‹²Öš`WÓšóÞEŒì p°'”¥:Óù<‹6Ýbì<…Ç4€L””WÇPu¼BS¸Ätd´k:Vͦ›i¦mߤ7Oãíº3™éM¦sØå]ôÝÓ´IÏ“Nw£çÑ2zôí»Ë«]Am¯Ìÿ¦7’ƒpÌI‡«F·ð¤tÒ;sL¤ì-‚<½8 G{sV˜Bý|åQV¡FÈx92Å›™c< .Q­˜¦@´sT Á`›ƒTO¹,<¼‘öƒñ³ø}Ø~Ê4÷¤CÆÁÂ8÷*Ô阷CU ÚNS<:nlÛ«h¾Úƒ´·–®C±™4‰Ÿ:ë–£•yêÿE®TC Ð1ýJ+ÛLÊíeÛpé< í·CQ±jç›Ví ÜŒü‘4ÍbÕ‘?‡U' ö^çÒhžé¢VòÈ=Nd&½À÷%wX~0u¡cøÖ€dѱS·ãE‘EwÛB;j… zÒvK)œ~Umsdƒ8¬¸€Ó„z¹ã— H4Å9lcáÛ°—‘¨šITDaå=Ë·Fݱ°íúœ±½²åÛÍ&Ž:âŒÊ-a•m•fM¯qp»z>DÉ}Ó­NaGÚ3¶Ô5Çèb›’5‰'c7)αÏœi‡ £y8íG£;Ø k0«³û¬F^›«ážçx0Ù9£cøgÜ^8LðÈ!4tþ-\oâöÞïzr µŽJB᤭¿G¹ŽÁyèZ¯Ã(¾E¿”ù½Mœ>i  ®_ÛÁhq‹¨Yéx15×%Q qXlPqójî‰-¼snŽ^Ä:‰’ßòô!ÒN³ûN°ò:C¦=„:ÖôäÌ¡ÙØñ²Ö¼«¸Iò©ÝíüËsjíͯC ßZp|ôõP†Nn(•~YzÛÅ$h?DÀ4ô”ÈúN6>)–h?;zñ€ŸÁû10J9À¨è{îfß7 ]ãõÛ<—w–©’äÂw'ùs]ô]Üý¦f¬Hfž™žaÕ;æ*‚kÎùr ï¿¿¥Ò¼¼àÂHªGåûtaoeÍõâôàn¸QÆ…¨ÞŒ%5TÑ7O£ôÄDB óü øN8PžAêAU¾§¢.s]>ÝÂ]EÅ64íQó=!0à7%«·æY}ëÔY–f9î|Áúqò¡‡¨" endstream endobj 2455 0 obj [ 2454 0 R 2456 0 R 2457 0 R 2458 0 R 2459 0 R 2460 0 R ] endobj 2453 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2455 0 R /Contents 2461 0 R >> endobj 2462 0 obj 1583 endobj 1424 0 obj << /Type /Action /S /GoTo /D [2463 0 R /XYZ 72.0 720.0 null] >> endobj 2464 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 564.293 290.49 573.173 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2466 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 564.293 290.49 573.173 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2467 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 523.547 250.77 532.427 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2468 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 523.547 250.77 532.427 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2469 0 obj << /Type /Annot /Subtype /Link /Rect [ 131.751 462.065 177.402 470.945 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2470 0 obj << /Type /Annot /Subtype /Link /Rect [ 131.751 462.065 177.402 470.945 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2471 0 obj << /Length 2472 0 R /Filter /FlateDecode >> stream xœÅXËrÛ6Ýë+0^4¶ÇBñ$È̤S·q:é$M+éÂö‚¢(‹-E*$eÇß ")¢Ò›d"¼Î}áàâ‚_'ø;Õ?*`(ZO¾Ú1ŠCܳCÒCT`&ÑÙ¶D©^Õi°] ~Ì"h¬Ð_“lBÐo“›;˜\ €Ç é‹«Áדýz†<»þ®œ²ÿÅmC½+õ¾0ø§p½9{Rý™ÎÆ5ãíh­›11ºõTj#m!¦iü1¿ý ­ÄGëáó)'è~òËlòã‰(A³eËs¥”`ŸúC³5º9¥wv‡f¿O®fý®cã”# ÂG,ÀÄ“z½oŸÿ|}9»š~ºúõç×Ó7Ÿ>¼Ÿ^¿û0»FFJƒ¥A€¹¯<J¹eLõŒŒÐçÍ"¬bÿ…ó°ŒÑ²ÈרLóªDù=$ñ#ŠÒ°„Þüï8ªðÎ)åpJPLÂ=#|¹Í¢*ɳæpü¼K F*jãW>eUøm Ê(SK$Èò¹õ¥þÓsߎ•ÛÚéiGy±˜j—§µËýÐ1§šU`SÏ,Æ]ÚLäúÂùZ”çtp(áÄ…A?ü?hâ‚9P;®V8=zõ:ÎÊD„¢ˆ¥èeq¿]Ç2ÌèK˜nãò°Éš’cOzÀ&ÏwíÀàD-`ÔÇ"€pH8$àq•ÀD'_ù.¸Ý`.Qš”•öT£Q ¬„Œ°ò6–Úm%]q6†>âr °0ßMJ·×ØåÈ®R‰ÓelD!:F.åc¥@Œ`Ê!£Ù*)Ñc’¦h/ÃmZ¡*GÕ*FšêzCÎíÄt§ó?HŒQÌpŠÔ¨z—Q‘lºÙy5 Ž}_6›»©N—%:Cz jãvíÚÈvª¬ò"^4]Í(ÊÓí:kQE¼)âÎx:rBkj_´ÝM%Ëä8.JórOHÓ1LßõFhÇ%TÃèŒ6á¹Q½»F^ÊÞ"Øû34 ¦­ažÊ’©³CD|!ãYˆ©Ù©¹Ê¢Z1M^XçÈBbB$t©\.9=>Cãï²À÷pÀ…É4CG3ÜêcøÖ„ËvÈPÐvš”Ñ dÛ~\%ÑêÒ,\GÅ:\tfò,}rPËS`5ÜÆRÆê¤¦–€Úp,tRaJ8ÂGö.à†\çA0·ê3¦ÕÓv€«y”„&+رǤZuV´Í]pq;ô6kÛÕª«&‚…N1¦&tñ¾1Éž‚¸#p³)òM‘ØM³+ÂyÚéæËÑ+Ž© ±£D…º{ˆÒ iïÑS]>5k®©ª"™oMŽ·cû9ÙÖÉÕ¶ÇÊ` "ƒ— $‡Eã “y I(`® XýÀô°ˆÛN’%UBÓX ƒõ[¦éµÓεeû&Ó:–ÛÍ&MºR]/…úEG{¦ÖTÍAZ:^…IvßÜõÆŒÞl ½r ×çÅxí¥‚òÁÓùp òȉ„õÍüú2ì_˜Xß¡×ß5ß¿#‘{°ž¯”ýxY›—ÐüiÌ OÌ9ÜZí×W¸uá’ÅÏÊ'ÿÚe÷P endstream endobj 2465 0 obj [ 2464 0 R 2466 0 R 2467 0 R 2468 0 R 2469 0 R 2470 0 R ] endobj 2463 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2465 0 R /Contents 2471 0 R >> endobj 2472 0 obj 1667 endobj 1455 0 obj << /Type /Action /S /GoTo /D [2473 0 R /XYZ 72.0 720.0 null] >> endobj 2474 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 557.675 290.49 566.555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2476 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 557.675 290.49 566.555 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2477 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 535.096 250.77 543.976 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2478 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 535.096 250.77 543.976 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2479 0 obj << /Type /Annot /Subtype /Link /Rect [ 242.265 481.202 287.282 490.082 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2480 0 obj << /Type /Annot /Subtype /Link /Rect [ 242.265 481.202 287.282 490.082 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2481 0 obj << /Length 2482 0 R /Filter /FlateDecode >> stream xœÅXÛnÛF}×W R qŒˆÝû’AÔ‰•"AîRR¶h‰²ØR¤BRvŒ¢ÿÞY^er)¹}Hå‹vIÎÌ™3³³³ü:¢@ðgl¾´Ç`¾}­®QÐ ¸ª.IT8Lª±„È<µ3`õ¿Ê‡p°‚ßFñˆÀ¯£³ ¼¹‚7#ÒUWOGwì›;ä»ÛßEÀ)û_ ETЏ0üÕNœ;7¤ wï쮹Þ^- òò^)m›[QÅtõ])‡¥?å÷ ¤uƒØy¬<ü~Æ \žÏF?½”@ Ì–mžk#H‰ã2Ï|ÌÖpvD=÷ÑÌ^&³^|gÖz4¶8P ¬K¡wÜ*‚«+§JŸÞùë tÊBƒpyQÒ<ï–Ÿ?œžÌ&ãW靈“w/&ã—ŸÞ¿š¼xÿét ¥¦Fž1î¸ÜÀpy_Ó9cº+À÷ ÀçÍÂÏÈ¢$‡k?Ú,Ód xÕ¿ô³À©=ÑOuˆGP›*µ½ÜÆó\’lÀŽ'hÞò¬b=À; ÐhÛ#«%-ú–DAÆ¿dÉuäN’^=°ºªg¶j«fÎjß/l°½.ÏÐù<ñ¯Ç?L3xxŽÊÏ .àÁµÓƒggQÐ.‹=mÌÚèXU±.ÉH“å1Þeó|ïy¢ˆŽÕžè²‹ö~øyòöÛ÷¿O&ðÖ8õ\òÓ¿ŸY„e?…ïŸB[rÏFºEÔí²´{ìÚ·V%¶xJ ,ÛŒW‡¼ýd¹ÄE6Ü¡M‰ÝþJtU:¦;çSSŸ·J$žóû µÁx”µ‰aº…ËÖÉ"\†÷*QR!…5ŠÓêX|RxŒõ÷ò¶yÙѾk0þ"ÇÔ¼n°¿:!fg»óÚä·< Áôã›îI½x‘rà•…¢ž#🖴.¢ó è¼ý¦a¾õÍxoˆ”ˆ‰{õ”:^í ‹Ô-ß;H‹è=NGÒÁ3L”²È› Åì#EOˆ}, üÅ.#Gÿ”Mé% endstream endobj 2475 0 obj [ 2474 0 R 2476 0 R 2477 0 R 2478 0 R 2479 0 R 2480 0 R ] endobj 2473 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2475 0 R /Contents 2481 0 R >> endobj 2482 0 obj 1493 endobj 1452 0 obj << /Type /Action /S /GoTo /D [2483 0 R /XYZ 72.0 720.0 null] >> endobj 2484 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 562.187 290.49 571.067 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2486 0 obj << /Type /Annot /Subtype /Link /Rect [ 245.76 562.187 290.49 571.067 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2487 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 520.037 250.77 528.917 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2488 0 obj << /Type /Annot /Subtype /Link /Rect [ 187.72 520.037 250.77 528.917 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2028 0 R /H /I >> endobj 2489 0 obj << /Type /Annot /Subtype /Link /Rect [ 418.057 469.151 463.934 478.031 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2490 0 obj << /Type /Annot /Subtype /Link /Rect [ 418.057 469.151 463.934 478.031 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2491 0 obj << /Length 2492 0 R /Filter /FlateDecode >> stream xœÅXmo›Hþî_1êI×4ª÷ö –­®Õ¥S©J/míötJòØ8¡‡Áœ4:Ý¿YÀàÀ‚£ûÐs"±,ÌÌóÌÌÎûmÄ€âߨ\”æ0_¾Us áVSŽ LîÀ ª±‘ykgÀ·#¼”/áàþÅ# oGç—øpîF´­®žŽ>îØ7Oè·¿‹@0þ¿ 0Ѝqáø¯HœI>Ù \=ßÌE9‡3¥mó(ª<]]K å°äS^{yІµû±bøãŒS¸½ž~9q€Q˜-›»„Ù»ÑdÖI€ìµN 횆õ(¥ì­"¸ª"UrúÝ_%)‹¤\ê:æ}¯øüáøh6OOÏfã“OgïÇŸ&oÎ>C©¤eZOžè*¹à\µ8€Ïë…Ÿ\} æyY”ä°L“à´ågÙ²P’ª)ªsKu'›xž‡I¼•éw˜«‰Ã<­«6½sÿûVP[Œ1*‰¦.ʸ[ôůEØ“–77ͱ¡76ôÆi0OÒEÛWœÛ¬lA!¤*Îm°JgöRá® áE-†K¿ mµñó_Áý€!!l†¶™ÐkL(kp^¾‚‡žX>‚I%¦¥ª¤ÒëÍ*ˆ1%ýx_ühdýÀMv8Q®It©maè,BF]‹ÐQ aœå~<ÇE±¿ö–Û‘W‚(³–¤Ã,о„Á¼‰ü,ëEÀ™G¤F…ºÈ0_åâºVèp)» agÛ™Ýc¥*©‹?ŒÄTΣ«˜EÝs,?Ò{øjE4Ã+EO^Ú9wÄŽBÊ0Üä§)½a_f)(e"É•E ÙM˜Á]E°–þ&Ê!O ÇXÜš<7Á8¬Œ·6ÉþUĹC¤Är,yUƒlž†ëÝ’lÝŒ$ÖX­ªÝ¨¨—<Ã7ÌÞ^sW¤Js[à~¾û|ÌÃe,væ®î{Õ½9=›ök/2´¹(”žgö7J9æT—ÔàÁfcHv—ƧHoj éê`R¸žM}Q-vü1X7„fD ¡5µÆnGO]Êã=)P­Ñı1ëªÝ“ôŠKQFSƸ¨¶Ý,Œ¯Ñ8vX•£ÌÈÏó4¼ÚäÛû"{²ê¦pnëýõ:MÖiè׸&¢ -0Ž$ž³ʽ…DP>$_Ù¿» ç7Õ¸Z¾[R¸¼Û¤êbRq̲dn¶{ãWÅ[ïÂÜX»„ ñv="$\!¹EÉÞýQI׿“ôy=—@ŸG´‹›½+ä€åÊ!éJV㲚ãÆÏõÔgúõh çJÝóÃÑN¹ot1u‹yÿ*£M¤Æò.1uuc [C×OKy²½6‹¿\ˆuË“™½ÇäèÜ Hb(“ÚL}5Ñ«+ÚãÖJÉ#6'S_ÇÑñœÀ仿ZGM[gëù…TD±*Úå'ŽY[·~ ‡;„‹ƒ9/² ¤§jLîƒ^Ü݈ñü%œM¹³6Ï‹Q¸¸v /–‘Ÿ¯!¿xfþº¾ŽnÀÖöp‚æ-ï*Ö¼ ¶ý0²ZòD×Ò“(ˆÃø·,¹ ƒœ$éõ‹ v:f«ožòK'ƒó-÷K lIÛ~†Öï…;^ûašÁÓ T~^p¸„'·¤ÏîEÉÚ^ì˜hbÖDǪJ´Œn²¼&ÛÞ¼èûÜé´ý‹úuòþÃéÙŸ“ ü-=ê¾vÄñ?¯,Ân7‰ŸRY²Ïæv‹¨nûi÷‹yhµ:Ì´êËPµûOC\õ“åÒœ õŽÄR¨¨ö„W}ƼO¦ÌŠ"Rtvu—kfÊrÿˆ‚Z 5‰¦Õ¹ÑQÇ”°ûúü¨9¾1`<‡óUÏyÜ!œEc‰6ß@Ó§í#âtjÏ9Ë)ÑžÔž#ê*7ŠÜ`æߌ]èJ³ñ¢ï•ã5 Š^!HÓ$Ívñ|ý ÷Ì? endstream endobj 2485 0 obj [ 2484 0 R 2486 0 R 2487 0 R 2488 0 R 2489 0 R 2490 0 R ] endobj 2483 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2485 0 R /Contents 2491 0 R >> endobj 2492 0 obj 1525 endobj 1486 0 obj << /Type /Action /S /GoTo /D [2493 0 R /XYZ 72.0 720.0 null] >> endobj 2494 0 obj << /Type /Annot /Subtype /Link /Rect [ 282.21 556.052 326.94 564.932 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2496 0 obj << /Type /Annot /Subtype /Link /Rect [ 282.21 556.052 326.94 564.932 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2497 0 obj << /Type /Annot /Subtype /Link /Rect [ 282.21 394.212 326.94 403.092 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2498 0 obj << /Type /Annot /Subtype /Link /Rect [ 282.21 394.212 326.94 403.092 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2499 0 obj << /Type /Annot /Subtype /Link /Rect [ 180.874 280.116 225.246 288.996 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2500 0 obj << /Type /Annot /Subtype /Link /Rect [ 180.874 280.116 225.246 288.996 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2378 0 R /H /I >> endobj 2501 0 obj << /Length 2502 0 R /Filter /FlateDecode >> stream xœÅXëoÛ6ÿî¿‚À€5 "¤ÞÁV iÒ¡EÑ®³Û~hŠ•–éX®$ç±aÿûŽ)É宨Ðåw¿»ãñGÒŸgaøµÄGQg³Ïª €"ÇW]žˆkSeHÉJŬž@µÍ$6èÝ,Ÿaôóìý\! w3<4'•ç³×=|1‚¿9~߇ÐÿÅáƒ\¹.þ[.ÎÞ€çâý‘Þµý]¯tš>èi°ÅPª2­>G±‰§ùœŒwa`sU„ߣ›ÙÅböÃSŒë®Î¡H°ÒHüP´ÈÐû#Šéñ´x>»ZŒ àgm´»ÇA6Ä“½°äâ*¨&¦—,ãMP†4¸!¢‘}OÌ…7¿\ž/®¬Wϯž,æÖóWÏ^ÎQc¡Õ#¾ocàì-\S ‚C èÍvÅj^¡OE’óªÒ¢®P±FÅòëÊÖ†\bãƒ1¿1öt—ÇuRäZg:W~d{$Œ¢€¨\ÍòšÝkÅÈF°oG…8\í»ü„º†™;¤¥b²D¬Õ@b“"Ò?—¨ì*(ˆÉ@¨GM0ßÿÎa…¦øåZM"9Ƴi‡š2°.ʘ[ÛißÿJ˜À”8eUeå½3®ǘºi$×1e c÷VÊó¥fZWôÓcôå²&Žo»‘EQ¼v^Þì2žÃžbù ½eéŽW<‡}b‡Q&Œ5âBÆ:ç(MªZìb¨óšå1—[šµø†b¶ác? #so~‡žˆšô‚z®¹ O]w¤o8ôlL ›žêÚðHç%YÆW ìst}´âk¶Këëcd¡’¯K^m$Ã)~»Kê :+y]&ü–¥=Ý!yÅ¡M±ÜnÔ‚/K L£ý¸ä`k5ÆÑj&‡À)$²æ“†¥éiÝÀv§ä7¬\¥¼’ëÛ™Ìà 9H™¦þ“¶Jª‡lY¤àÜm’xƒøý6Mâ¤V(u¡ñMvƒJ>ˆB˜WÙe¨Jò›” ÃÅ2•vYcmdl¢*ŒmV˜70‘±.ÆZçè¢(RÎòS¤j<NL34‰ìfµC“ÁÅô Þ!ÅûÀ¡Žm8§ÑòHñ_îþ±Á¯Ýÿc _ˆÝõm( Ó€9ÚøHëÁvBt”¹•ÃÖ¨“[®û’¼æ7¼ÔÍ¢•¦ ú¶\9‘ìå³ÓÙpÝš¸WªG”e#¨AkpsQ‰9±õÄw¦ýäxáUæ$I…žãÔ&©´ÜI@$pV%À2º‹iaÉj Õ¨’?¸–×M.«m/xªÅ|—-y;JQKMP­r¡¥Ï;^¶¬Ë"ëÙ7 OŠý`!glÉ*Ž€uª“ŒÛèÙÝq”s å¬(9ª7,G*Ÿb$-Š-L‚…ƆAå² Žàéã6€í:âB¨ñ%¯â2Ùö/Ŧ—€ Ô:.&n¨vŒ¾–Cà„;êò š*ÕªUò¸(WýéMš“Ùv[ÛR•]o›³ž[¦{>ìÛ‘Q×l‹^{Ëãd@¾»¾åC¯1ñj1ïµ÷¬—ZäÉ yªv[8«$†9DG’ûtC&¡'ÉÀñ‚»<Ï ÉO9L‚Äslêú@‚Ô`¨5Ò±²îQ>»í8o¥*ɶ©Ü> endobj 2502 0 obj 1699 endobj 2058 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 556.12 null] >> endobj 2061 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 207.984 null] >> endobj 2064 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 172.981 null] >> endobj 2504 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 477.844 190.0 486.244 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 740 0 R /H /I >> endobj 2506 0 obj << /Type /Action /S /GoTo /D [2374 0 R /XYZ 72.0 720.0 null] >> endobj 2507 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 455.244 152.22 464.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2506 0 R /H /I >> endobj 2508 0 obj << /Type /Annot /Subtype /Link /Rect [ 130.0 455.244 152.22 464.124 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2506 0 R /H /I >> endobj 2509 0 obj << /Type /Annot /Subtype /Link /Rect [ 291.493 433.604 363.493 442.004 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 641 0 R /H /I >> endobj 2510 0 obj << /Type /Annot /Subtype /Link /Rect [ 430.82 337.964 466.82 346.364 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 1025 0 R /H /I >> endobj 2511 0 obj << /URI (http://odbc.postgresql.org) /S /URI >> endobj 2512 0 obj << /Type /Annot /Subtype /Link /Rect [ 382.539 97.505 428.495 106.505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2511 0 R /H /I >> endobj 2513 0 obj << /Type /Annot /Subtype /Link /Rect [ 433.891 97.505 536.671 106.505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2511 0 R /H /I >> endobj 2514 0 obj << /URI (http://www.mysql.com/products/connector/odbc/) /S /URI >> endobj 2515 0 obj << /Type /Annot /Subtype /Link /Rect [ 247.79 85.505 291.12 94.505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2514 0 R /H /I >> endobj 2516 0 obj << /Type /Annot /Subtype /Link /Rect [ 297.79 85.505 494.45 94.505 ] /C [ 0 0 0 ] /Border [ 0 0 0 ] /A 2514 0 R /H /I >> endobj 2517 0 obj << /Length 2518 0 R /Filter /FlateDecode >> stream xœÅYÝÔ6ß¿Âo=$Îç¯|ñVz¥¢â€Óê *›ønS²ñ^’eY©|DZóé$TªDi=cgæ7ã;f !ój±Wåz-tE–N¥ÞJŸ;›Æ+Qûý±hM?eõ®Yf š9¦µÐ »‡:™¦ qrBDàýoU-« Û=lFN<#óêúúÍ¢› ÐÄBjO[î>1æµÑT›“HKu¸ÌŠT~[”Î ”OÇ ÀD1‚b–KâJt¶ ¢šöà½$¿ÈsïC\BÕ¨;Gþø ”pßsýñçüq$¾fòT-ºBZ0{ø]Y—P¦UªãAçø°=›ÐÏY ¸½xQÁÔڑκ{S¸ a\¼¨Ë¸¨âæRPµÌ+KÆåãqok›è ¢-†šÑ‹:¡¯u HJ ]ñ² Û"V †ˆ8¡T¹{´6@êK•wÆŸvb^¶¤êFØÖƒcJç«É$KdÕ š‘?1jÊë¢P×/mžvY²kCX¡!À3Qä4Ä‘ð Ϊu–ÙFB_F^¨Sa\6ô €†1 ¡á˜ Úñp/}è{êáXô¹aYj )Ϫ¶][MÅ@-”œñìH¶»„tµý î]sàœŒ¡È UʯV7î˜xpQb~ØV·›ÕêÆá° ߇z(ØjhœuïËL5—)(Ö•.ãÓç¶„§ *ÖàŒ£0‚ü«ŽÛ§£,3˜Í 7EÈh£¥ƽòJIÀÙŒ •ÌÉE÷¸†wYzJA|ìA£€"Ö6·ó~«ò,AÚûsQÇËÕ,‘.æLð5dÝu 6 ¼„ |ìë^L|:³åß/7è¢+’ú®¬o÷…éÕê ˸V%Fªs »bB#‹ÈܦfÏåÀ º& ¹Ù§3…Fx Sh7aà9Ímº³î¿ƒîl Ù^ÕËÏ/Ùé 5  ƒÀõˆ’(Z4êÓ2ÚÌ[Û` í@@§‡"…{mgÝGÛÙ2+à¾S­Õ5ueÔTõE˜áÁCàÞØ\]aù-‘‡Õ!àŽÉÙ o¨.{F««Ž±‹¿ö‹- †è1¤ÄÎíz¡‰ÅœÂ»™GáÏØ>›I®[1T÷¦ºª§|xÜÝêùðŠƒúîQ¶fÀÇ©á>Åpɉ" K]¹]]^\]©t›àƒªêG8ÕO9Våã4d¾À~@"ýihfŸÏ3æl²¨‹Úe(º7Œ¾7šÛ>"ú.!ú2í…´AœE3êÆRsG3ˆ0åPRE8gîÍy5"úmNõˆ5YÔ> 4Õ5£m@N§ÞŸu(µ¿:”*=ƒîÊ~UVe±«)èŒaá³›»µ#m‰.La0ç~뀵™P á`×liþèvóz‹èq endstream endobj 2505 0 obj [ 2504 0 R 2507 0 R 2508 0 R 2509 0 R 2510 0 R 2512 0 R 2513 0 R 2515 0 R 2516 0 R ] endobj 2503 0 obj << /Resources 3 0 R /Type /Page /MediaBox [0 0 612 792] /CropBox [0 0 612 792] /BleedBox [0 0 612 792] /TrimBox [0 0 612 792] /Parent 1 0 R /Annots 2505 0 R /Contents 2517 0 R >> endobj 2518 0 obj 2054 endobj 2519 0 obj << /Type /Action /S /GoTo /D [8 0 R /XYZ 72.0 720.0 null] >> endobj 2520 0 obj << /Type /Action /S /GoTo /D [23 0 R /XYZ 72.0 720.0 null] >> endobj 2521 0 obj << /Type /Action /S /GoTo /D [23 0 R /XYZ 72.0 657.113 null] >> endobj 2522 0 obj << /Type /Action /S /GoTo /D [1864 0 R /XYZ 72.0 118.883 null] >> endobj 2523 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 696.0 null] >> endobj 2524 0 obj << /Type /Action /S /GoTo /D [1873 0 R /XYZ 72.0 130.562 null] >> endobj 2525 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 708.0 null] >> endobj 2526 0 obj << /Type /Action /S /GoTo /D [2002 0 R /XYZ 72.0 119.854 null] >> endobj 2527 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 720.0 null] >> endobj 2528 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 525.264 null] >> endobj 2529 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 385.384 null] >> endobj 2530 0 obj << /Type /Action /S /GoTo /D [2503 0 R /XYZ 72.0 335.864 null] >> endobj 2531 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 576.832 null] >> endobj 2532 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 526.704 null] >> endobj 2533 0 obj << /Type /Action /S /GoTo /D [2005 0 R /XYZ 72.0 366.144 null] >> endobj 2534 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 466.496 null] >> endobj 2535 0 obj << /Type /Action /S /GoTo /D [2008 0 R /XYZ 72.0 393.098 null] >> endobj 2536 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 643.83 null] >> endobj 2537 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 595.116 null] >> endobj 2538 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 515.949 null] >> endobj 2539 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 421.518 null] >> endobj 2540 0 obj << /Type /Action /S /GoTo /D [2011 0 R /XYZ 72.0 339.087 null] >> endobj 2541 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 699.264 null] >> endobj 2542 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 651.06 null] >> endobj 2543 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 469.734 null] >> endobj 2544 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 376.068 null] >> endobj 2545 0 obj << /Type /Action /S /GoTo /D [2016 0 R /XYZ 72.0 294.402 null] >> endobj 2546 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 520.528 null] >> endobj 2547 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 471.248 null] >> endobj 2548 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 335.232 null] >> endobj 2549 0 obj << /Type /Action /S /GoTo /D [2021 0 R /XYZ 72.0 241.952 null] >> endobj 2551 0 obj << /Title (CLSQL Users' Guide) /Parent 2550 0 R /Next 2553 0 R /A 2519 0 R >> endobj 2552 0 obj << /Type /Action /S /GoTo /D [356 0 R /XYZ 72.0 720.0 null] >> endobj 2553 0 obj << /Title (Table of Contents) /Parent 2550 0 R /Prev 2551 0 R /Next 2554 0 R /A 2552 0 R >> endobj 2554 0 obj << /Title (Preface) /Parent 2550 0 R /Prev 2553 0 R /Next 2555 0 R /A 357 0 R >> endobj 2555 0 obj << /Title /Parent 2550 0 R /Prev 2554 0 R /Next 2573 0 R /First 2556 0 R /Last 2564 0 R /Count -17 /A 361 0 R >> endobj 2556 0 obj << /Title (Purpose) /Parent 2555 0 R /Next 2557 0 R /A 364 0 R >> endobj 2557 0 obj << /Title (History) /Parent 2555 0 R /Prev 2556 0 R /Next 2558 0 R /A 367 0 R >> endobj 2558 0 obj << /Title (Prerequisites) /Parent 2555 0 R /Prev 2557 0 R /Next 2564 0 R /First 2559 0 R /Last 2563 0 R /Count -5 /A 370 0 R >> endobj 2559 0 obj << /Title (ASDF) /Parent 2558 0 R /Next 2560 0 R /A 373 0 R >> endobj 2560 0 obj << /Title (UFFI) /Parent 2558 0 R /Prev 2559 0 R /Next 2561 0 R /A 376 0 R >> endobj 2561 0 obj << /Title (MD5) /Parent 2558 0 R /Prev 2560 0 R /Next 2562 0 R /A 379 0 R >> endobj 2562 0 obj << /Title (Supported Common Lisp Implementation) /Parent 2558 0 R /Prev 2561 0 R /Next 2563 0 R /A 382 0 R >> endobj 2563 0 obj << /Title (Supported SQL Implementation) /Parent 2558 0 R /Prev 2562 0 R /A 385 0 R >> endobj 2564 0 obj << /Title (Installation) /Parent 2555 0 R /Prev 2558 0 R /First 2565 0 R /Last 2572 0 R /Count -8 /A 388 0 R >> endobj 2565 0 obj << /Title (Ensure ASDF is loaded) /Parent 2564 0 R /Next 2566 0 R /A 391 0 R >> endobj 2566 0 obj << /Title (Build C helper libraries) /Parent 2564 0 R /Prev 2565 0 R /Next 2569 0 R /First 2567 0 R /Last 2568 0 R /Count -2 /A 394 0 R >> endobj 2567 0 obj << /Title (Microsoft Windows) /Parent 2566 0 R /Next 2568 0 R /A 2520 0 R >> endobj 2568 0 obj << /Title (UNIX) /Parent 2566 0 R /Prev 2567 0 R /A 2521 0 R >> endobj 2569 0 obj << /Title (Add UFFI path) /Parent 2564 0 R /Prev 2566 0 R /Next 2570 0 R /A 397 0 R >> endobj 2570 0 obj << /Title (Add MD5 path) /Parent 2564 0 R /Prev 2569 0 R /Next 2571 0 R /A 400 0 R >> endobj 2571 0 obj << /Title (Add CLSQL path and load module) /Parent 2564 0 R /Prev 2570 0 R /Next 2572 0 R /A 403 0 R >> endobj 2572 0 obj << /Title (Run test suite \(optional\)) /Parent 2564 0 R /Prev 2571 0 R /A 406 0 R >> endobj 2573 0 obj << /Title /Parent 2550 0 R /Prev 2555 0 R /Next 2581 0 R /First 2574 0 R /Last 2580 0 R /Count -7 /A 409 0 R >> endobj 2574 0 obj << /Title (Introduction) /Parent 2573 0 R /Next 2575 0 R /A 412 0 R >> endobj 2575 0 obj << /Title (Data Modeling with CLSQL) /Parent 2573 0 R /Prev 2574 0 R /Next 2576 0 R /A 415 0 R >> endobj 2576 0 obj << /Title (Class Relations) /Parent 2573 0 R /Prev 2575 0 R /Next 2577 0 R /A 418 0 R >> endobj 2577 0 obj << /Title (Object Creation) /Parent 2573 0 R /Prev 2576 0 R /Next 2578 0 R /A 421 0 R >> endobj 2578 0 obj << /Title (Finding Objects) /Parent 2573 0 R /Prev 2577 0 R /Next 2579 0 R /A 424 0 R >> endobj 2579 0 obj << /Title (Deleting Objects) /Parent 2573 0 R /Prev 2578 0 R /Next 2580 0 R /A 427 0 R >> endobj 2580 0 obj << /Title (Conclusion) /Parent 2573 0 R /Prev 2579 0 R /A 430 0 R >> endobj 2581 0 obj << /Title (Connection and Initialisation) /Parent 2550 0 R /Prev 2573 0 R /Next 2605 0 R /First 2582 0 R /Last 2604 0 R /Count -23 /A 433 0 R >> endobj 2582 0 obj << /Title (DATABASE) /Parent 2581 0 R /Next 2583 0 R /A 293 0 R >> endobj 2583 0 obj << /Title (*CONNECT-IF-EXISTS*) /Parent 2581 0 R /Prev 2582 0 R /Next 2584 0 R /A 87 0 R >> endobj 2584 0 obj << /Title (*DB-POOL-MAX-FREE-CONNECTIONS*) /Parent 2581 0 R /Prev 2583 0 R /Next 2585 0 R /A 110 0 R >> endobj 2585 0 obj << /Title (*DEFAULT-DATABASE*) /Parent 2581 0 R /Prev 2584 0 R /Next 2586 0 R /A 136 0 R >> endobj 2586 0 obj << /Title (*DEFAULT-DATABASE-TYPE*) /Parent 2581 0 R /Prev 2585 0 R /Next 2587 0 R /A 84 0 R >> endobj 2587 0 obj << /Title (*INITIALIZED-DATABASE-TYPES*) /Parent 2581 0 R /Prev 2586 0 R /Next 2588 0 R /A 163 0 R >> endobj 2588 0 obj << /Title (CONNECT) /Parent 2581 0 R /Prev 2587 0 R /Next 2589 0 R /A 76 0 R >> endobj 2589 0 obj << /Title (CONNECTED-DATABASES) /Parent 2581 0 R /Prev 2588 0 R /Next 2590 0 R /A 106 0 R >> endobj 2590 0 obj << /Title (DATABASE-NAME) /Parent 2581 0 R /Prev 2589 0 R /Next 2591 0 R /A 226 0 R >> endobj 2591 0 obj << /Title (DATABASE-NAME-FROM-SPEC) /Parent 2581 0 R /Prev 2590 0 R /Next 2592 0 R /A 204 0 R >> endobj 2592 0 obj << /Title (DATABASE-TYPE) /Parent 2581 0 R /Prev 2591 0 R /Next 2593 0 R /A 315 0 R >> endobj 2593 0 obj << /Title (DISCONNECT) /Parent 2581 0 R /Prev 2592 0 R /Next 2594 0 R /A 117 0 R >> endobj 2594 0 obj << /Title (DISCONNECT-POOLED) /Parent 2581 0 R /Prev 2593 0 R /Next 2595 0 R /A 141 0 R >> endobj 2595 0 obj << /Title (FIND-DATABASE) /Parent 2581 0 R /Prev 2594 0 R /Next 2596 0 R /A 189 0 R >> endobj 2596 0 obj << /Title (INITIALIZE-DATABASE-TYPE) /Parent 2581 0 R /Prev 2595 0 R /Next 2597 0 R /A 152 0 R >> endobj 2597 0 obj << /Title (RECONNECT) /Parent 2581 0 R /Prev 2596 0 R /Next 2598 0 R /A 186 0 R >> endobj 2598 0 obj << /Title (STATUS) /Parent 2581 0 R /Prev 2597 0 R /Next 2599 0 R /A 191 0 R >> endobj 2599 0 obj << /Title (CREATE-DATABASE) /Parent 2581 0 R /Prev 2598 0 R /Next 2600 0 R /A 251 0 R >> endobj 2600 0 obj << /Title (DESTROY-DATABASE) /Parent 2581 0 R /Prev 2599 0 R /Next 2601 0 R /A 254 0 R >> endobj 2601 0 obj << /Title (PROBE-DATABASE) /Parent 2581 0 R /Prev 2600 0 R /Next 2602 0 R /A 256 0 R >> endobj 2602 0 obj << /Title (LIST-DATABASES) /Parent 2581 0 R /Prev 2601 0 R /Next 2603 0 R /A 264 0 R >> endobj 2603 0 obj << /Title (WITH-DATABASE) /Parent 2581 0 R /Prev 2602 0 R /Next 2604 0 R /A 286 0 R >> endobj 2604 0 obj << /Title (WITH-DEFAULT-DATABASE) /Parent 2581 0 R /Prev 2603 0 R /A 340 0 R >> endobj 2605 0 obj << /Title (The Symbolic SQL Syntax) /Parent 2550 0 R /Prev 2581 0 R /Next 2616 0 R /First 2606 0 R /Last 2615 0 R /Count -10 /A 482 0 R >> endobj 2606 0 obj << /Title (ENABLE-SQL-READER-SYNTAX) /Parent 2605 0 R /Next 2607 0 R /A 485 0 R >> endobj 2607 0 obj << /Title (DISABLE-SQL-READER-SYNTAX) /Parent 2605 0 R /Prev 2606 0 R /Next 2608 0 R /A 499 0 R >> endobj 2608 0 obj << /Title (LOCALLY-ENABLE-SQL-READER-SYNTAX) /Parent 2605 0 R /Prev 2607 0 R /Next 2609 0 R /A 523 0 R >> endobj 2609 0 obj << /Title (LOCALLY-DISABLE-SQL-READER-SYNTAX) /Parent 2605 0 R /Prev 2608 0 R /Next 2610 0 R /A 526 0 R >> endobj 2610 0 obj << /Title (RESTORE-SQL-READER-SYNTAX-STATE) /Parent 2605 0 R /Prev 2609 0 R /Next 2611 0 R /A 512 0 R >> endobj 2611 0 obj << /Title (FILE-ENABLE-SQL-READER-SYNTAX) /Parent 2605 0 R /Prev 2610 0 R /Next 2612 0 R /A 517 0 R >> endobj 2612 0 obj << /Title (SQL) /Parent 2605 0 R /Prev 2611 0 R /Next 2613 0 R /A 602 0 R >> endobj 2613 0 obj << /Title (SQL-EXPRESSION) /Parent 2605 0 R /Prev 2612 0 R /Next 2614 0 R /A 605 0 R >> endobj 2614 0 obj << /Title (SQL-OPERATION) /Parent 2605 0 R /Prev 2613 0 R /Next 2615 0 R /A 607 0 R >> endobj 2615 0 obj << /Title (SQL-OPERATOR) /Parent 2605 0 R /Prev 2614 0 R /A 632 0 R >> endobj 2616 0 obj << /Title (Functional Data Definition Language \(FDDL\)) /Parent 2550 0 R /Prev 2605 0 R /Next 2640 0 R /First 2617 0 R /Last 2639 0 R /Count -23 /A 1136 0 R >> endobj 2617 0 obj << /Title (CREATE-TABLE) /Parent 2616 0 R /Next 2618 0 R /A 641 0 R >> endobj 2618 0 obj << /Title (DROP-TABLE) /Parent 2616 0 R /Prev 2617 0 R /Next 2619 0 R /A 652 0 R >> endobj 2619 0 obj << /Title (LIST-TABLES) /Parent 2616 0 R /Prev 2618 0 R /Next 2620 0 R /A 654 0 R >> endobj 2620 0 obj << /Title (TABLE-EXISTS-P) /Parent 2616 0 R /Prev 2619 0 R /Next 2621 0 R /A 662 0 R >> endobj 2621 0 obj << /Title (CREATE-VIEW) /Parent 2616 0 R /Prev 2620 0 R /Next 2622 0 R /A 686 0 R >> endobj 2622 0 obj << /Title (DROP-VIEW) /Parent 2616 0 R /Prev 2621 0 R /Next 2623 0 R /A 697 0 R >> endobj 2623 0 obj << /Title (LIST-VIEWS) /Parent 2616 0 R /Prev 2622 0 R /Next 2624 0 R /A 699 0 R >> endobj 2624 0 obj << /Title (VIEW-EXISTS-P) /Parent 2616 0 R /Prev 2623 0 R /Next 2625 0 R /A 707 0 R >> endobj 2625 0 obj << /Title (CREATE-INDEX) /Parent 2616 0 R /Prev 2624 0 R /Next 2626 0 R /A 737 0 R >> endobj 2626 0 obj << /Title (DROP-INDEX) /Parent 2616 0 R /Prev 2625 0 R /Next 2627 0 R /A 740 0 R >> endobj 2627 0 obj << /Title (LIST-INDEXES) /Parent 2616 0 R /Prev 2626 0 R /Next 2628 0 R /A 742 0 R >> endobj 2628 0 obj << /Title (INDEX-EXISTS-P) /Parent 2616 0 R /Prev 2627 0 R /Next 2629 0 R /A 750 0 R >> endobj 2629 0 obj << /Title (ATTRIBUTE-TYPE) /Parent 2616 0 R /Prev 2628 0 R /Next 2630 0 R /A 778 0 R >> endobj 2630 0 obj << /Title (LIST-ATTRIBUTE-TYPES) /Parent 2616 0 R /Prev 2629 0 R /Next 2631 0 R /A 781 0 R >> endobj 2631 0 obj << /Title (LIST-ATTRIBUTES) /Parent 2616 0 R /Prev 2630 0 R /Next 2632 0 R /A 792 0 R >> endobj 2632 0 obj << /Title (CREATE-SEQUENCE) /Parent 2616 0 R /Prev 2631 0 R /Next 2633 0 R /A 805 0 R >> endobj 2633 0 obj << /Title (DROP-SEQUENCE) /Parent 2616 0 R /Prev 2632 0 R /Next 2634 0 R /A 813 0 R >> endobj 2634 0 obj << /Title (LIST-SEQUENCES) /Parent 2616 0 R /Prev 2633 0 R /Next 2635 0 R /A 815 0 R >> endobj 2635 0 obj << /Title (SEQUENCE-EXISTS-P) /Parent 2616 0 R /Prev 2634 0 R /Next 2636 0 R /A 833 0 R >> endobj 2636 0 obj << /Title (SEQUENCE-LAST) /Parent 2616 0 R /Prev 2635 0 R /Next 2637 0 R /A 817 0 R >> endobj 2637 0 obj << /Title (SEQUENCE-NEXT) /Parent 2616 0 R /Prev 2636 0 R /Next 2638 0 R /A 836 0 R >> endobj 2638 0 obj << /Title (SET-SEQUENCE-POSITION) /Parent 2616 0 R /Prev 2637 0 R /Next 2639 0 R /A 853 0 R >> endobj 2639 0 obj << /Title (TRUNCATE-DATABASE) /Parent 2616 0 R /Prev 2638 0 R /A 950 0 R >> endobj 2640 0 obj << /Title (Functional Data Manipulation Language \(FDML\)) /Parent 2550 0 R /Prev 2616 0 R /Next 2653 0 R /First 2641 0 R /Last 2652 0 R /Count -12 /A 1185 0 R >> endobj 2641 0 obj << /Title (*CACHE-TABLE-QUERIES-DEFAULT*) /Parent 2640 0 R /Next 2642 0 R /A 970 0 R >> endobj 2642 0 obj << /Title (CACHE-TABLE-QUERIES) /Parent 2640 0 R /Prev 2641 0 R /Next 2643 0 R /A 964 0 R >> endobj 2643 0 obj << /Title (INSERT-RECORDS) /Parent 2640 0 R /Prev 2642 0 R /Next 2644 0 R /A 985 0 R >> endobj 2644 0 obj << /Title (UPDATE-RECORDS) /Parent 2640 0 R /Prev 2643 0 R /Next 2645 0 R /A 977 0 R >> endobj 2645 0 obj << /Title (DELETE-RECORDS) /Parent 2640 0 R /Prev 2644 0 R /Next 2646 0 R /A 980 0 R >> endobj 2646 0 obj << /Title (EXECUTE-COMMAND) /Parent 2640 0 R /Prev 2645 0 R /Next 2647 0 R /A 1004 0 R >> endobj 2647 0 obj << /Title (QUERY) /Parent 2640 0 R /Prev 2646 0 R /Next 2648 0 R /A 998 0 R >> endobj 2648 0 obj << /Title (PRINT-QUERY) /Parent 2640 0 R /Prev 2647 0 R /Next 2649 0 R /A 1047 0 R >> endobj 2649 0 obj << /Title (SELECT) /Parent 2640 0 R /Prev 2648 0 R /Next 2650 0 R /A 1025 0 R >> endobj 2650 0 obj << /Title (DO-QUERY) /Parent 2640 0 R /Prev 2649 0 R /Next 2651 0 R /A 1027 0 R >> endobj 2651 0 obj << /Title (LOOP) /Parent 2640 0 R /Prev 2650 0 R /Next 2652 0 R /A 1031 0 R >> endobj 2652 0 obj << /Title (MAP-QUERY) /Parent 2640 0 R /Prev 2651 0 R /A 1029 0 R >> endobj 2653 0 obj << /Title (Transaction Handling) /Parent 2550 0 R /Prev 2640 0 R /Next 2662 0 R /First 2654 0 R /Last 2661 0 R /Count -8 /A 1212 0 R >> endobj 2654 0 obj << /Title (START-TRANSACTION) /Parent 2653 0 R /Next 2655 0 R /A 1215 0 R >> endobj 2655 0 obj << /Title (COMMIT) /Parent 2653 0 R /Prev 2654 0 R /Next 2656 0 R /A 1218 0 R >> endobj 2656 0 obj << /Title (ROLLBACK) /Parent 2653 0 R /Prev 2655 0 R /Next 2657 0 R /A 1109 0 R >> endobj 2657 0 obj << /Title (IN-TRANSACTION-P) /Parent 2653 0 R /Prev 2656 0 R /Next 2658 0 R /A 1223 0 R >> endobj 2658 0 obj << /Title (ADD-TRANSACTION-COMMIT-HOOK) /Parent 2653 0 R /Prev 2657 0 R /Next 2659 0 R /A 1112 0 R >> endobj 2659 0 obj << /Title (ADD-TRANSACTION-ROLLBACK-HOOK) /Parent 2653 0 R /Prev 2658 0 R /Next 2660 0 R /A 1228 0 R >> endobj 2660 0 obj << /Title (SET-AUTOCOMMIT) /Parent 2653 0 R /Prev 2659 0 R /Next 2661 0 R /A 1231 0 R >> endobj 2661 0 obj << /Title (WITH-TRANSACTION) /Parent 2653 0 R /Prev 2660 0 R /A 1264 0 R >> endobj 2662 0 obj << /Title (Object Oriented Data Definition Language \(OODDL\)) /Parent 2550 0 R /Prev 2653 0 R /Next 2669 0 R /First 2663 0 R /Last 2668 0 R /Count -6 /A 1448 0 R >> endobj 2663 0 obj << /Title (STANDARD-DB-OBJECT) /Parent 2662 0 R /Next 2664 0 R /A 1359 0 R >> endobj 2664 0 obj << /Title (*DEFAULT-STRING-LENGTH*) /Parent 2662 0 R /Prev 2663 0 R /Next 2665 0 R /A 1331 0 R >> endobj 2665 0 obj << /Title (CREATE-VIEW-FROM-CLASS) /Parent 2662 0 R /Prev 2664 0 R /Next 2666 0 R /A 1356 0 R >> endobj 2666 0 obj << /Title (DEF-VIEW-CLASS) /Parent 2662 0 R /Prev 2665 0 R /Next 2667 0 R /A 1320 0 R >> endobj 2667 0 obj << /Title (DROP-VIEW-FROM-CLASS) /Parent 2662 0 R /Prev 2666 0 R /Next 2668 0 R /A 1350 0 R >> endobj 2668 0 obj << /Title (LIST-CLASSES) /Parent 2662 0 R /Prev 2667 0 R /A 1380 0 R >> endobj 2669 0 obj << /Title (Object Oriented Data Manipulation Language \(OODML\)) /Parent 2550 0 R /Prev 2662 0 R /Next 2681 0 R /First 2670 0 R /Last 2680 0 R /Count -11 /A 1894 0 R >> endobj 2670 0 obj << /Title (*DB-AUTO-SYNC*) /Parent 2669 0 R /Next 2671 0 R /A 1463 0 R >> endobj 2671 0 obj << /Title (*DEFAULT-CACHING*) /Parent 2669 0 R /Prev 2670 0 R /Next 2672 0 R /A 1466 0 R >> endobj 2672 0 obj << /Title (*DEFAULT-UPDATE-OBJECTS-MAX-LEN*) /Parent 2669 0 R /Prev 2671 0 R /Next 2673 0 R /A 1469 0 R >> endobj 2673 0 obj << /Title (INSTANCE-REFRESHED) /Parent 2669 0 R /Prev 2672 0 R /Next 2674 0 R /A 1403 0 R >> endobj 2674 0 obj << /Title (DELETE-INSTANCE-RECORDS) /Parent 2669 0 R /Prev 2673 0 R /Next 2675 0 R /A 1461 0 R >> endobj 2675 0 obj << /Title (UPDATE-RECORDS-FROM-INSTANCE) /Parent 2669 0 R /Prev 2674 0 R /Next 2676 0 R /A 1416 0 R >> endobj 2676 0 obj << /Title (UPDATE-RECORD-FROM-SLOT) /Parent 2669 0 R /Prev 2675 0 R /Next 2677 0 R /A 1421 0 R >> endobj 2677 0 obj << /Title (UPDATE-RECORD-FROM-SLOTS) /Parent 2669 0 R /Prev 2676 0 R /Next 2678 0 R /A 1424 0 R >> endobj 2678 0 obj << /Title (UPDATE-INSTANCE-FROM-RECORDS) /Parent 2669 0 R /Prev 2677 0 R /Next 2679 0 R /A 1455 0 R >> endobj 2679 0 obj << /Title (UPDATE-SLOT-FROM-RECORD) /Parent 2669 0 R /Prev 2678 0 R /Next 2680 0 R /A 1452 0 R >> endobj 2680 0 obj << /Title (UPDATE-OBJECTS-JOINS) /Parent 2669 0 R /Prev 2679 0 R /A 1486 0 R >> endobj 2681 0 obj << /Title (SQL I/O Recording) /Parent 2550 0 R /Prev 2669 0 R /Next 2689 0 R /First 2682 0 R /Last 2688 0 R /Count -7 /A 1919 0 R >> endobj 2682 0 obj << /Title (START-SQL-RECORDING) /Parent 2681 0 R /Next 2683 0 R /A 1519 0 R >> endobj 2683 0 obj << /Title (STOP-SQL-RECORDING) /Parent 2681 0 R /Prev 2682 0 R /Next 2684 0 R /A 1529 0 R >> endobj 2684 0 obj << /Title (SQL-RECORDING-P) /Parent 2681 0 R /Prev 2683 0 R /Next 2685 0 R /A 1522 0 R >> endobj 2685 0 obj << /Title (SQL-STREAM) /Parent 2681 0 R /Prev 2684 0 R /Next 2686 0 R /A 1541 0 R >> endobj 2686 0 obj << /Title (ADD-SQL-STREAM) /Parent 2681 0 R /Prev 2685 0 R /Next 2687 0 R /A 1544 0 R >> endobj 2687 0 obj << /Title (DELETE-SQL-STREAM) /Parent 2681 0 R /Prev 2686 0 R /Next 2688 0 R /A 1547 0 R >> endobj 2688 0 obj << /Title (LIST-SQL-STREAMS) /Parent 2681 0 R /Prev 2687 0 R /A 1550 0 R >> endobj 2689 0 obj << /Title (CLSQL Condition System) /Parent 2550 0 R /Prev 2681 0 R /Next 2702 0 R /First 2690 0 R /Last 2701 0 R /Count -12 /A 1936 0 R >> endobj 2690 0 obj << /Title (*BACKEND-WARNING-BEHAVIOR*) /Parent 2689 0 R /Next 2691 0 R /A 1711 0 R >> endobj 2691 0 obj << /Title (SQL-CONDITION) /Parent 2689 0 R /Prev 2690 0 R /Next 2692 0 R /A 1602 0 R >> endobj 2692 0 obj << /Title (SQL-ERROR) /Parent 2689 0 R /Prev 2691 0 R /Next 2693 0 R /A 1608 0 R >> endobj 2693 0 obj << /Title (SQL-WARNING) /Parent 2689 0 R /Prev 2692 0 R /Next 2694 0 R /A 1615 0 R >> endobj 2694 0 obj << /Title (SQL-DATABASE-WARNING) /Parent 2689 0 R /Prev 2693 0 R /Next 2695 0 R /A 1622 0 R >> endobj 2695 0 obj << /Title (SQL-USER-ERROR) /Parent 2689 0 R /Prev 2694 0 R /Next 2696 0 R /A 1636 0 R >> endobj 2696 0 obj << /Title (SQL-DATABASE-ERROR) /Parent 2689 0 R /Prev 2695 0 R /Next 2697 0 R /A 1661 0 R >> endobj 2697 0 obj << /Title (SQL-CONNECTION-ERROR) /Parent 2689 0 R /Prev 2696 0 R /Next 2698 0 R /A 1669 0 R >> endobj 2698 0 obj << /Title (SQL-DATABASE-DATA-ERROR) /Parent 2689 0 R /Prev 2697 0 R /Next 2699 0 R /A 1728 0 R >> endobj 2699 0 obj << /Title (SQL-TEMPORARY-ERROR) /Parent 2689 0 R /Prev 2698 0 R /Next 2700 0 R /A 1731 0 R >> endobj 2700 0 obj << /Title (SQL-TIMEOUT-ERROR) /Parent 2689 0 R /Prev 2699 0 R /Next 2701 0 R /A 1734 0 R >> endobj 2701 0 obj << /Title (SQL-FATAL-ERROR) /Parent 2689 0 R /Prev 2700 0 R /A 1737 0 R >> endobj 2702 0 obj << /Title (Index) /Parent 2550 0 R /Prev 2689 0 R /Next 2704 0 R /First 2703 0 R /Last 2703 0 R /Count -1 /A 1963 0 R >> endobj 2703 0 obj << /Title (Alphabetical Index for package CLSQL) /Parent 2702 0 R /A 1845 0 R >> endobj 2704 0 obj << /Title /Parent 2550 0 R /Prev 2702 0 R /Next 2776 0 R /First 2705 0 R /Last 2766 0 R /Count -71 /A 1868 0 R >> endobj 2705 0 obj << /Title (How CLSQL finds and loads foreign libraries) /Parent 2704 0 R /Next 2706 0 R /A 1970 0 R >> endobj 2706 0 obj << /Title (PostgreSQL) /Parent 2704 0 R /Prev 2705 0 R /Next 2713 0 R /First 2707 0 R /Last 2712 0 R /Count -6 /A 1973 0 R >> endobj 2707 0 obj << /Title (Libraries) /Parent 2706 0 R /Next 2708 0 R /A 1976 0 R >> endobj 2708 0 obj << /Title (Initialization) /Parent 2706 0 R /Prev 2707 0 R /Next 2709 0 R /A 1979 0 R >> endobj 2709 0 obj << /Title (Connection Specification) /Parent 2706 0 R /Prev 2708 0 R /Next 2712 0 R /First 2710 0 R /Last 2711 0 R /Count -2 /A 1982 0 R >> endobj 2710 0 obj << /Title (Syntax of connection-spec) /Parent 2709 0 R /Next 2711 0 R /A 2522 0 R >> endobj 2711 0 obj << /Title (Description of connection-spec) /Parent 2709 0 R /Prev 2710 0 R /A 2523 0 R >> endobj 2712 0 obj << /Title (Notes) /Parent 2706 0 R /Prev 2709 0 R /A 1985 0 R >> endobj 2713 0 obj << /Title (PostgreSQL Socket) /Parent 2704 0 R /Prev 2706 0 R /Next 2720 0 R /First 2714 0 R /Last 2719 0 R /Count -6 /A 1988 0 R >> endobj 2714 0 obj << /Title (Libraries) /Parent 2713 0 R /Next 2715 0 R /A 1991 0 R >> endobj 2715 0 obj << /Title (Initialization) /Parent 2713 0 R /Prev 2714 0 R /Next 2716 0 R /A 1994 0 R >> endobj 2716 0 obj << /Title (Connection Specification) /Parent 2713 0 R /Prev 2715 0 R /Next 2719 0 R /First 2717 0 R /Last 2718 0 R /Count -2 /A 1997 0 R >> endobj 2717 0 obj << /Title (Syntax of connection-spec) /Parent 2716 0 R /Next 2718 0 R /A 2524 0 R >> endobj 2718 0 obj << /Title (Description of connection-spec) /Parent 2716 0 R /Prev 2717 0 R /A 2525 0 R >> endobj 2719 0 obj << /Title (Notes) /Parent 2713 0 R /Prev 2716 0 R /A 2042 0 R >> endobj 2720 0 obj << /Title (MySQL) /Parent 2704 0 R /Prev 2713 0 R /Next 2730 0 R /First 2721 0 R /Last 2726 0 R /Count -9 /A 2046 0 R >> endobj 2721 0 obj << /Title (Libraries) /Parent 2720 0 R /Next 2722 0 R /A 2049 0 R >> endobj 2722 0 obj << /Title (Initialization) /Parent 2720 0 R /Prev 2721 0 R /Next 2723 0 R /A 2052 0 R >> endobj 2723 0 obj << /Title (Connection Specification) /Parent 2720 0 R /Prev 2722 0 R /Next 2726 0 R /First 2724 0 R /Last 2725 0 R /Count -2 /A 2055 0 R >> endobj 2724 0 obj << /Title (Syntax of connection-spec) /Parent 2723 0 R /Next 2725 0 R /A 2526 0 R >> endobj 2725 0 obj << /Title (Description of connection-spec) /Parent 2723 0 R /Prev 2724 0 R /A 2527 0 R >> endobj 2726 0 obj << /Title (Notes) /Parent 2720 0 R /Prev 2723 0 R /First 2727 0 R /Last 2729 0 R /Count -3 /A 2058 0 R >> endobj 2727 0 obj << /Title (FDDL) /Parent 2726 0 R /Next 2728 0 R /A 2528 0 R >> endobj 2728 0 obj << /Title (FDML) /Parent 2726 0 R /Prev 2727 0 R /Next 2729 0 R /A 2529 0 R >> endobj 2729 0 obj << /Title (Symbolic SQL Syntax) /Parent 2726 0 R /Prev 2728 0 R /A 2530 0 R >> endobj 2730 0 obj << /Title (ODBC) /Parent 2704 0 R /Prev 2720 0 R /Next 2739 0 R /First 2731 0 R /Last 2738 0 R /Count -8 /A 2061 0 R >> endobj 2731 0 obj << /Title (Libraries) /Parent 2730 0 R /Next 2732 0 R /A 2064 0 R >> endobj 2732 0 obj << /Title (Initialization) /Parent 2730 0 R /Prev 2731 0 R /Next 2733 0 R /A 2067 0 R >> endobj 2733 0 obj << /Title (Connection Specification) /Parent 2730 0 R /Prev 2732 0 R /Next 2736 0 R /First 2734 0 R /Last 2735 0 R /Count -2 /A 2070 0 R >> endobj 2734 0 obj << /Title (Syntax of connection-spec) /Parent 2733 0 R /Next 2735 0 R /A 2531 0 R >> endobj 2735 0 obj << /Title (Description of connection-spec) /Parent 2733 0 R /Prev 2734 0 R /A 2532 0 R >> endobj 2736 0 obj << /Title (Notes) /Parent 2730 0 R /Prev 2733 0 R /Next 2738 0 R /First 2737 0 R /Last 2737 0 R /Count -1 /A 2073 0 R >> endobj 2737 0 obj << /Title (FDDL) /Parent 2736 0 R /A 2533 0 R >> endobj 2738 0 obj << /Title (Connect Examples) /Parent 2730 0 R /Prev 2736 0 R /A 2076 0 R >> endobj 2739 0 obj << /Title (AODBC) /Parent 2704 0 R /Prev 2730 0 R /Next 2746 0 R /First 2740 0 R /Last 2745 0 R /Count -6 /A 2079 0 R >> endobj 2740 0 obj << /Title (Libraries) /Parent 2739 0 R /Next 2741 0 R /A 2082 0 R >> endobj 2741 0 obj << /Title (Initialization) /Parent 2739 0 R /Prev 2740 0 R /Next 2742 0 R /A 2085 0 R >> endobj 2742 0 obj << /Title (Connection Specification) /Parent 2739 0 R /Prev 2741 0 R /Next 2745 0 R /First 2743 0 R /Last 2744 0 R /Count -2 /A 2088 0 R >> endobj 2743 0 obj << /Title (Syntax of connection-spec) /Parent 2742 0 R /Next 2744 0 R /A 2534 0 R >> endobj 2744 0 obj << /Title (Description of connection-spec) /Parent 2742 0 R /Prev 2743 0 R /A 2535 0 R >> endobj 2745 0 obj << /Title (Notes) /Parent 2739 0 R /Prev 2742 0 R /A 2091 0 R >> endobj 2746 0 obj << /Title (SQLite version 2) /Parent 2704 0 R /Prev 2739 0 R /Next 2756 0 R /First 2747 0 R /Last 2752 0 R /Count -9 /A 2094 0 R >> endobj 2747 0 obj << /Title (Libraries) /Parent 2746 0 R /Next 2748 0 R /A 2097 0 R >> endobj 2748 0 obj << /Title (Initialization) /Parent 2746 0 R /Prev 2747 0 R /Next 2749 0 R /A 2100 0 R >> endobj 2749 0 obj << /Title (Connection Specification) /Parent 2746 0 R /Prev 2748 0 R /Next 2752 0 R /First 2750 0 R /Last 2751 0 R /Count -2 /A 2103 0 R >> endobj 2750 0 obj << /Title (Syntax of connection-spec) /Parent 2749 0 R /Next 2751 0 R /A 2536 0 R >> endobj 2751 0 obj << /Title (Description of connection-spec) /Parent 2749 0 R /Prev 2750 0 R /A 2537 0 R >> endobj 2752 0 obj << /Title (Notes) /Parent 2746 0 R /Prev 2749 0 R /First 2753 0 R /Last 2755 0 R /Count -3 /A 2106 0 R >> endobj 2753 0 obj << /Title (Connection) /Parent 2752 0 R /Next 2754 0 R /A 2538 0 R >> endobj 2754 0 obj << /Title (FDDL) /Parent 2752 0 R /Prev 2753 0 R /Next 2755 0 R /A 2539 0 R >> endobj 2755 0 obj << /Title (Symbolic SQL Syntax) /Parent 2752 0 R /Prev 2754 0 R /A 2540 0 R >> endobj 2756 0 obj << /Title (SQLite version 3) /Parent 2704 0 R /Prev 2746 0 R /Next 2766 0 R /First 2757 0 R /Last 2762 0 R /Count -9 /A 2109 0 R >> endobj 2757 0 obj << /Title (Libraries) /Parent 2756 0 R /Next 2758 0 R /A 2112 0 R >> endobj 2758 0 obj << /Title (Initialization) /Parent 2756 0 R /Prev 2757 0 R /Next 2759 0 R /A 2115 0 R >> endobj 2759 0 obj << /Title (Connection Specification) /Parent 2756 0 R /Prev 2758 0 R /Next 2762 0 R /First 2760 0 R /Last 2761 0 R /Count -2 /A 2118 0 R >> endobj 2760 0 obj << /Title (Syntax of connection-spec) /Parent 2759 0 R /Next 2761 0 R /A 2541 0 R >> endobj 2761 0 obj << /Title (Description of connection-spec) /Parent 2759 0 R /Prev 2760 0 R /A 2542 0 R >> endobj 2762 0 obj << /Title (Notes) /Parent 2756 0 R /Prev 2759 0 R /First 2763 0 R /Last 2765 0 R /Count -3 /A 2121 0 R >> endobj 2763 0 obj << /Title (Connection) /Parent 2762 0 R /Next 2764 0 R /A 2543 0 R >> endobj 2764 0 obj << /Title (FDDL) /Parent 2762 0 R /Prev 2763 0 R /Next 2765 0 R /A 2544 0 R >> endobj 2765 0 obj << /Title (Symbolic SQL Syntax) /Parent 2762 0 R /Prev 2764 0 R /A 2545 0 R >> endobj 2766 0 obj << /Title (Oracle) /Parent 2704 0 R /Prev 2756 0 R /First 2767 0 R /Last 2773 0 R /Count -9 /A 2124 0 R >> endobj 2767 0 obj << /Title (Libraries) /Parent 2766 0 R /Next 2768 0 R /A 2127 0 R >> endobj 2768 0 obj << /Title (Library Versions) /Parent 2766 0 R /Prev 2767 0 R /Next 2769 0 R /A 2130 0 R >> endobj 2769 0 obj << /Title (Initialization) /Parent 2766 0 R /Prev 2768 0 R /Next 2770 0 R /A 2133 0 R >> endobj 2770 0 obj << /Title (Connection Specification) /Parent 2766 0 R /Prev 2769 0 R /Next 2773 0 R /First 2771 0 R /Last 2772 0 R /Count -2 /A 2136 0 R >> endobj 2771 0 obj << /Title (Syntax of connection-spec) /Parent 2770 0 R /Next 2772 0 R /A 2546 0 R >> endobj 2772 0 obj << /Title (Description of connection-spec) /Parent 2770 0 R /Prev 2771 0 R /A 2547 0 R >> endobj 2773 0 obj << /Title (Notes) /Parent 2766 0 R /Prev 2770 0 R /First 2774 0 R /Last 2775 0 R /Count -2 /A 2139 0 R >> endobj 2774 0 obj << /Title (Symbolic SQL Syntax) /Parent 2773 0 R /Next 2775 0 R /A 2548 0 R >> endobj 2775 0 obj << /Title (Transactions) /Parent 2773 0 R /Prev 2774 0 R /A 2549 0 R >> endobj 2776 0 obj << /Title (Glossary) /Parent 2550 0 R /Prev 2704 0 R /A 2142 0 R >> endobj 2777 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Courier-Oblique /Encoding /WinAnsiEncoding >> endobj 2778 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >> endobj 2779 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding >> endobj 2780 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj 2781 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Courier /Encoding /WinAnsiEncoding >> endobj 2782 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Times-Italic /Encoding /WinAnsiEncoding >> endobj 2783 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Times-Bold /Encoding /WinAnsiEncoding >> endobj 2784 0 obj << /Limits [(add-sql-stream) (add-sql-stream)] /Names [(add-sql-stream) 1544 0 R] >> endobj 2785 0 obj << /Limits [(add-transaction-commit-hook) (add-transaction-commit-hook)] /Names [(add-transaction-commit-hook) 1112 0 R] >> endobj 2786 0 obj << /Limits [(add-transaction-rollback-hook) (add-transaction-rollback-hook)] /Names [(add-transaction-rollback-hook) 1228 0 R] >> endobj 2787 0 obj << /Limits [(aodbc) (aodbc)] /Names [(aodbc) 2079 0 R] >> endobj 2788 0 obj << /Limits [(appendix) (appendix)] /Names [(appendix) 1868 0 R] >> endobj 2789 0 obj << /Limits [(attribute-type) (attribute-type)] /Names [(attribute-type) 778 0 R] >> endobj 2790 0 obj << /Limits [(backend-warning-behavior) (backend-warning-behavior)] /Names [(backend-warning-behavior) 1711 0 R] >> endobj 2791 0 obj << /Limits [(cache-table-queries) (cache-table-queries)] /Names [(cache-table-queries) 964 0 R] >> endobj 2792 0 obj << /Limits [(cache-table-queries-default) (cache-table-queries-default)] /Names [(cache-table-queries-default) 970 0 R] >> endobj 2793 0 obj << /Limits [(clsql-index) (clsql-index)] /Names [(clsql-index) 1845 0 R] >> endobj 2794 0 obj << /Limits [(commit) (commit)] /Names [(commit) 1218 0 R] >> endobj 2795 0 obj << /Limits [(connect) (connect)] /Names [(connect) 76 0 R] >> endobj 2796 0 obj << /Limits [(connect-if-exists) (connect-if-exists)] /Names [(connect-if-exists) 87 0 R] >> endobj 2797 0 obj << /Limits [(connected-databases) (connected-databases)] /Names [(connected-databases) 106 0 R] >> endobj 2798 0 obj << /Limits [(create-database) (create-database)] /Names [(create-database) 251 0 R] >> endobj 2799 0 obj << /Limits [(create-index) (create-index)] /Names [(create-index) 737 0 R] >> endobj 2800 0 obj << /Limits [(create-sequence) (create-sequence)] /Names [(create-sequence) 805 0 R] >> endobj 2801 0 obj << /Limits [(create-table) (create-table)] /Names [(create-table) 641 0 R] >> endobj 2802 0 obj << /Limits [(create-view) (create-view)] /Names [(create-view) 686 0 R] >> endobj 2803 0 obj << /Limits [(create-view-from-class) (create-view-from-class)] /Names [(create-view-from-class) 1356 0 R] >> endobj 2804 0 obj << /Limits [(csql) (csql)] /Names [(csql) 409 0 R] >> endobj 2805 0 obj << /Limits [(csql-concl) (csql-concl)] /Names [(csql-concl) 430 0 R] >> endobj 2806 0 obj << /Limits [(csql-creat) (csql-creat)] /Names [(csql-creat) 421 0 R] >> endobj 2807 0 obj << /Limits [(csql-del) (csql-del)] /Names [(csql-del) 427 0 R] >> endobj 2808 0 obj << /Limits [(csql-find) (csql-find)] /Names [(csql-find) 424 0 R] >> endobj 2809 0 obj << /Limits [(csql-intro) (csql-intro)] /Names [(csql-intro) 412 0 R] >> endobj 2810 0 obj << /Limits [(csql-rel) (csql-rel)] /Names [(csql-rel) 418 0 R] >> endobj 2811 0 obj << /Limits [(database) (database)] /Names [(database) 293 0 R] >> endobj 2812 0 obj << /Limits [(database-name) (database-name)] /Names [(database-name) 226 0 R] >> endobj 2813 0 obj << /Limits [(database-name-from-spec) (database-name-from-spec)] /Names [(database-name-from-spec) 204 0 R] >> endobj 2814 0 obj << /Limits [(database-type) (database-type)] /Names [(database-type) 315 0 R] >> endobj 2815 0 obj << /Limits [(db-auto-sync) (db-auto-sync)] /Names [(db-auto-sync) 1463 0 R] >> endobj 2816 0 obj << /Limits [(db-pool-max-free-connections) (db-pool-max-free-connections)] /Names [(db-pool-max-free-connections) 110 0 R] >> endobj 2817 0 obj << /Limits [(def-view-class) (def-view-class)] /Names [(def-view-class) 1320 0 R] >> endobj 2818 0 obj << /Limits [(default-caching) (default-caching)] /Names [(default-caching) 1466 0 R] >> endobj 2819 0 obj << /Limits [(default-database) (default-database)] /Names [(default-database) 136 0 R] >> endobj 2820 0 obj << /Limits [(default-database-type) (default-database-type)] /Names [(default-database-type) 84 0 R] >> endobj 2821 0 obj << /Limits [(default-string-length) (default-string-length)] /Names [(default-string-length) 1331 0 R] >> endobj 2822 0 obj << /Limits [(default-update-objects-max-len) (default-update-objects-max-len)] /Names [(default-update-objects-max-len) 1469 0 R] >> endobj 2823 0 obj << /Limits [(delete-instance-records) (delete-instance-records)] /Names [(delete-instance-records) 1461 0 R] >> endobj 2824 0 obj << /Limits [(delete-records) (delete-records)] /Names [(delete-records) 980 0 R] >> endobj 2825 0 obj << /Limits [(delete-sql-stream) (delete-sql-stream)] /Names [(delete-sql-stream) 1547 0 R] >> endobj 2826 0 obj << /Limits [(destroy-database) (destroy-database)] /Names [(destroy-database) 254 0 R] >> endobj 2827 0 obj << /Limits [(disable-sql-reader-syntax) (disable-sql-reader-syntax)] /Names [(disable-sql-reader-syntax) 499 0 R] >> endobj 2828 0 obj << /Limits [(disconnect) (disconnect)] /Names [(disconnect) 117 0 R] >> endobj 2829 0 obj << /Limits [(disconnect-pooled) (disconnect-pooled)] /Names [(disconnect-pooled) 141 0 R] >> endobj 2830 0 obj << /Limits [(do-query) (do-query)] /Names [(do-query) 1027 0 R] >> endobj 2831 0 obj << /Limits [(drop-index) (drop-index)] /Names [(drop-index) 740 0 R] >> endobj 2832 0 obj << /Limits [(drop-sequence) (drop-sequence)] /Names [(drop-sequence) 813 0 R] >> endobj 2833 0 obj << /Limits [(drop-table) (drop-table)] /Names [(drop-table) 652 0 R] >> endobj 2834 0 obj << /Limits [(drop-view) (drop-view)] /Names [(drop-view) 697 0 R] >> endobj 2835 0 obj << /Limits [(drop-view-from-class) (drop-view-from-class)] /Names [(drop-view-from-class) 1350 0 R] >> endobj 2836 0 obj << /Limits [(enable-sql-reader-syntax) (enable-sql-reader-syntax)] /Names [(enable-sql-reader-syntax) 485 0 R] >> endobj 2837 0 obj << /Limits [(execute-command) (execute-command)] /Names [(execute-command) 1004 0 R] >> endobj 2838 0 obj << /Limits [(file-enable-sql-reader-syntax) (file-enable-sql-reader-syntax)] /Names [(file-enable-sql-reader-syntax) 517 0 R] >> endobj 2839 0 obj << /Limits [(find-database) (find-database)] /Names [(find-database) 189 0 R] >> endobj 2840 0 obj << /Limits [(foreignlibs) (foreignlibs)] /Names [(foreignlibs) 1970 0 R] >> endobj 2841 0 obj << /Limits [(glossary) (glossary)] /Names [(glossary) 2142 0 R] >> endobj 2842 0 obj << /Limits [(history) (history)] /Names [(history) 367 0 R] >> endobj 2843 0 obj << /Limits [(idp63600912) (idp63600912)] /Names [(idp63600912) 2523 0 R] >> endobj 2844 0 obj << /Limits [(idp63863936) (idp63863936)] /Names [(idp63863936) 2519 0 R] >> endobj 2845 0 obj << /Limits [(idp69340288) (idp69340288)] /Names [(idp69340288) 379 0 R] >> endobj 2846 0 obj << /Limits [(idp69343424) (idp69343424)] /Names [(idp69343424) 382 0 R] >> endobj 2847 0 obj << /Limits [(idp70511808) (idp70511808)] /Names [(idp70511808) 1979 0 R] >> endobj 2848 0 obj << /Limits [(idp70514368) (idp70514368)] /Names [(idp70514368) 1982 0 R] >> endobj 2849 0 obj << /Limits [(idp70515120) (idp70515120)] /Names [(idp70515120) 2522 0 R] >> endobj 2850 0 obj << /Limits [(idp70540352) (idp70540352)] /Names [(idp70540352) 415 0 R] >> endobj 2851 0 obj << /Limits [(idp71616352) (idp71616352)] /Names [(idp71616352) 373 0 R] >> endobj 2852 0 obj << /Limits [(idp71621792) (idp71621792)] /Names [(idp71621792) 376 0 R] >> endobj 2853 0 obj << /Limits [(idp72392656) (idp72392656)] /Names [(idp72392656) 385 0 R] >> endobj 2854 0 obj << /Limits [(idp72405728) (idp72405728)] /Names [(idp72405728) 391 0 R] >> endobj 2855 0 obj << /Limits [(idp72409232) (idp72409232)] /Names [(idp72409232) 394 0 R] >> endobj 2856 0 obj << /Limits [(idp72414720) (idp72414720)] /Names [(idp72414720) 2520 0 R] >> endobj 2857 0 obj << /Limits [(idp72419600) (idp72419600)] /Names [(idp72419600) 2521 0 R] >> endobj 2858 0 obj << /Limits [(idp72426608) (idp72426608)] /Names [(idp72426608) 397 0 R] >> endobj 2859 0 obj << /Limits [(idp72434016) (idp72434016)] /Names [(idp72434016) 400 0 R] >> endobj 2860 0 obj << /Limits [(idp72439024) (idp72439024)] /Names [(idp72439024) 403 0 R] >> endobj 2861 0 obj << /Limits [(idp72447024) (idp72447024)] /Names [(idp72447024) 406 0 R] >> endobj 2862 0 obj << /Limits [(idp73197328) (idp73197328)] /Names [(idp73197328) 1976 0 R] >> endobj 2863 0 obj << /Limits [(idp75840560) (idp75840560)] /Names [(idp75840560) 1985 0 R] >> endobj 2864 0 obj << /Limits [(idp75842944) (idp75842944)] /Names [(idp75842944) 1991 0 R] >> endobj 2865 0 obj << /Limits [(idp75845008) (idp75845008)] /Names [(idp75845008) 1994 0 R] >> endobj 2866 0 obj << /Limits [(idp75847584) (idp75847584)] /Names [(idp75847584) 1997 0 R] >> endobj 2867 0 obj << /Limits [(idp75848336) (idp75848336)] /Names [(idp75848336) 2524 0 R] >> endobj 2868 0 obj << /Limits [(idp78456112) (idp78456112)] /Names [(idp78456112) 2525 0 R] >> endobj 2869 0 obj << /Limits [(idp78474128) (idp78474128)] /Names [(idp78474128) 2042 0 R] >> endobj 2870 0 obj << /Limits [(idp78476512) (idp78476512)] /Names [(idp78476512) 2049 0 R] >> endobj 2871 0 obj << /Limits [(idp78482800) (idp78482800)] /Names [(idp78482800) 2052 0 R] >> endobj 2872 0 obj << /Limits [(idp78485968) (idp78485968)] /Names [(idp78485968) 2055 0 R] >> endobj 2873 0 obj << /Limits [(idp78486720) (idp78486720)] /Names [(idp78486720) 2526 0 R] >> endobj 2874 0 obj << /Limits [(idp78490592) (idp78490592)] /Names [(idp78490592) 2527 0 R] >> endobj 2875 0 obj << /Limits [(idp78504976) (idp78504976)] /Names [(idp78504976) 2058 0 R] >> endobj 2876 0 obj << /Limits [(idp78505552) (idp78505552)] /Names [(idp78505552) 2528 0 R] >> endobj 2877 0 obj << /Limits [(idp78515856) (idp78515856)] /Names [(idp78515856) 2529 0 R] >> endobj 2878 0 obj << /Limits [(idp78520032) (idp78520032)] /Names [(idp78520032) 2530 0 R] >> endobj 2879 0 obj << /Limits [(idp78534208) (idp78534208)] /Names [(idp78534208) 2064 0 R] >> endobj 2880 0 obj << /Limits [(idp78542832) (idp78542832)] /Names [(idp78542832) 2067 0 R] >> endobj 2881 0 obj << /Limits [(idp78546768) (idp78546768)] /Names [(idp78546768) 2070 0 R] >> endobj 2882 0 obj << /Limits [(idp78547520) (idp78547520)] /Names [(idp78547520) 2531 0 R] >> endobj 2883 0 obj << /Limits [(idp78550944) (idp78550944)] /Names [(idp78550944) 2532 0 R] >> endobj 2884 0 obj << /Limits [(idp78561232) (idp78561232)] /Names [(idp78561232) 2073 0 R] >> endobj 2885 0 obj << /Limits [(idp78561808) (idp78561808)] /Names [(idp78561808) 2533 0 R] >> endobj 2886 0 obj << /Limits [(idp78564880) (idp78564880)] /Names [(idp78564880) 2076 0 R] >> endobj 2887 0 obj << /Limits [(idp78569952) (idp78569952)] /Names [(idp78569952) 2082 0 R] >> endobj 2888 0 obj << /Limits [(idp78574000) (idp78574000)] /Names [(idp78574000) 2085 0 R] >> endobj 2889 0 obj << /Limits [(idp78577936) (idp78577936)] /Names [(idp78577936) 2088 0 R] >> endobj 2890 0 obj << /Limits [(idp78578688) (idp78578688)] /Names [(idp78578688) 2534 0 R] >> endobj 2891 0 obj << /Limits [(idp78581664) (idp78581664)] /Names [(idp78581664) 2535 0 R] >> endobj 2892 0 obj << /Limits [(idp78589664) (idp78589664)] /Names [(idp78589664) 2091 0 R] >> endobj 2893 0 obj << /Limits [(idp78592448) (idp78592448)] /Names [(idp78592448) 2097 0 R] >> endobj 2894 0 obj << /Limits [(idp78595936) (idp78595936)] /Names [(idp78595936) 2100 0 R] >> endobj 2895 0 obj << /Limits [(idp78599872) (idp78599872)] /Names [(idp78599872) 2103 0 R] >> endobj 2896 0 obj << /Limits [(idp78600624) (idp78600624)] /Names [(idp78600624) 2536 0 R] >> endobj 2897 0 obj << /Limits [(idp78602704) (idp78602704)] /Names [(idp78602704) 2537 0 R] >> endobj 2898 0 obj << /Limits [(idp78607104) (idp78607104)] /Names [(idp78607104) 2106 0 R] >> endobj 2899 0 obj << /Limits [(idp78607680) (idp78607680)] /Names [(idp78607680) 2538 0 R] >> endobj 2900 0 obj << /Limits [(idp78612656) (idp78612656)] /Names [(idp78612656) 2539 0 R] >> endobj 2901 0 obj << /Limits [(idp78618784) (idp78618784)] /Names [(idp78618784) 2540 0 R] >> endobj 2902 0 obj << /Limits [(idp78626512) (idp78626512)] /Names [(idp78626512) 2112 0 R] >> endobj 2903 0 obj << /Limits [(idp78630000) (idp78630000)] /Names [(idp78630000) 2115 0 R] >> endobj 2904 0 obj << /Limits [(idp78633936) (idp78633936)] /Names [(idp78633936) 2118 0 R] >> endobj 2905 0 obj << /Limits [(idp78634688) (idp78634688)] /Names [(idp78634688) 2541 0 R] >> endobj 2906 0 obj << /Limits [(idp78637216) (idp78637216)] /Names [(idp78637216) 2542 0 R] >> endobj 2907 0 obj << /Limits [(idp78648688) (idp78648688)] /Names [(idp78648688) 2121 0 R] >> endobj 2908 0 obj << /Limits [(idp78649264) (idp78649264)] /Names [(idp78649264) 2543 0 R] >> endobj 2909 0 obj << /Limits [(idp78654240) (idp78654240)] /Names [(idp78654240) 2544 0 R] >> endobj 2910 0 obj << /Limits [(idp78660368) (idp78660368)] /Names [(idp78660368) 2545 0 R] >> endobj 2911 0 obj << /Limits [(idp78667696) (idp78667696)] /Names [(idp78667696) 2127 0 R] >> endobj 2912 0 obj << /Limits [(idp78671600) (idp78671600)] /Names [(idp78671600) 2130 0 R] >> endobj 2913 0 obj << /Limits [(idp78677040) (idp78677040)] /Names [(idp78677040) 2133 0 R] >> endobj 2914 0 obj << /Limits [(idp78680208) (idp78680208)] /Names [(idp78680208) 2136 0 R] >> endobj 2915 0 obj << /Limits [(idp78680960) (idp78680960)] /Names [(idp78680960) 2546 0 R] >> endobj 2916 0 obj << /Limits [(idp78683936) (idp78683936)] /Names [(idp78683936) 2547 0 R] >> endobj 2917 0 obj << /Limits [(idp78692064) (idp78692064)] /Names [(idp78692064) 2139 0 R] >> endobj 2918 0 obj << /Limits [(idp78692640) (idp78692640)] /Names [(idp78692640) 2548 0 R] >> endobj 2919 0 obj << /Limits [(idp78865840) (idp78865840)] /Names [(idp78865840) 2549 0 R] >> endobj 2920 0 obj << /Limits [(in-transaction-p) (in-transaction-p)] /Names [(in-transaction-p) 1223 0 R] >> endobj 2921 0 obj << /Limits [(index-exists-p) (index-exists-p)] /Names [(index-exists-p) 750 0 R] >> endobj 2922 0 obj << /Limits [(indexes) (indexes)] /Names [(indexes) 1963 0 R] >> endobj 2923 0 obj << /Limits [(initialize-database-type) (initialize-database-type)] /Names [(initialize-database-type) 152 0 R] >> endobj 2924 0 obj << /Limits [(initialized-database-types) (initialized-database-types)] /Names [(initialized-database-types) 163 0 R] >> endobj 2925 0 obj << /Limits [(insert-records) (insert-records)] /Names [(insert-records) 985 0 R] >> endobj 2926 0 obj << /Limits [(installation) (installation)] /Names [(installation) 388 0 R] >> endobj 2927 0 obj << /Limits [(instance-refreshed) (instance-refreshed)] /Names [(instance-refreshed) 1403 0 R] >> endobj 2928 0 obj << /Limits [(introduction) (introduction)] /Names [(introduction) 361 0 R] >> endobj 2929 0 obj << /Limits [(list-attribute-types) (list-attribute-types)] /Names [(list-attribute-types) 781 0 R] >> endobj 2930 0 obj << /Limits [(list-attributes) (list-attributes)] /Names [(list-attributes) 792 0 R] >> endobj 2931 0 obj << /Limits [(list-classes) (list-classes)] /Names [(list-classes) 1380 0 R] >> endobj 2932 0 obj << /Limits [(list-databases) (list-databases)] /Names [(list-databases) 264 0 R] >> endobj 2933 0 obj << /Limits [(list-indexes) (list-indexes)] /Names [(list-indexes) 742 0 R] >> endobj 2934 0 obj << /Limits [(list-sequences) (list-sequences)] /Names [(list-sequences) 815 0 R] >> endobj 2935 0 obj << /Limits [(list-sql-streams) (list-sql-streams)] /Names [(list-sql-streams) 1550 0 R] >> endobj 2936 0 obj << /Limits [(list-tables) (list-tables)] /Names [(list-tables) 654 0 R] >> endobj 2937 0 obj << /Limits [(list-views) (list-views)] /Names [(list-views) 699 0 R] >> endobj 2938 0 obj << /Limits [(locally-disable-sql-reader-syntax) (locally-disable-sql-reader-syntax)] /Names [(locally-disable-sql-reader-syntax) 526 0 R] >> endobj 2939 0 obj << /Limits [(locally-enable-sql-reader-syntax) (locally-enable-sql-reader-syntax)] /Names [(locally-enable-sql-reader-syntax) 523 0 R] >> endobj 2940 0 obj << /Limits [(loop-tuples) (loop-tuples)] /Names [(loop-tuples) 1031 0 R] >> endobj 2941 0 obj << /Limits [(map-query) (map-query)] /Names [(map-query) 1029 0 R] >> endobj 2942 0 obj << /Limits [(mysql) (mysql)] /Names [(mysql) 2046 0 R] >> endobj 2943 0 obj << /Limits [(odbc) (odbc)] /Names [(odbc) 2061 0 R] >> endobj 2944 0 obj << /Limits [(oracle) (oracle)] /Names [(oracle) 2124 0 R] >> endobj 2945 0 obj << /Limits [(postgresql) (postgresql)] /Names [(postgresql) 1973 0 R] >> endobj 2946 0 obj << /Limits [(postgresql-socket) (postgresql-socket)] /Names [(postgresql-socket) 1988 0 R] >> endobj 2947 0 obj << /Limits [(preface) (preface)] /Names [(preface) 357 0 R] >> endobj 2948 0 obj << /Limits [(prerequisites) (prerequisites)] /Names [(prerequisites) 370 0 R] >> endobj 2949 0 obj << /Limits [(print-query) (print-query)] /Names [(print-query) 1047 0 R] >> endobj 2950 0 obj << /Limits [(probe-database) (probe-database)] /Names [(probe-database) 256 0 R] >> endobj 2951 0 obj << /Limits [(purpose) (purpose)] /Names [(purpose) 364 0 R] >> endobj 2952 0 obj << /Limits [(query) (query)] /Names [(query) 998 0 R] >> endobj 2953 0 obj << /Limits [(reconnect) (reconnect)] /Names [(reconnect) 186 0 R] >> endobj 2954 0 obj << /Limits [(ref-conditions) (ref-conditions)] /Names [(ref-conditions) 1936 0 R] >> endobj 2955 0 obj << /Limits [(ref-connect) (ref-connect)] /Names [(ref-connect) 433 0 R] >> endobj 2956 0 obj << /Limits [(ref-fddl) (ref-fddl)] /Names [(ref-fddl) 1136 0 R] >> endobj 2957 0 obj << /Limits [(ref-fdml) (ref-fdml)] /Names [(ref-fdml) 1185 0 R] >> endobj 2958 0 obj << /Limits [(ref-ooddl) (ref-ooddl)] /Names [(ref-ooddl) 1448 0 R] >> endobj 2959 0 obj << /Limits [(ref-oodml) (ref-oodml)] /Names [(ref-oodml) 1894 0 R] >> endobj 2960 0 obj << /Limits [(ref-recording) (ref-recording)] /Names [(ref-recording) 1919 0 R] >> endobj 2961 0 obj << /Limits [(ref-syntax) (ref-syntax)] /Names [(ref-syntax) 482 0 R] >> endobj 2962 0 obj << /Limits [(ref-transaction) (ref-transaction)] /Names [(ref-transaction) 1212 0 R] >> endobj 2963 0 obj << /Limits [(restore-sql-reader-syntax-state) (restore-sql-reader-syntax-state)] /Names [(restore-sql-reader-syntax-state) 512 0 R] >> endobj 2964 0 obj << /Limits [(rollback) (rollback)] /Names [(rollback) 1109 0 R] >> endobj 2965 0 obj << /Limits [(select) (select)] /Names [(select) 1025 0 R] >> endobj 2966 0 obj << /Limits [(sequence-exists-p) (sequence-exists-p)] /Names [(sequence-exists-p) 833 0 R] >> endobj 2967 0 obj << /Limits [(sequence-last) (sequence-last)] /Names [(sequence-last) 817 0 R] >> endobj 2968 0 obj << /Limits [(sequence-next) (sequence-next)] /Names [(sequence-next) 836 0 R] >> endobj 2969 0 obj << /Limits [(set-autocommit) (set-autocommit)] /Names [(set-autocommit) 1231 0 R] >> endobj 2970 0 obj << /Limits [(set-sequence-position) (set-sequence-position)] /Names [(set-sequence-position) 853 0 R] >> endobj 2971 0 obj << /Limits [(sql) (sql)] /Names [(sql) 602 0 R] >> endobj 2972 0 obj << /Limits [(sql-condition) (sql-condition)] /Names [(sql-condition) 1602 0 R] >> endobj 2973 0 obj << /Limits [(sql-connection-error) (sql-connection-error)] /Names [(sql-connection-error) 1669 0 R] >> endobj 2974 0 obj << /Limits [(sql-database-data-error) (sql-database-data-error)] /Names [(sql-database-data-error) 1728 0 R] >> endobj 2975 0 obj << /Limits [(sql-database-error) (sql-database-error)] /Names [(sql-database-error) 1661 0 R] >> endobj 2976 0 obj << /Limits [(sql-database-warning) (sql-database-warning)] /Names [(sql-database-warning) 1622 0 R] >> endobj 2977 0 obj << /Limits [(sql-error) (sql-error)] /Names [(sql-error) 1608 0 R] >> endobj 2978 0 obj << /Limits [(sql-expression) (sql-expression)] /Names [(sql-expression) 605 0 R] >> endobj 2979 0 obj << /Limits [(sql-fatal-error) (sql-fatal-error)] /Names [(sql-fatal-error) 1737 0 R] >> endobj 2980 0 obj << /Limits [(sql-operation) (sql-operation)] /Names [(sql-operation) 607 0 R] >> endobj 2981 0 obj << /Limits [(sql-operator) (sql-operator)] /Names [(sql-operator) 632 0 R] >> endobj 2982 0 obj << /Limits [(sql-recording-p) (sql-recording-p)] /Names [(sql-recording-p) 1522 0 R] >> endobj 2983 0 obj << /Limits [(sql-stream) (sql-stream)] /Names [(sql-stream) 1541 0 R] >> endobj 2984 0 obj << /Limits [(sql-temporary-error) (sql-temporary-error)] /Names [(sql-temporary-error) 1731 0 R] >> endobj 2985 0 obj << /Limits [(sql-timeout-error) (sql-timeout-error)] /Names [(sql-timeout-error) 1734 0 R] >> endobj 2986 0 obj << /Limits [(sql-user-error) (sql-user-error)] /Names [(sql-user-error) 1636 0 R] >> endobj 2987 0 obj << /Limits [(sql-warning) (sql-warning)] /Names [(sql-warning) 1615 0 R] >> endobj 2988 0 obj << /Limits [(sqlite) (sqlite)] /Names [(sqlite) 2094 0 R] >> endobj 2989 0 obj << /Limits [(sqlite3) (sqlite3)] /Names [(sqlite3) 2109 0 R] >> endobj 2990 0 obj << /Limits [(standard-db-object) (standard-db-object)] /Names [(standard-db-object) 1359 0 R] >> endobj 2991 0 obj << /Limits [(start-sql-recording) (start-sql-recording)] /Names [(start-sql-recording) 1519 0 R] >> endobj 2992 0 obj << /Limits [(start-transaction) (start-transaction)] /Names [(start-transaction) 1215 0 R] >> endobj 2993 0 obj << /Limits [(status) (status)] /Names [(status) 191 0 R] >> endobj 2994 0 obj << /Limits [(stop-sql-recording) (stop-sql-recording)] /Names [(stop-sql-recording) 1529 0 R] >> endobj 2995 0 obj << /Limits [(table-exists-p) (table-exists-p)] /Names [(table-exists-p) 662 0 R] >> endobj 2996 0 obj << /Limits [(truncate-database) (truncate-database)] /Names [(truncate-database) 950 0 R] >> endobj 2997 0 obj << /Limits [(update-instance-from-records) (update-instance-from-records)] /Names [(update-instance-from-records) 1455 0 R] >> endobj 2998 0 obj << /Limits [(update-objects-joins) (update-objects-joins)] /Names [(update-objects-joins) 1486 0 R] >> endobj 2999 0 obj << /Limits [(update-record-from-slot) (update-record-from-slot)] /Names [(update-record-from-slot) 1421 0 R] >> endobj 3000 0 obj << /Limits [(update-record-from-slots) (update-record-from-slots)] /Names [(update-record-from-slots) 1424 0 R] >> endobj 3001 0 obj << /Limits [(update-records) (update-records)] /Names [(update-records) 977 0 R] >> endobj 3002 0 obj << /Limits [(update-records-from-instance) (update-records-from-instance)] /Names [(update-records-from-instance) 1416 0 R] >> endobj 3003 0 obj << /Limits [(update-slot-from-record) (update-slot-from-record)] /Names [(update-slot-from-record) 1452 0 R] >> endobj 3004 0 obj << /Limits [(view-exists-p) (view-exists-p)] /Names [(view-exists-p) 707 0 R] >> endobj 3005 0 obj << /Limits [(with-database) (with-database)] /Names [(with-database) 286 0 R] >> endobj 3006 0 obj << /Limits [(with-default-database) (with-default-database)] /Names [(with-default-database) 340 0 R] >> endobj 3007 0 obj << /Limits [(with-transaction) (with-transaction)] /Names [(with-transaction) 1264 0 R] >> endobj 3008 0 obj << /Limits [(add-sql-stream) (with-transaction)] /Kids [2784 0 R 2785 0 R 2786 0 R 2787 0 R 2788 0 R 2789 0 R 2790 0 R 2791 0 R 2792 0 R 2793 0 R 2794 0 R 2795 0 R 2796 0 R 2797 0 R 2798 0 R 2799 0 R 2800 0 R 2801 0 R 2802 0 R 2803 0 R 2804 0 R 2805 0 R 2806 0 R 2807 0 R 2808 0 R 2809 0 R 2810 0 R 2811 0 R 2812 0 R 2813 0 R 2814 0 R 2815 0 R 2816 0 R 2817 0 R 2818 0 R 2819 0 R 2820 0 R 2821 0 R 2822 0 R 2823 0 R 2824 0 R 2825 0 R 2826 0 R 2827 0 R 2828 0 R 2829 0 R 2830 0 R 2831 0 R 2832 0 R 2833 0 R 2834 0 R 2835 0 R 2836 0 R 2837 0 R 2838 0 R 2839 0 R 2840 0 R 2841 0 R 2842 0 R 2843 0 R 2844 0 R 2845 0 R 2846 0 R 2847 0 R 2848 0 R 2849 0 R 2850 0 R 2851 0 R 2852 0 R 2853 0 R 2854 0 R 2855 0 R 2856 0 R 2857 0 R 2858 0 R 2859 0 R 2860 0 R 2861 0 R 2862 0 R 2863 0 R 2864 0 R 2865 0 R 2866 0 R 2867 0 R 2868 0 R 2869 0 R 2870 0 R 2871 0 R 2872 0 R 2873 0 R 2874 0 R 2875 0 R 2876 0 R 2877 0 R 2878 0 R 2879 0 R 2880 0 R 2881 0 R 2882 0 R 2883 0 R 2884 0 R 2885 0 R 2886 0 R 2887 0 R 2888 0 R 2889 0 R 2890 0 R 2891 0 R 2892 0 R 2893 0 R 2894 0 R 2895 0 R 2896 0 R 2897 0 R 2898 0 R 2899 0 R 2900 0 R 2901 0 R 2902 0 R 2903 0 R 2904 0 R 2905 0 R 2906 0 R 2907 0 R 2908 0 R 2909 0 R 2910 0 R 2911 0 R 2912 0 R 2913 0 R 2914 0 R 2915 0 R 2916 0 R 2917 0 R 2918 0 R 2919 0 R 2920 0 R 2921 0 R 2922 0 R 2923 0 R 2924 0 R 2925 0 R 2926 0 R 2927 0 R 2928 0 R 2929 0 R 2930 0 R 2931 0 R 2932 0 R 2933 0 R 2934 0 R 2935 0 R 2936 0 R 2937 0 R 2938 0 R 2939 0 R 2940 0 R 2941 0 R 2942 0 R 2943 0 R 2944 0 R 2945 0 R 2946 0 R 2947 0 R 2948 0 R 2949 0 R 2950 0 R 2951 0 R 2952 0 R 2953 0 R 2954 0 R 2955 0 R 2956 0 R 2957 0 R 2958 0 R 2959 0 R 2960 0 R 2961 0 R 2962 0 R 2963 0 R 2964 0 R 2965 0 R 2966 0 R 2967 0 R 2968 0 R 2969 0 R 2970 0 R 2971 0 R 2972 0 R 2973 0 R 2974 0 R 2975 0 R 2976 0 R 2977 0 R 2978 0 R 2979 0 R 2980 0 R 2981 0 R 2982 0 R 2983 0 R 2984 0 R 2985 0 R 2986 0 R 2987 0 R 2988 0 R 2989 0 R 2990 0 R 2991 0 R 2992 0 R 2993 0 R 2994 0 R 2995 0 R 2996 0 R 2997 0 R 2998 0 R 2999 0 R 3000 0 R 3001 0 R 3002 0 R 3003 0 R 3004 0 R 3005 0 R 3006 0 R 3007 0 R] >> endobj 1 0 obj << /Type /Pages /Count 252 /Kids [8 0 R 14 0 R 356 0 R 1116 0 R 1876 0 R 2041 0 R 17 0 R 2147 0 R 20 0 R 23 0 R 26 0 R 29 0 R 48 0 R 51 0 R 1319 0 R 54 0 R 1325 0 R 57 0 R 60 0 R 63 0 R 292 0 R 66 0 R 75 0 R 114 0 R 69 0 R 121 0 R 151 0 R 157 0 R 72 0 R 83 0 R 182 0 R 91 0 R 195 0 R 94 0 R 203 0 R 97 0 R 100 0 R 214 0 R 105 0 R 135 0 R 128 0 R 145 0 R 223 0 R 148 0 R 162 0 R 169 0 R 172 0 R 179 0 R 235 0 R 260 0 R 244 0 R 268 0 R 247 0 R 275 0 R 250 0 R 282 0 R 345 0 R 285 0 R 353 0 R 611 0 R 511 0 R 522 0 R 532 0 R 542 0 R 551 0 R 560 0 R 490 0 R 571 0 R 493 0 R 496 0 R 585 0 R 592 0 R 1635 0 R 595 0 R 1644 0 R 598 0 R 1652 0 R 601 0 R 1867 0 R 904 0 R 637 0 R 658 0 R 640 0 R 666 0 R 646 0 R 672 0 R 649 0 R 679 0 R 682 0 R 703 0 R 685 0 R 711 0 R 691 0 R 717 0 R 694 0 R 724 0 R 727 0 R 746 0 R 730 0 R 754 0 R 733 0 R 761 0 R 736 0 R 768 0 R 771 0 R 791 0 R 774 0 R 777 0 R 785 0 R 798 0 R 846 0 R 801 0 R 804 0 R 857 0 R 829 0 R 866 0 R 810 0 R 871 0 R 877 0 R 821 0 R 824 0 R 887 0 R 840 0 R 896 0 R 2167 0 R 955 0 R 1021 0 R 963 0 R 2173 0 R 969 0 R 2179 0 R 976 0 R 2185 0 R 984 0 R 2191 0 R 991 0 R 2197 0 R 997 0 R 2206 0 R 1003 0 R 1060 0 R 2217 0 R 1069 0 R 2225 0 R 1009 0 R 1012 0 R 1396 0 R 1015 0 R 2235 0 R 1078 0 R 2246 0 R 1087 0 R 1018 0 R 2254 0 R 1096 0 R 1099 0 R 1246 0 R 2265 0 R 1269 0 R 2271 0 R 1278 0 R 2277 0 R 1288 0 R 2283 0 R 1236 0 R 2290 0 R 1298 0 R 2298 0 R 1108 0 R 2305 0 R 1243 0 R 2315 0 R 1304 0 R 1364 0 R 1313 0 R 1316 0 R 2377 0 R 1349 0 R 2392 0 R 1330 0 R 2398 0 R 1337 0 R 1340 0 R 1343 0 R 1346 0 R 1355 0 R 2404 0 R 2321 0 R 1385 0 R 1447 0 R 2416 0 R 1420 0 R 1390 0 R 1491 0 R 2427 0 R 1407 0 R 2435 0 R 1412 0 R 2443 0 R 1428 0 R 2453 0 R 1435 0 R 2463 0 R 1441 0 R 2473 0 R 1498 0 R 2483 0 R 1504 0 R 2493 0 R 1510 0 R 1533 0 R 2327 0 R 1555 0 R 2333 0 R 1518 0 R 2339 0 R 1526 0 R 2347 0 R 1565 0 R 2354 0 R 1572 0 R 2360 0 R 1580 0 R 2366 0 R 1591 0 R 1707 0 R 1598 0 R 1601 0 R 1607 0 R 1614 0 R 1621 0 R 1629 0 R 1660 0 R 1668 0 R 1677 0 R 1684 0 R 1691 0 R 1699 0 R 1844 0 R 1742 0 R 1851 0 R 1864 0 R 1873 0 R 2002 0 R 2503 0 R 2005 0 R 2008 0 R 2011 0 R 2016 0 R 2021 0 R 2027 0 R 2374 0 R ] >> endobj 2 0 obj << /Type /Catalog /Pages 1 0 R /Lang (en) /Metadata 7 0 R /PageLabels 9 0 R /Outlines 2550 0 R /PageMode /UseOutlines /Names 3009 0 R >> endobj 3 0 obj << /Font << /F10 2777 0 R /F5 2778 0 R /F4 2779 0 R /F3 2780 0 R /F9 2781 0 R /F6 2782 0 R /F7 2783 0 R >> /ProcSet [/PDF /ImageB /ImageC /Text] /ColorSpace << /DefaultRGB 6 0 R >> >> endobj 9 0 obj << /Nums [0 << /P (i) >> 1 << /P (ii) >> 2 << /P (iii) >> 3 << /P (iv) >> 4 << /P (v) >> 5 << /P (vi) >> 6 << /P (vii) >> 7 << /P (1) >> 8 << /P (2) >> 9 << /P (3) >> 10 << /P (4) >> 11 << /P (5) >> 12 << /P (6) >> 13 << /P (7) >> 14 << /P (8) >> 15 << /P (9) >> 16 << /P (10) >> 17 << /P (11) >> 18 << /P (12) >> 19 << /P (13) >> 20 << /P (14) >> 21 << /P (15) >> 22 << /P (16) >> 23 << /P (17) >> 24 << /P (18) >> 25 << /P (19) >> 26 << /P (20) >> 27 << /P (21) >> 28 << /P (22) >> 29 << /P (23) >> 30 << /P (24) >> 31 << /P (25) >> 32 << /P (26) >> 33 << /P (27) >> 34 << /P (28) >> 35 << /P (29) >> 36 << /P (30) >> 37 << /P (31) >> 38 << /P (32) >> 39 << /P (33) >> 40 << /P (34) >> 41 << /P (35) >> 42 << /P (36) >> 43 << /P (37) >> 44 << /P (38) >> 45 << /P (39) >> 46 << /P (40) >> 47 << /P (41) >> 48 << /P (42) >> 49 << /P (43) >> 50 << /P (44) >> 51 << /P (45) >> 52 << /P (46) >> 53 << /P (47) >> 54 << /P (48) >> 55 << /P (49) >> 56 << /P (50) >> 57 << /P (51) >> 58 << /P (52) >> 59 << /P (53) >> 60 << /P (54) >> 61 << /P (55) >> 62 << /P (56) >> 63 << /P (57) >> 64 << /P (58) >> 65 << /P (59) >> 66 << /P (60) >> 67 << /P (61) >> 68 << /P (62) >> 69 << /P (63) >> 70 << /P (64) >> 71 << /P (65) >> 72 << /P (66) >> 73 << /P (67) >> 74 << /P (68) >> 75 << /P (69) >> 76 << /P (70) >> 77 << /P (71) >> 78 << /P (72) >> 79 << /P (73) >> 80 << /P (74) >> 81 << /P (75) >> 82 << /P (76) >> 83 << /P (77) >> 84 << /P (78) >> 85 << /P (79) >> 86 << /P (80) >> 87 << /P (81) >> 88 << /P (82) >> 89 << /P (83) >> 90 << /P (84) >> 91 << /P (85) >> 92 << /P (86) >> 93 << /P (87) >> 94 << /P (88) >> 95 << /P (89) >> 96 << /P (90) >> 97 << /P (91) >> 98 << /P (92) >> 99 << /P (93) >> 100 << /P (94) >> 101 << /P (95) >> 102 << /P (96) >> 103 << /P (97) >> 104 << /P (98) >> 105 << /P (99) >> 106 << /P (100) >> 107 << /P (101) >> 108 << /P (102) >> 109 << /P (103) >> 110 << /P (104) >> 111 << /P (105) >> 112 << /P (106) >> 113 << /P (107) >> 114 << /P (108) >> 115 << /P (109) >> 116 << /P (110) >> 117 << /P (111) >> 118 << /P (112) >> 119 << /P (113) >> 120 << /P (114) >> 121 << /P (115) >> 122 << /P (116) >> 123 << /P (117) >> 124 << /P (118) >> 125 << /P (119) >> 126 << /P (120) >> 127 << /P (121) >> 128 << /P (122) >> 129 << /P (123) >> 130 << /P (124) >> 131 << /P (125) >> 132 << /P (126) >> 133 << /P (127) >> 134 << /P (128) >> 135 << /P (129) >> 136 << /P (130) >> 137 << /P (131) >> 138 << /P (132) >> 139 << /P (133) >> 140 << /P (134) >> 141 << /P (135) >> 142 << /P (136) >> 143 << /P (137) >> 144 << /P (138) >> 145 << /P (139) >> 146 << /P (140) >> 147 << /P (141) >> 148 << /P (142) >> 149 << /P (143) >> 150 << /P (144) >> 151 << /P (145) >> 152 << /P (146) >> 153 << /P (147) >> 154 << /P (148) >> 155 << /P (149) >> 156 << /P (150) >> 157 << /P (151) >> 158 << /P (152) >> 159 << /P (153) >> 160 << /P (154) >> 161 << /P (155) >> 162 << /P (156) >> 163 << /P (157) >> 164 << /P (158) >> 165 << /P (159) >> 166 << /P (160) >> 167 << /P (161) >> 168 << /P (162) >> 169 << /P (163) >> 170 << /P (164) >> 171 << /P (165) >> 172 << /P (166) >> 173 << /P (167) >> 174 << /P (168) >> 175 << /P (169) >> 176 << /P (170) >> 177 << /P (171) >> 178 << /P (172) >> 179 << /P (173) >> 180 << /P (174) >> 181 << /P (175) >> 182 << /P (176) >> 183 << /P (177) >> 184 << /P (178) >> 185 << /P (179) >> 186 << /P (180) >> 187 << /P (181) >> 188 << /P (182) >> 189 << /P (183) >> 190 << /P (184) >> 191 << /P (185) >> 192 << /P (186) >> 193 << /P (187) >> 194 << /P (188) >> 195 << /P (189) >> 196 << /P (190) >> 197 << /P (191) >> 198 << /P (192) >> 199 << /P (193) >> 200 << /P (194) >> 201 << /P (195) >> 202 << /P (196) >> 203 << /P (197) >> 204 << /P (198) >> 205 << /P (199) >> 206 << /P (200) >> 207 << /P (201) >> 208 << /P (202) >> 209 << /P (203) >> 210 << /P (204) >> 211 << /P (205) >> 212 << /P (206) >> 213 << /P (207) >> 214 << /P (208) >> 215 << /P (209) >> 216 << /P (210) >> 217 << /P (211) >> 218 << /P (212) >> 219 << /P (213) >> 220 << /P (214) >> 221 << /P (215) >> 222 << /P (216) >> 223 << /P (217) >> 224 << /P (218) >> 225 << /P (219) >> 226 << /P (220) >> 227 << /P (221) >> 228 << /P (222) >> 229 << /P (223) >> 230 << /P (224) >> 231 << /P (225) >> 232 << /P (226) >> 233 << /P (227) >> 234 << /P (228) >> 235 << /P (229) >> 236 << /P (230) >> 237 << /P (231) >> 238 << /P (232) >> 239 << /P (233) >> 240 << /P (234) >> 241 << /P (235) >> 242 << /P (236) >> 243 << /P (237) >> 244 << /P (238) >> 245 << /P (239) >> 246 << /P (240) >> 247 << /P (241) >> 248 << /P (242) >> 249 << /P (243) >> 250 << /P (244) >> 251 << /P (245) >> ] >> endobj 2550 0 obj << /First 2551 0 R /Last 2776 0 R >> endobj 3009 0 obj << /Dests 3008 0 R >> endobj xref 0 3010 0000000000 65535 f 0000727844 00000 n 0000730023 00000 n 0000730192 00000 n 0000000015 00000 n 0000000277 00000 n 0000002816 00000 n 0000002849 00000 n 0000004311 00000 n 0000730414 00000 n 0000003947 00000 n 0000004503 00000 n 0000004524 00000 n 0000004545 00000 n 0000005312 00000 n 0000004565 00000 n 0000005505 00000 n 0000006150 00000 n 0000005525 00000 n 0000006343 00000 n 0000007952 00000 n 0000006363 00000 n 0000008145 00000 n 0000010658 00000 n 0000008166 00000 n 0000010851 00000 n 0000011407 00000 n 0000010872 00000 n 0000011600 00000 n 0000016155 00000 n 0000011620 00000 n 0000011726 00000 n 0000016058 00000 n 0000011864 00000 n 0000012004 00000 n 0000012141 00000 n 0000012246 00000 n 0000012382 00000 n 0000012520 00000 n 0000012654 00000 n 0000012754 00000 n 0000012892 00000 n 0000013032 00000 n 0000013169 00000 n 0000013257 00000 n 0000013388 00000 n 0000013522 00000 n 0000016365 00000 n 0000017948 00000 n 0000016386 00000 n 0000018141 00000 n 0000021088 00000 n 0000018162 00000 n 0000021281 00000 n 0000023384 00000 n 0000021302 00000 n 0000023577 00000 n 0000025481 00000 n 0000023598 00000 n 0000025674 00000 n 0000027585 00000 n 0000025695 00000 n 0000027778 00000 n 0000029152 00000 n 0000027799 00000 n 0000029345 00000 n 0000030066 00000 n 0000029366 00000 n 0000030259 00000 n 0000031948 00000 n 0000030279 00000 n 0000032141 00000 n 0000034626 00000 n 0000032162 00000 n 0000034819 00000 n 0000036384 00000 n 0000034840 00000 n 0000034918 00000 n 0000036343 00000 n 0000035054 00000 n 0000035192 00000 n 0000035328 00000 n 0000036594 00000 n 0000038695 00000 n 0000059277 00000 n 0000036614 00000 n 0000038661 00000 n 0000036747 00000 n 0000036825 00000 n 0000036958 00000 n 0000038905 00000 n 0000040083 00000 n 0000038926 00000 n 0000040276 00000 n 0000042004 00000 n 0000040297 00000 n 0000042197 00000 n 0000043651 00000 n 0000042218 00000 n 0000043844 00000 n 0000044897 00000 n 0000043865 00000 n 0000044868 00000 n 0000044002 00000 n 0000045110 00000 n 0000047854 00000 n 0000045131 00000 n 0000045210 00000 n 0000047809 00000 n 0000045348 00000 n 0000048089 00000 n 0000045486 00000 n 0000045627 00000 n 0000048067 00000 n 0000049596 00000 n 0000048169 00000 n 0000049559 00000 n 0000048306 00000 n 0000048386 00000 n 0000048524 00000 n 0000049809 00000 n 0000051303 00000 n 0000049830 00000 n 0000051258 00000 n 0000049967 00000 n 0000050105 00000 n 0000050243 00000 n 0000051516 00000 n 0000053249 00000 n 0000051537 00000 n 0000053204 00000 n 0000051674 00000 n 0000051811 00000 n 0000051949 00000 n 0000053462 00000 n 0000054923 00000 n 0000053484 00000 n 0000053563 00000 n 0000054870 00000 n 0000053702 00000 n 0000053841 00000 n 0000053978 00000 n 0000054058 00000 n 0000054196 00000 n 0000055136 00000 n 0000057204 00000 n 0000055157 00000 n 0000057399 00000 n 0000059060 00000 n 0000057421 00000 n 0000059255 00000 n 0000060832 00000 n 0000059356 00000 n 0000059436 00000 n 0000060803 00000 n 0000059574 00000 n 0000061045 00000 n 0000062439 00000 n 0000061067 00000 n 0000062410 00000 n 0000061205 00000 n 0000062652 00000 n 0000063824 00000 n 0000062674 00000 n 0000062754 00000 n 0000063787 00000 n 0000062892 00000 n 0000063029 00000 n 0000064037 00000 n 0000066042 00000 n 0000064058 00000 n 0000066237 00000 n 0000067252 00000 n 0000066259 00000 n 0000067207 00000 n 0000066396 00000 n 0000066534 00000 n 0000066672 00000 n 0000067465 00000 n 0000068706 00000 n 0000067486 00000 n 0000068901 00000 n 0000070858 00000 n 0000068923 00000 n 0000070789 00000 n 0000069061 00000 n 0000069199 00000 n 0000069279 00000 n 0000069417 00000 n 0000069554 00000 n 0000069634 00000 n 0000069772 00000 n 0000069852 00000 n 0000069990 00000 n 0000071071 00000 n 0000072207 00000 n 0000071092 00000 n 0000072154 00000 n 0000071230 00000 n 0000071367 00000 n 0000071505 00000 n 0000071643 00000 n 0000072420 00000 n 0000074127 00000 n 0000072441 00000 n 0000072520 00000 n 0000074058 00000 n 0000072658 00000 n 0000072795 00000 n 0000072933 00000 n 0000073071 00000 n 0000073209 00000 n 0000073347 00000 n 0000074340 00000 n 0000076330 00000 n 0000074361 00000 n 0000076269 00000 n 0000074498 00000 n 0000074636 00000 n 0000074774 00000 n 0000074912 00000 n 0000075050 00000 n 0000076543 00000 n 0000078751 00000 n 0000076565 00000 n 0000078674 00000 n 0000076703 00000 n 0000076782 00000 n 0000076920 00000 n 0000077058 00000 n 0000077196 00000 n 0000077333 00000 n 0000077471 00000 n 0000077609 00000 n 0000078964 00000 n 0000080275 00000 n 0000078985 00000 n 0000080214 00000 n 0000079123 00000 n 0000079260 00000 n 0000079398 00000 n 0000079535 00000 n 0000079673 00000 n 0000080488 00000 n 0000081169 00000 n 0000080509 00000 n 0000081364 00000 n 0000082051 00000 n 0000081385 00000 n 0000082246 00000 n 0000084034 00000 n 0000084269 00000 n 0000082267 00000 n 0000083989 00000 n 0000086499 00000 n 0000082405 00000 n 0000088617 00000 n 0000082543 00000 n 0000082681 00000 n 0000084247 00000 n 0000086264 00000 n 0000084349 00000 n 0000086219 00000 n 0000084486 00000 n 0000084622 00000 n 0000084702 00000 n 0000084838 00000 n 0000086477 00000 n 0000088382 00000 n 0000086579 00000 n 0000088337 00000 n 0000086716 00000 n 0000086852 00000 n 0000086988 00000 n 0000088595 00000 n 0000090435 00000 n 0000088697 00000 n 0000090390 00000 n 0000088835 00000 n 0000088973 00000 n 0000089111 00000 n 0000090648 00000 n 0000092336 00000 n 0000090670 00000 n 0000092531 00000 n 0000094211 00000 n 0000092553 00000 n 0000092633 00000 n 0000094174 00000 n 0000092769 00000 n 0000092906 00000 n 0000094424 00000 n 0000109349 00000 n 0000094446 00000 n 0000094525 00000 n 0000108960 00000 n 0000094664 00000 n 0000094806 00000 n 0000094944 00000 n 0000095085 00000 n 0000095224 00000 n 0000095366 00000 n 0000095505 00000 n 0000095647 00000 n 0000095785 00000 n 0000095926 00000 n 0000096065 00000 n 0000096207 00000 n 0000096345 00000 n 0000096484 00000 n 0000096623 00000 n 0000096765 00000 n 0000096903 00000 n 0000097045 00000 n 0000097183 00000 n 0000097325 00000 n 0000097405 00000 n 0000097544 00000 n 0000097686 00000 n 0000097825 00000 n 0000097967 00000 n 0000098105 00000 n 0000098247 00000 n 0000098386 00000 n 0000098528 00000 n 0000098667 00000 n 0000098809 00000 n 0000098947 00000 n 0000099089 00000 n 0000099228 00000 n 0000099370 00000 n 0000099509 00000 n 0000099651 00000 n 0000099790 00000 n 0000099932 00000 n 0000100071 00000 n 0000100213 00000 n 0000100352 00000 n 0000100494 00000 n 0000100633 00000 n 0000100775 00000 n 0000100855 00000 n 0000100994 00000 n 0000101132 00000 n 0000109562 00000 n 0000110703 00000 n 0000109584 00000 n 0000110650 00000 n 0000109721 00000 n 0000109859 00000 n 0000109997 00000 n 0000110135 00000 n 0000110916 00000 n 0000111383 00000 n 0000110937 00000 n 0000111578 00000 n 0000144293 00000 n 0000111599 00000 n 0000111678 00000 n 0000143456 00000 n 0000111817 00000 n 0000553828 00000 n 0000111959 00000 n 0000112099 00000 n 0000553909 00000 n 0000112241 00000 n 0000112380 00000 n 0000553992 00000 n 0000112522 00000 n 0000112660 00000 n 0000554074 00000 n 0000112802 00000 n 0000112941 00000 n 0000554157 00000 n 0000113083 00000 n 0000113222 00000 n 0000554240 00000 n 0000113364 00000 n 0000113503 00000 n 0000554323 00000 n 0000113645 00000 n 0000113784 00000 n 0000113926 00000 n 0000114005 00000 n 0000114144 00000 n 0000114286 00000 n 0000114367 00000 n 0000114507 00000 n 0000114649 00000 n 0000114730 00000 n 0000114868 00000 n 0000115010 00000 n 0000115091 00000 n 0000115231 00000 n 0000115373 00000 n 0000115454 00000 n 0000115594 00000 n 0000115736 00000 n 0000115817 00000 n 0000115957 00000 n 0000116099 00000 n 0000116180 00000 n 0000116320 00000 n 0000116462 00000 n 0000116543 00000 n 0000116683 00000 n 0000116825 00000 n 0000116906 00000 n 0000117046 00000 n 0000117188 00000 n 0000117267 00000 n 0000117407 00000 n 0000117549 00000 n 0000117630 00000 n 0000117769 00000 n 0000117911 00000 n 0000117992 00000 n 0000118132 00000 n 0000355860 00000 n 0000118272 00000 n 0000118412 00000 n 0000358232 00000 n 0000118554 00000 n 0000118694 00000 n 0000118834 00000 n 0000118915 00000 n 0000119055 00000 n 0000119197 00000 n 0000119276 00000 n 0000119416 00000 n 0000119558 00000 n 0000119639 00000 n 0000119778 00000 n 0000119920 00000 n 0000120000 00000 n 0000120140 00000 n 0000120282 00000 n 0000120421 00000 n 0000120561 00000 n 0000120699 00000 n 0000120840 00000 n 0000120979 00000 n 0000121121 00000 n 0000121260 00000 n 0000121400 00000 n 0000121538 00000 n 0000121679 00000 n 0000121818 00000 n 0000121960 00000 n 0000122098 00000 n 0000122239 00000 n 0000122378 00000 n 0000122520 00000 n 0000122658 00000 n 0000122800 00000 n 0000122938 00000 n 0000123080 00000 n 0000123219 00000 n 0000123361 00000 n 0000123500 00000 n 0000123640 00000 n 0000123778 00000 n 0000123920 00000 n 0000124059 00000 n 0000124201 00000 n 0000124340 00000 n 0000124482 00000 n 0000124620 00000 n 0000124762 00000 n 0000124901 00000 n 0000125043 00000 n 0000125182 00000 n 0000125324 00000 n 0000125463 00000 n 0000125605 00000 n 0000125744 00000 n 0000125886 00000 n 0000126025 00000 n 0000126167 00000 n 0000126306 00000 n 0000126448 00000 n 0000126587 00000 n 0000173590 00000 n 0000126729 00000 n 0000126868 00000 n 0000149245 00000 n 0000127009 00000 n 0000127146 00000 n 0000127286 00000 n 0000144506 00000 n 0000145118 00000 n 0000144529 00000 n 0000145313 00000 n 0000145852 00000 n 0000145334 00000 n 0000146047 00000 n 0000149010 00000 n 0000146068 00000 n 0000148925 00000 n 0000153386 00000 n 0000146210 00000 n 0000146352 00000 n 0000146490 00000 n 0000146593 00000 n 0000146733 00000 n 0000146873 00000 n 0000146978 00000 n 0000147116 00000 n 0000147254 00000 n 0000147390 00000 n 0000149223 00000 n 0000151690 00000 n 0000162629 00000 n 0000149325 00000 n 0000151629 00000 n 0000149463 00000 n 0000149601 00000 n 0000149739 00000 n 0000149819 00000 n 0000149959 00000 n 0000150095 00000 n 0000151903 00000 n 0000153152 00000 n 0000155724 00000 n 0000151925 00000 n 0000153099 00000 n 0000160140 00000 n 0000152059 00000 n 0000152193 00000 n 0000152327 00000 n 0000152461 00000 n 0000153365 00000 n 0000155489 00000 n 0000153466 00000 n 0000155420 00000 n 0000153604 00000 n 0000153742 00000 n 0000153880 00000 n 0000154018 00000 n 0000154156 00000 n 0000154294 00000 n 0000155702 00000 n 0000158245 00000 n 0000155804 00000 n 0000158184 00000 n 0000155946 00000 n 0000156084 00000 n 0000156222 00000 n 0000156360 00000 n 0000156500 00000 n 0000158458 00000 n 0000159906 00000 n 0000158480 00000 n 0000159845 00000 n 0000158618 00000 n 0000158756 00000 n 0000158894 00000 n 0000159032 00000 n 0000159170 00000 n 0000160119 00000 n 0000162394 00000 n 0000160220 00000 n 0000162317 00000 n 0000160362 00000 n 0000160500 00000 n 0000160634 00000 n 0000160768 00000 n 0000160901 00000 n 0000161033 00000 n 0000161165 00000 n 0000162607 00000 n 0000165402 00000 n 0000162709 00000 n 0000165301 00000 n 0000162851 00000 n 0000162989 00000 n 0000163131 00000 n 0000163271 00000 n 0000163409 00000 n 0000163547 00000 n 0000163685 00000 n 0000163823 00000 n 0000163961 00000 n 0000164099 00000 n 0000165615 00000 n 0000166604 00000 n 0000165637 00000 n 0000166559 00000 n 0000165771 00000 n 0000165905 00000 n 0000166039 00000 n 0000166817 00000 n 0000167981 00000 n 0000166838 00000 n 0000168176 00000 n 0000169536 00000 n 0000168198 00000 n 0000169731 00000 n 0000171240 00000 n 0000169753 00000 n 0000171435 00000 n 0000173355 00000 n 0000171457 00000 n 0000171537 00000 n 0000173310 00000 n 0000171675 00000 n 0000171755 00000 n 0000171893 00000 n 0000171973 00000 n 0000172111 00000 n 0000173568 00000 n 0000180635 00000 n 0000173670 00000 n 0000180446 00000 n 0000173808 00000 n 0000173947 00000 n 0000174089 00000 n 0000174228 00000 n 0000174368 00000 n 0000174507 00000 n 0000174649 00000 n 0000174788 00000 n 0000174930 00000 n 0000175069 00000 n 0000175211 00000 n 0000175350 00000 n 0000175492 00000 n 0000175631 00000 n 0000175773 00000 n 0000175912 00000 n 0000176054 00000 n 0000176193 00000 n 0000176335 00000 n 0000176415 00000 n 0000176553 00000 n 0000176695 00000 n 0000180848 00000 n 0000182412 00000 n 0000180870 00000 n 0000182607 00000 n 0000184313 00000 n 0000182629 00000 n 0000182709 00000 n 0000184284 00000 n 0000182845 00000 n 0000184526 00000 n 0000185958 00000 n 0000184548 00000 n 0000186153 00000 n 0000188145 00000 n 0000186175 00000 n 0000188100 00000 n 0000186312 00000 n 0000186392 00000 n 0000186528 00000 n 0000186608 00000 n 0000186744 00000 n 0000188358 00000 n 0000189929 00000 n 0000188380 00000 n 0000189884 00000 n 0000188518 00000 n 0000188656 00000 n 0000188736 00000 n 0000188874 00000 n 0000190142 00000 n 0000190995 00000 n 0000190163 00000 n 0000190958 00000 n 0000190297 00000 n 0000190431 00000 n 0000191208 00000 n 0000192138 00000 n 0000191229 00000 n 0000192093 00000 n 0000191367 00000 n 0000191505 00000 n 0000191643 00000 n 0000192351 00000 n 0000192742 00000 n 0000192372 00000 n 0000192937 00000 n 0000194624 00000 n 0000192958 00000 n 0000194819 00000 n 0000196526 00000 n 0000194841 00000 n 0000194921 00000 n 0000196497 00000 n 0000195057 00000 n 0000196739 00000 n 0000198103 00000 n 0000196761 00000 n 0000198298 00000 n 0000200303 00000 n 0000198320 00000 n 0000200258 00000 n 0000198457 00000 n 0000198537 00000 n 0000198673 00000 n 0000198753 00000 n 0000198889 00000 n 0000200516 00000 n 0000201779 00000 n 0000200538 00000 n 0000201734 00000 n 0000200676 00000 n 0000200814 00000 n 0000200894 00000 n 0000201032 00000 n 0000201992 00000 n 0000202843 00000 n 0000202013 00000 n 0000202806 00000 n 0000202147 00000 n 0000202281 00000 n 0000203056 00000 n 0000204036 00000 n 0000203077 00000 n 0000203991 00000 n 0000203215 00000 n 0000203353 00000 n 0000203491 00000 n 0000204249 00000 n 0000204703 00000 n 0000204270 00000 n 0000204898 00000 n 0000206507 00000 n 0000204919 00000 n 0000206702 00000 n 0000208287 00000 n 0000206724 00000 n 0000208482 00000 n 0000210081 00000 n 0000208504 00000 n 0000210276 00000 n 0000212345 00000 n 0000210298 00000 n 0000210378 00000 n 0000212300 00000 n 0000210515 00000 n 0000210595 00000 n 0000210731 00000 n 0000210811 00000 n 0000210947 00000 n 0000212558 00000 n 0000213567 00000 n 0000212580 00000 n 0000213522 00000 n 0000212718 00000 n 0000212856 00000 n 0000212936 00000 n 0000213074 00000 n 0000213780 00000 n 0000214937 00000 n 0000213801 00000 n 0000214892 00000 n 0000213939 00000 n 0000214077 00000 n 0000214215 00000 n 0000215150 00000 n 0000216133 00000 n 0000215171 00000 n 0000216088 00000 n 0000215309 00000 n 0000215447 00000 n 0000215585 00000 n 0000216346 00000 n 0000216801 00000 n 0000216367 00000 n 0000216996 00000 n 0000218821 00000 n 0000217017 00000 n 0000219016 00000 n 0000220738 00000 n 0000219038 00000 n 0000220933 00000 n 0000221875 00000 n 0000220955 00000 n 0000221035 00000 n 0000221838 00000 n 0000221173 00000 n 0000221253 00000 n 0000221391 00000 n 0000222088 00000 n 0000223847 00000 n 0000222109 00000 n 0000223810 00000 n 0000222245 00000 n 0000222381 00000 n 0000224060 00000 n 0000224954 00000 n 0000224082 00000 n 0000224162 00000 n 0000224917 00000 n 0000224300 00000 n 0000224438 00000 n 0000225167 00000 n 0000225560 00000 n 0000225188 00000 n 0000225755 00000 n 0000226211 00000 n 0000225776 00000 n 0000226406 00000 n 0000228043 00000 n 0000237298 00000 n 0000226427 00000 n 0000228014 00000 n 0000226563 00000 n 0000228256 00000 n 0000230346 00000 n 0000228278 00000 n 0000230293 00000 n 0000228416 00000 n 0000228496 00000 n 0000232914 00000 n 0000228633 00000 n 0000243087 00000 n 0000228769 00000 n 0000228905 00000 n 0000230559 00000 n 0000231014 00000 n 0000230581 00000 n 0000231209 00000 n 0000232679 00000 n 0000231230 00000 n 0000232650 00000 n 0000231364 00000 n 0000232892 00000 n 0000235189 00000 n 0000232994 00000 n 0000235128 00000 n 0000233132 00000 n 0000233270 00000 n 0000233350 00000 n 0000233487 00000 n 0000233623 00000 n 0000233703 00000 n 0000233839 00000 n 0000235402 00000 n 0000237063 00000 n 0000235424 00000 n 0000237026 00000 n 0000235560 00000 n 0000235696 00000 n 0000237276 00000 n 0000239512 00000 n 0000237378 00000 n 0000239443 00000 n 0000237512 00000 n 0000237646 00000 n 0000237780 00000 n 0000237913 00000 n 0000238045 00000 n 0000238125 00000 n 0000238257 00000 n 0000239725 00000 n 0000240984 00000 n 0000239747 00000 n 0000240923 00000 n 0000239881 00000 n 0000240015 00000 n 0000240149 00000 n 0000240283 00000 n 0000240417 00000 n 0000241197 00000 n 0000241838 00000 n 0000241218 00000 n 0000241809 00000 n 0000241352 00000 n 0000242051 00000 n 0000242853 00000 n 0000242072 00000 n 0000242816 00000 n 0000242206 00000 n 0000242340 00000 n 0000243066 00000 n 0000245336 00000 n 0000243167 00000 n 0000245267 00000 n 0000243305 00000 n 0000243443 00000 n 0000243581 00000 n 0000243718 00000 n 0000243854 00000 n 0000243990 00000 n 0000245549 00000 n 0000246809 00000 n 0000245571 00000 n 0000246748 00000 n 0000245705 00000 n 0000245839 00000 n 0000245973 00000 n 0000246107 00000 n 0000246241 00000 n 0000247022 00000 n 0000248133 00000 n 0000247043 00000 n 0000248080 00000 n 0000247177 00000 n 0000247311 00000 n 0000247445 00000 n 0000247579 00000 n 0000248346 00000 n 0000263619 00000 n 0000248367 00000 n 0000263230 00000 n 0000248506 00000 n 0000248648 00000 n 0000248787 00000 n 0000248929 00000 n 0000249068 00000 n 0000249210 00000 n 0000249349 00000 n 0000249491 00000 n 0000249630 00000 n 0000249772 00000 n 0000249910 00000 n 0000250052 00000 n 0000250190 00000 n 0000250332 00000 n 0000250471 00000 n 0000250613 00000 n 0000250752 00000 n 0000250892 00000 n 0000251030 00000 n 0000251170 00000 n 0000251309 00000 n 0000251449 00000 n 0000251588 00000 n 0000251730 00000 n 0000251869 00000 n 0000252009 00000 n 0000252148 00000 n 0000252290 00000 n 0000252429 00000 n 0000252571 00000 n 0000252710 00000 n 0000252852 00000 n 0000252991 00000 n 0000253133 00000 n 0000253272 00000 n 0000253414 00000 n 0000253553 00000 n 0000253695 00000 n 0000253834 00000 n 0000253976 00000 n 0000254115 00000 n 0000254257 00000 n 0000254396 00000 n 0000558945 00000 n 0000254538 00000 n 0000254677 00000 n 0000254819 00000 n 0000263832 00000 n 0000264982 00000 n 0000263854 00000 n 0000264929 00000 n 0000263992 00000 n 0000264130 00000 n 0000264268 00000 n 0000264406 00000 n 0000265195 00000 n 0000266417 00000 n 0000560730 00000 n 0000265216 00000 n 0000266388 00000 n 0000265354 00000 n 0000266630 00000 n 0000267814 00000 n 0000266651 00000 n 0000266731 00000 n 0000267777 00000 n 0000266870 00000 n 0000267009 00000 n 0000268027 00000 n 0000269223 00000 n 0000566260 00000 n 0000268048 00000 n 0000269186 00000 n 0000568868 00000 n 0000268186 00000 n 0000268324 00000 n 0000269436 00000 n 0000270732 00000 n 0000563246 00000 n 0000269457 00000 n 0000270695 00000 n 0000269595 00000 n 0000269733 00000 n 0000270945 00000 n 0000271719 00000 n 0000270966 00000 n 0000271682 00000 n 0000271104 00000 n 0000271242 00000 n 0000271932 00000 n 0000272755 00000 n 0000573461 00000 n 0000271953 00000 n 0000272725 00000 n 0000272091 00000 n 0000272970 00000 n 0000274660 00000 n 0000570996 00000 n 0000272992 00000 n 0000274629 00000 n 0000273128 00000 n 0000274876 00000 n 0000278614 00000 n 0000274899 00000 n 0000278811 00000 n 0000279911 00000 n 0000278834 00000 n 0000280108 00000 n 0000280808 00000 n 0000280130 00000 n 0000281005 00000 n 0000281489 00000 n 0000281027 00000 n 0000281686 00000 n 0000291454 00000 n 0000281708 00000 n 0000291162 00000 n 0000281847 00000 n 0000580600 00000 n 0000281991 00000 n 0000583976 00000 n 0000282135 00000 n 0000590914 00000 n 0000282277 00000 n 0000587885 00000 n 0000282419 00000 n 0000282561 00000 n 0000282701 00000 n 0000282844 00000 n 0000282984 00000 n 0000283127 00000 n 0000283267 00000 n 0000283410 00000 n 0000283550 00000 n 0000283693 00000 n 0000283833 00000 n 0000283976 00000 n 0000284117 00000 n 0000284261 00000 n 0000284401 00000 n 0000577387 00000 n 0000284544 00000 n 0000284685 00000 n 0000284829 00000 n 0000284970 00000 n 0000285114 00000 n 0000285255 00000 n 0000285399 00000 n 0000285540 00000 n 0000285684 00000 n 0000285825 00000 n 0000285969 00000 n 0000291670 00000 n 0000292994 00000 n 0000291693 00000 n 0000292927 00000 n 0000291829 00000 n 0000291965 00000 n 0000292101 00000 n 0000292237 00000 n 0000292373 00000 n 0000293210 00000 n 0000294816 00000 n 0000293232 00000 n 0000294749 00000 n 0000293371 00000 n 0000293511 00000 n 0000293651 00000 n 0000293791 00000 n 0000293931 00000 n 0000295032 00000 n 0000297154 00000 n 0000295054 00000 n 0000297087 00000 n 0000295193 00000 n 0000295333 00000 n 0000295473 00000 n 0000295613 00000 n 0000295753 00000 n 0000297370 00000 n 0000299556 00000 n 0000297393 00000 n 0000299489 00000 n 0000297532 00000 n 0000297672 00000 n 0000297812 00000 n 0000297952 00000 n 0000298092 00000 n 0000299772 00000 n 0000301099 00000 n 0000299795 00000 n 0000301296 00000 n 0000303080 00000 n 0000301319 00000 n 0000303013 00000 n 0000301458 00000 n 0000301598 00000 n 0000301738 00000 n 0000301878 00000 n 0000302018 00000 n 0000303296 00000 n 0000304139 00000 n 0000598805 00000 n 0000303318 00000 n 0000304099 00000 n 0000602673 00000 n 0000303454 00000 n 0000303590 00000 n 0000304355 00000 n 0000336877 00000 n 0000304377 00000 n 0000335883 00000 n 0000304513 00000 n 0000304652 00000 n 0000304788 00000 n 0000304927 00000 n 0000305063 00000 n 0000305202 00000 n 0000305338 00000 n 0000305477 00000 n 0000305613 00000 n 0000305752 00000 n 0000305888 00000 n 0000306027 00000 n 0000306163 00000 n 0000306302 00000 n 0000306438 00000 n 0000306577 00000 n 0000306712 00000 n 0000306851 00000 n 0000306932 00000 n 0000307069 00000 n 0000307209 00000 n 0000307345 00000 n 0000307484 00000 n 0000307620 00000 n 0000307759 00000 n 0000307895 00000 n 0000308034 00000 n 0000308170 00000 n 0000308309 00000 n 0000308445 00000 n 0000308584 00000 n 0000308719 00000 n 0000308858 00000 n 0000308993 00000 n 0000309132 00000 n 0000309268 00000 n 0000309407 00000 n 0000309543 00000 n 0000309680 00000 n 0000309815 00000 n 0000309954 00000 n 0000310090 00000 n 0000310229 00000 n 0000310365 00000 n 0000310504 00000 n 0000310640 00000 n 0000310779 00000 n 0000310915 00000 n 0000311054 00000 n 0000311190 00000 n 0000311329 00000 n 0000311465 00000 n 0000311604 00000 n 0000311740 00000 n 0000311879 00000 n 0000312015 00000 n 0000312154 00000 n 0000312290 00000 n 0000312429 00000 n 0000312565 00000 n 0000312704 00000 n 0000312840 00000 n 0000312979 00000 n 0000313115 00000 n 0000313254 00000 n 0000313390 00000 n 0000313529 00000 n 0000313611 00000 n 0000313748 00000 n 0000313888 00000 n 0000314024 00000 n 0000314163 00000 n 0000314299 00000 n 0000314438 00000 n 0000314574 00000 n 0000314711 00000 n 0000314847 00000 n 0000314986 00000 n 0000315122 00000 n 0000315261 00000 n 0000315398 00000 n 0000315538 00000 n 0000315674 00000 n 0000315813 00000 n 0000315950 00000 n 0000316090 00000 n 0000316227 00000 n 0000316367 00000 n 0000316504 00000 n 0000316644 00000 n 0000316781 00000 n 0000316921 00000 n 0000317058 00000 n 0000338957 00000 n 0000317198 00000 n 0000317336 00000 n 0000594879 00000 n 0000317476 00000 n 0000317613 00000 n 0000596808 00000 n 0000317753 00000 n 0000317890 00000 n 0000318028 00000 n 0000318165 00000 n 0000600825 00000 n 0000318305 00000 n 0000318442 00000 n 0000318582 00000 n 0000318718 00000 n 0000605070 00000 n 0000318855 00000 n 0000318990 00000 n 0000607321 00000 n 0000319128 00000 n 0000319263 00000 n 0000319397 00000 n 0000337093 00000 n 0000338064 00000 n 0000337117 00000 n 0000338015 00000 n 0000337253 00000 n 0000337389 00000 n 0000337525 00000 n 0000338280 00000 n 0000338738 00000 n 0000338302 00000 n 0000338935 00000 n 0000345282 00000 n 0000339039 00000 n 0000345098 00000 n 0000339179 00000 n 0000339323 00000 n 0000339464 00000 n 0000339608 00000 n 0000339749 00000 n 0000339893 00000 n 0000340034 00000 n 0000340178 00000 n 0000340319 00000 n 0000340463 00000 n 0000340604 00000 n 0000340748 00000 n 0000340889 00000 n 0000341033 00000 n 0000341174 00000 n 0000609950 00000 n 0000341318 00000 n 0000341459 00000 n 0000341603 00000 n 0000345498 00000 n 0000346946 00000 n 0000345521 00000 n 0000346879 00000 n 0000345661 00000 n 0000345801 00000 n 0000345941 00000 n 0000346081 00000 n 0000346221 00000 n 0000347162 00000 n 0000348787 00000 n 0000347184 00000 n 0000348711 00000 n 0000347324 00000 n 0000347464 00000 n 0000347604 00000 n 0000347744 00000 n 0000347884 00000 n 0000348024 00000 n 0000349003 00000 n 0000350632 00000 n 0000349025 00000 n 0000350556 00000 n 0000349165 00000 n 0000349305 00000 n 0000349445 00000 n 0000349585 00000 n 0000349725 00000 n 0000349865 00000 n 0000350848 00000 n 0000351694 00000 n 0000350870 00000 n 0000351654 00000 n 0000351006 00000 n 0000351142 00000 n 0000351910 00000 n 0000353185 00000 n 0000351932 00000 n 0000353118 00000 n 0000352072 00000 n 0000352212 00000 n 0000352352 00000 n 0000352492 00000 n 0000352632 00000 n 0000353401 00000 n 0000354197 00000 n 0000353423 00000 n 0000354394 00000 n 0000355640 00000 n 0000354416 00000 n 0000355837 00000 n 0000357993 00000 n 0000634387 00000 n 0000355941 00000 n 0000357962 00000 n 0000356079 00000 n 0000358209 00000 n 0000360326 00000 n 0000358315 00000 n 0000360295 00000 n 0000358457 00000 n 0000360542 00000 n 0000363854 00000 n 0000360565 00000 n 0000360647 00000 n 0000363814 00000 n 0000360785 00000 n 0000360923 00000 n 0000364070 00000 n 0000365424 00000 n 0000364093 00000 n 0000365621 00000 n 0000367308 00000 n 0000365644 00000 n 0000367505 00000 n 0000368421 00000 n 0000367528 00000 n 0000368618 00000 n 0000369653 00000 n 0000368640 00000 n 0000369850 00000 n 0000370758 00000 n 0000641004 00000 n 0000369872 00000 n 0000370727 00000 n 0000370008 00000 n 0000370974 00000 n 0000372817 00000 n 0000630865 00000 n 0000370996 00000 n 0000372768 00000 n 0000371136 00000 n 0000371218 00000 n 0000371358 00000 n 0000371498 00000 n 0000373033 00000 n 0000378516 00000 n 0000373056 00000 n 0000378350 00000 n 0000373196 00000 n 0000373340 00000 n 0000373484 00000 n 0000373624 00000 n 0000373765 00000 n 0000373909 00000 n 0000374050 00000 n 0000374194 00000 n 0000374335 00000 n 0000374479 00000 n 0000374620 00000 n 0000374764 00000 n 0000374905 00000 n 0000612109 00000 n 0000375049 00000 n 0000375190 00000 n 0000375334 00000 n 0000378732 00000 n 0000379351 00000 n 0000378755 00000 n 0000379320 00000 n 0000378895 00000 n 0000379567 00000 n 0000380797 00000 n 0000379589 00000 n 0000380757 00000 n 0000379731 00000 n 0000379871 00000 n 0000381013 00000 n 0000383337 00000 n 0000381035 00000 n 0000383261 00000 n 0000381170 00000 n 0000381306 00000 n 0000381442 00000 n 0000381578 00000 n 0000646610 00000 n 0000381714 00000 n 0000381850 00000 n 0000383553 00000 n 0000384207 00000 n 0000383576 00000 n 0000384176 00000 n 0000383716 00000 n 0000384423 00000 n 0000385567 00000 n 0000384445 00000 n 0000385518 00000 n 0000384584 00000 n 0000651621 00000 n 0000384723 00000 n 0000384863 00000 n 0000385783 00000 n 0000386574 00000 n 0000654376 00000 n 0000385805 00000 n 0000386534 00000 n 0000657290 00000 n 0000385941 00000 n 0000386077 00000 n 0000386790 00000 n 0000387761 00000 n 0000386812 00000 n 0000387712 00000 n 0000386952 00000 n 0000387092 00000 n 0000387231 00000 n 0000387977 00000 n 0000388783 00000 n 0000387999 00000 n 0000388743 00000 n 0000388139 00000 n 0000388279 00000 n 0000388999 00000 n 0000389857 00000 n 0000389021 00000 n 0000389817 00000 n 0000389161 00000 n 0000389301 00000 n 0000390073 00000 n 0000399732 00000 n 0000390095 00000 n 0000390177 00000 n 0000399422 00000 n 0000390321 00000 n 0000663116 00000 n 0000390465 00000 n 0000390609 00000 n 0000660290 00000 n 0000390749 00000 n 0000390891 00000 n 0000391031 00000 n 0000391175 00000 n 0000391319 00000 n 0000649131 00000 n 0000391459 00000 n 0000643858 00000 n 0000391603 00000 n 0000391744 00000 n 0000391886 00000 n 0000391968 00000 n 0000392109 00000 n 0000399971 00000 n 0000392253 00000 n 0000392394 00000 n 0000392538 00000 n 0000392678 00000 n 0000392822 00000 n 0000392963 00000 n 0000393107 00000 n 0000393248 00000 n 0000393392 00000 n 0000393533 00000 n 0000393677 00000 n 0000393818 00000 n 0000393962 00000 n 0000394103 00000 n 0000394247 00000 n 0000394388 00000 n 0000665974 00000 n 0000394532 00000 n 0000394673 00000 n 0000394817 00000 n 0000399948 00000 n 0000401443 00000 n 0000400053 00000 n 0000401394 00000 n 0000400197 00000 n 0000400337 00000 n 0000400477 00000 n 0000401659 00000 n 0000402487 00000 n 0000401681 00000 n 0000402447 00000 n 0000401821 00000 n 0000401961 00000 n 0000402703 00000 n 0000403514 00000 n 0000402725 00000 n 0000403474 00000 n 0000402865 00000 n 0000403005 00000 n 0000403730 00000 n 0000405023 00000 n 0000403752 00000 n 0000404965 00000 n 0000403892 00000 n 0000404032 00000 n 0000404172 00000 n 0000404312 00000 n 0000405239 00000 n 0000406071 00000 n 0000614237 00000 n 0000405261 00000 n 0000406031 00000 n 0000618902 00000 n 0000405401 00000 n 0000405541 00000 n 0000406287 00000 n 0000407179 00000 n 0000406309 00000 n 0000407139 00000 n 0000616626 00000 n 0000406449 00000 n 0000406589 00000 n 0000407395 00000 n 0000412684 00000 n 0000407417 00000 n 0000412536 00000 n 0000407558 00000 n 0000407702 00000 n 0000407843 00000 n 0000407987 00000 n 0000408128 00000 n 0000621119 00000 n 0000408270 00000 n 0000408411 00000 n 0000623241 00000 n 0000408555 00000 n 0000408696 00000 n 0000625610 00000 n 0000408840 00000 n 0000408981 00000 n 0000627766 00000 n 0000409125 00000 n 0000409266 00000 n 0000409408 00000 n 0000412900 00000 n 0000414332 00000 n 0000412923 00000 n 0000414256 00000 n 0000413063 00000 n 0000413203 00000 n 0000413343 00000 n 0000413483 00000 n 0000413623 00000 n 0000413763 00000 n 0000414548 00000 n 0000415453 00000 n 0000414570 00000 n 0000415404 00000 n 0000414706 00000 n 0000414842 00000 n 0000414978 00000 n 0000415669 00000 n 0000416959 00000 n 0000415691 00000 n 0000416901 00000 n 0000415831 00000 n 0000415971 00000 n 0000416111 00000 n 0000416251 00000 n 0000417175 00000 n 0000418760 00000 n 0000417197 00000 n 0000418675 00000 n 0000417337 00000 n 0000417477 00000 n 0000417617 00000 n 0000417757 00000 n 0000417897 00000 n 0000418037 00000 n 0000418177 00000 n 0000418976 00000 n 0000419916 00000 n 0000418998 00000 n 0000419867 00000 n 0000419138 00000 n 0000419278 00000 n 0000419418 00000 n 0000420132 00000 n 0000421089 00000 n 0000420154 00000 n 0000421286 00000 n 0000422344 00000 n 0000421308 00000 n 0000421390 00000 n 0000422313 00000 n 0000421531 00000 n 0000422560 00000 n 0000423840 00000 n 0000422582 00000 n 0000422664 00000 n 0000423800 00000 n 0000422805 00000 n 0000422947 00000 n 0000424056 00000 n 0000425322 00000 n 0000424078 00000 n 0000424160 00000 n 0000425282 00000 n 0000424301 00000 n 0000424443 00000 n 0000425538 00000 n 0000426964 00000 n 0000425560 00000 n 0000425642 00000 n 0000426915 00000 n 0000425783 00000 n 0000425924 00000 n 0000426066 00000 n 0000427180 00000 n 0000428619 00000 n 0000427202 00000 n 0000428579 00000 n 0000427346 00000 n 0000427490 00000 n 0000428835 00000 n 0000430264 00000 n 0000428858 00000 n 0000428940 00000 n 0000430206 00000 n 0000429084 00000 n 0000429223 00000 n 0000429362 00000 n 0000429501 00000 n 0000430480 00000 n 0000431794 00000 n 0000430502 00000 n 0000431736 00000 n 0000430646 00000 n 0000430785 00000 n 0000430924 00000 n 0000431063 00000 n 0000432010 00000 n 0000433276 00000 n 0000432032 00000 n 0000433218 00000 n 0000432176 00000 n 0000432315 00000 n 0000432454 00000 n 0000432593 00000 n 0000433492 00000 n 0000435479 00000 n 0000433514 00000 n 0000433596 00000 n 0000435430 00000 n 0000433737 00000 n 0000433879 00000 n 0000434020 00000 n 0000435695 00000 n 0000437897 00000 n 0000435718 00000 n 0000435800 00000 n 0000437839 00000 n 0000435941 00000 n 0000436085 00000 n 0000436227 00000 n 0000436369 00000 n 0000438113 00000 n 0000440095 00000 n 0000438136 00000 n 0000440046 00000 n 0000438280 00000 n 0000438424 00000 n 0000438566 00000 n 0000440311 00000 n 0000442228 00000 n 0000440334 00000 n 0000442179 00000 n 0000440478 00000 n 0000440622 00000 n 0000440763 00000 n 0000442444 00000 n 0000444607 00000 n 0000442467 00000 n 0000444549 00000 n 0000442608 00000 n 0000442752 00000 n 0000442894 00000 n 0000443036 00000 n 0000444823 00000 n 0000446943 00000 n 0000444846 00000 n 0000446885 00000 n 0000444987 00000 n 0000445131 00000 n 0000445273 00000 n 0000445415 00000 n 0000447159 00000 n 0000456208 00000 n 0000447182 00000 n 0000455952 00000 n 0000447323 00000 n 0000447467 00000 n 0000447549 00000 n 0000447690 00000 n 0000447834 00000 n 0000447975 00000 n 0000448119 00000 n 0000448260 00000 n 0000448404 00000 n 0000448545 00000 n 0000448689 00000 n 0000448829 00000 n 0000448973 00000 n 0000449114 00000 n 0000449258 00000 n 0000449399 00000 n 0000449543 00000 n 0000449684 00000 n 0000449828 00000 n 0000449910 00000 n 0000450051 00000 n 0000450195 00000 n 0000450277 00000 n 0000450418 00000 n 0000450562 00000 n 0000450644 00000 n 0000450785 00000 n 0000450929 00000 n 0000451011 00000 n 0000451152 00000 n 0000451296 00000 n 0000456424 00000 n 0000472634 00000 n 0000456447 00000 n 0000471730 00000 n 0000456588 00000 n 0000456728 00000 n 0000456868 00000 n 0000457009 00000 n 0000457148 00000 n 0000457288 00000 n 0000457429 00000 n 0000457568 00000 n 0000457708 00000 n 0000457848 00000 n 0000457987 00000 n 0000458127 00000 n 0000458268 00000 n 0000458408 00000 n 0000458549 00000 n 0000458690 00000 n 0000458830 00000 n 0000458970 00000 n 0000459111 00000 n 0000459251 00000 n 0000459392 00000 n 0000459531 00000 n 0000459672 00000 n 0000459812 00000 n 0000459952 00000 n 0000460093 00000 n 0000460233 00000 n 0000460374 00000 n 0000460515 00000 n 0000460655 00000 n 0000460794 00000 n 0000460934 00000 n 0000461074 00000 n 0000461214 00000 n 0000461354 00000 n 0000461495 00000 n 0000461635 00000 n 0000461775 00000 n 0000461915 00000 n 0000462055 00000 n 0000462195 00000 n 0000462336 00000 n 0000462476 00000 n 0000462617 00000 n 0000462758 00000 n 0000462899 00000 n 0000463039 00000 n 0000463180 00000 n 0000463319 00000 n 0000463459 00000 n 0000463598 00000 n 0000463739 00000 n 0000463879 00000 n 0000464019 00000 n 0000464160 00000 n 0000464301 00000 n 0000464442 00000 n 0000464582 00000 n 0000464722 00000 n 0000464861 00000 n 0000465002 00000 n 0000465143 00000 n 0000465283 00000 n 0000465424 00000 n 0000465564 00000 n 0000465705 00000 n 0000465845 00000 n 0000465986 00000 n 0000466125 00000 n 0000466266 00000 n 0000466407 00000 n 0000466548 00000 n 0000466687 00000 n 0000466828 00000 n 0000466968 00000 n 0000467109 00000 n 0000467249 00000 n 0000467389 00000 n 0000467528 00000 n 0000467669 00000 n 0000467810 00000 n 0000467950 00000 n 0000468090 00000 n 0000468230 00000 n 0000468371 00000 n 0000468512 00000 n 0000468652 00000 n 0000468793 00000 n 0000468934 00000 n 0000469075 00000 n 0000469215 00000 n 0000469356 00000 n 0000469496 00000 n 0000469636 00000 n 0000469774 00000 n 0000469913 00000 n 0000470051 00000 n 0000470190 00000 n 0000472850 00000 n 0000473980 00000 n 0000472873 00000 n 0000472955 00000 n 0000473940 00000 n 0000473096 00000 n 0000473240 00000 n 0000474196 00000 n 0000476048 00000 n 0000474218 00000 n 0000475945 00000 n 0000474354 00000 n 0000474490 00000 n 0000474626 00000 n 0000474762 00000 n 0000474899 00000 n 0000475035 00000 n 0000475171 00000 n 0000475308 00000 n 0000475444 00000 n 0000476264 00000 n 0000478298 00000 n 0000476286 00000 n 0000478495 00000 n 0000479813 00000 n 0000478518 00000 n 0000478600 00000 n 0000479782 00000 n 0000478735 00000 n 0000480029 00000 n 0000481894 00000 n 0000480051 00000 n 0000482091 00000 n 0000515135 00000 n 0000482114 00000 n 0000514141 00000 n 0000482251 00000 n 0000482391 00000 n 0000482529 00000 n 0000482665 00000 n 0000482802 00000 n 0000482940 00000 n 0000483077 00000 n 0000483217 00000 n 0000483354 00000 n 0000483492 00000 n 0000483629 00000 n 0000483769 00000 n 0000483906 00000 n 0000484046 00000 n 0000484183 00000 n 0000484323 00000 n 0000484405 00000 n 0000484542 00000 n 0000484682 00000 n 0000484819 00000 n 0000484959 00000 n 0000485096 00000 n 0000485236 00000 n 0000485373 00000 n 0000485513 00000 n 0000485649 00000 n 0000485787 00000 n 0000485924 00000 n 0000486064 00000 n 0000486201 00000 n 0000486341 00000 n 0000486478 00000 n 0000486618 00000 n 0000486755 00000 n 0000486895 00000 n 0000487032 00000 n 0000487172 00000 n 0000487309 00000 n 0000487449 00000 n 0000487586 00000 n 0000487726 00000 n 0000487808 00000 n 0000487946 00000 n 0000488086 00000 n 0000488223 00000 n 0000488363 00000 n 0000488500 00000 n 0000488640 00000 n 0000488777 00000 n 0000488917 00000 n 0000489054 00000 n 0000489192 00000 n 0000489329 00000 n 0000489469 00000 n 0000489606 00000 n 0000489746 00000 n 0000489883 00000 n 0000490023 00000 n 0000490105 00000 n 0000490243 00000 n 0000490383 00000 n 0000490520 00000 n 0000490660 00000 n 0000490797 00000 n 0000490937 00000 n 0000491074 00000 n 0000491214 00000 n 0000491351 00000 n 0000491491 00000 n 0000491627 00000 n 0000491767 00000 n 0000491904 00000 n 0000492042 00000 n 0000492179 00000 n 0000492319 00000 n 0000492456 00000 n 0000492596 00000 n 0000492733 00000 n 0000492871 00000 n 0000493008 00000 n 0000493148 00000 n 0000493285 00000 n 0000493425 00000 n 0000493562 00000 n 0000493702 00000 n 0000493784 00000 n 0000493922 00000 n 0000494062 00000 n 0000494200 00000 n 0000494340 00000 n 0000494478 00000 n 0000494614 00000 n 0000494698 00000 n 0000494836 00000 n 0000494976 00000 n 0000495060 00000 n 0000495197 00000 n 0000495337 00000 n 0000495421 00000 n 0000495557 00000 n 0000495697 00000 n 0000495781 00000 n 0000495918 00000 n 0000496058 00000 n 0000496142 00000 n 0000496280 00000 n 0000496420 00000 n 0000496504 00000 n 0000496641 00000 n 0000496781 00000 n 0000496865 00000 n 0000497003 00000 n 0000497143 00000 n 0000497227 00000 n 0000497362 00000 n 0000497501 00000 n 0000497585 00000 n 0000497720 00000 n 0000497858 00000 n 0000497942 00000 n 0000498078 00000 n 0000498216 00000 n 0000515351 00000 n 0000517188 00000 n 0000515375 00000 n 0000517385 00000 n 0000518876 00000 n 0000517408 00000 n 0000519073 00000 n 0000520226 00000 n 0000519096 00000 n 0000520423 00000 n 0000522129 00000 n 0000520446 00000 n 0000522098 00000 n 0000520587 00000 n 0000522345 00000 n 0000524711 00000 n 0000522368 00000 n 0000524680 00000 n 0000522509 00000 n 0000524927 00000 n 0000526587 00000 n 0000524950 00000 n 0000526547 00000 n 0000525092 00000 n 0000525234 00000 n 0000526803 00000 n 0000530112 00000 n 0000526826 00000 n 0000526910 00000 n 0000530027 00000 n 0000527052 00000 n 0000527194 00000 n 0000527278 00000 n 0000527420 00000 n 0000527562 00000 n 0000527704 00000 n 0000527788 00000 n 0000527930 00000 n 0000528070 00000 n 0000530328 00000 n 0000553588 00000 n 0000530351 00000 n 0000530435 00000 n 0000552954 00000 n 0000530572 00000 n 0000530712 00000 n 0000530796 00000 n 0000530933 00000 n 0000531073 00000 n 0000531157 00000 n 0000531293 00000 n 0000531433 00000 n 0000531517 00000 n 0000531654 00000 n 0000531794 00000 n 0000531878 00000 n 0000532016 00000 n 0000669006 00000 n 0000532156 00000 n 0000532293 00000 n 0000669089 00000 n 0000532433 00000 n 0000532570 00000 n 0000669173 00000 n 0000532710 00000 n 0000532846 00000 n 0000532986 00000 n 0000533068 00000 n 0000533205 00000 n 0000533345 00000 n 0000533429 00000 n 0000533567 00000 n 0000533707 00000 n 0000533791 00000 n 0000533928 00000 n 0000534068 00000 n 0000534152 00000 n 0000534289 00000 n 0000534429 00000 n 0000534511 00000 n 0000534647 00000 n 0000534787 00000 n 0000534871 00000 n 0000535007 00000 n 0000535147 00000 n 0000535231 00000 n 0000535368 00000 n 0000535508 00000 n 0000535592 00000 n 0000535730 00000 n 0000535870 00000 n 0000535954 00000 n 0000536091 00000 n 0000536231 00000 n 0000536315 00000 n 0000536453 00000 n 0000536593 00000 n 0000536677 00000 n 0000536813 00000 n 0000536953 00000 n 0000537037 00000 n 0000537174 00000 n 0000537314 00000 n 0000537398 00000 n 0000537536 00000 n 0000537676 00000 n 0000537760 00000 n 0000537897 00000 n 0000538037 00000 n 0000538121 00000 n 0000538259 00000 n 0000538399 00000 n 0000538483 00000 n 0000538619 00000 n 0000538759 00000 n 0000538843 00000 n 0000538980 00000 n 0000539120 00000 n 0000539202 00000 n 0000539340 00000 n 0000539480 00000 n 0000539564 00000 n 0000539701 00000 n 0000539841 00000 n 0000539925 00000 n 0000540062 00000 n 0000540200 00000 n 0000540284 00000 n 0000540420 00000 n 0000540560 00000 n 0000540644 00000 n 0000540782 00000 n 0000540922 00000 n 0000541004 00000 n 0000541141 00000 n 0000541281 00000 n 0000541365 00000 n 0000541503 00000 n 0000541643 00000 n 0000541727 00000 n 0000541864 00000 n 0000542004 00000 n 0000542086 00000 n 0000542223 00000 n 0000542363 00000 n 0000553804 00000 n 0000558706 00000 n 0000554406 00000 n 0000554490 00000 n 0000558585 00000 n 0000554632 00000 n 0000554774 00000 n 0000554842 00000 n 0000554986 00000 n 0000555126 00000 n 0000555267 00000 n 0000555326 00000 n 0000555470 00000 n 0000555614 00000 n 0000555698 00000 n 0000555842 00000 n 0000555986 00000 n 0000556050 00000 n 0000556186 00000 n 0000556322 00000 n 0000558922 00000 n 0000560491 00000 n 0000559026 00000 n 0000560451 00000 n 0000559168 00000 n 0000559310 00000 n 0000560707 00000 n 0000563007 00000 n 0000560811 00000 n 0000562967 00000 n 0000560953 00000 n 0000561095 00000 n 0000563223 00000 n 0000566021 00000 n 0000563327 00000 n 0000565981 00000 n 0000563469 00000 n 0000563611 00000 n 0000566237 00000 n 0000568629 00000 n 0000566341 00000 n 0000568589 00000 n 0000566483 00000 n 0000566625 00000 n 0000568845 00000 n 0000570757 00000 n 0000568949 00000 n 0000570717 00000 n 0000569091 00000 n 0000569233 00000 n 0000570973 00000 n 0000573222 00000 n 0000571078 00000 n 0000571162 00000 n 0000573164 00000 n 0000571304 00000 n 0000571446 00000 n 0000571588 00000 n 0000571730 00000 n 0000573438 00000 n 0000577148 00000 n 0000573542 00000 n 0000577072 00000 n 0000573686 00000 n 0000573830 00000 n 0000573972 00000 n 0000574114 00000 n 0000574198 00000 n 0000574339 00000 n 0000574480 00000 n 0000577364 00000 n 0000580361 00000 n 0000577469 00000 n 0000580303 00000 n 0000577613 00000 n 0000577757 00000 n 0000577899 00000 n 0000578041 00000 n 0000580577 00000 n 0000583737 00000 n 0000580682 00000 n 0000583661 00000 n 0000580824 00000 n 0000580966 00000 n 0000581108 00000 n 0000581250 00000 n 0000581388 00000 n 0000581526 00000 n 0000583953 00000 n 0000587646 00000 n 0000584058 00000 n 0000587561 00000 n 0000584202 00000 n 0000584346 00000 n 0000584488 00000 n 0000584630 00000 n 0000584774 00000 n 0000584918 00000 n 0000585061 00000 n 0000587862 00000 n 0000590675 00000 n 0000587967 00000 n 0000590617 00000 n 0000588111 00000 n 0000588255 00000 n 0000588393 00000 n 0000588531 00000 n 0000590891 00000 n 0000594640 00000 n 0000590996 00000 n 0000594555 00000 n 0000591140 00000 n 0000591284 00000 n 0000591426 00000 n 0000591568 00000 n 0000591712 00000 n 0000591856 00000 n 0000591999 00000 n 0000594856 00000 n 0000596569 00000 n 0000594961 00000 n 0000596529 00000 n 0000595103 00000 n 0000595245 00000 n 0000596785 00000 n 0000598566 00000 n 0000596890 00000 n 0000598526 00000 n 0000597032 00000 n 0000597174 00000 n 0000598782 00000 n 0000600586 00000 n 0000598887 00000 n 0000600546 00000 n 0000599029 00000 n 0000599171 00000 n 0000600802 00000 n 0000602435 00000 n 0000600907 00000 n 0000602386 00000 n 0000601049 00000 n 0000601191 00000 n 0000601325 00000 n 0000602651 00000 n 0000604831 00000 n 0000602755 00000 n 0000604773 00000 n 0000602897 00000 n 0000603039 00000 n 0000603177 00000 n 0000603315 00000 n 0000605047 00000 n 0000607082 00000 n 0000605152 00000 n 0000607033 00000 n 0000605294 00000 n 0000605436 00000 n 0000605574 00000 n 0000607298 00000 n 0000609711 00000 n 0000607403 00000 n 0000609635 00000 n 0000607545 00000 n 0000607687 00000 n 0000607827 00000 n 0000607966 00000 n 0000608104 00000 n 0000608242 00000 n 0000609927 00000 n 0000611870 00000 n 0000610032 00000 n 0000611830 00000 n 0000610174 00000 n 0000610316 00000 n 0000612086 00000 n 0000613998 00000 n 0000612191 00000 n 0000613958 00000 n 0000612335 00000 n 0000612479 00000 n 0000614214 00000 n 0000616387 00000 n 0000614319 00000 n 0000616347 00000 n 0000614458 00000 n 0000614597 00000 n 0000616603 00000 n 0000618663 00000 n 0000616708 00000 n 0000618623 00000 n 0000616850 00000 n 0000616992 00000 n 0000618879 00000 n 0000620880 00000 n 0000618984 00000 n 0000620822 00000 n 0000619126 00000 n 0000619268 00000 n 0000619408 00000 n 0000619548 00000 n 0000621096 00000 n 0000623002 00000 n 0000621201 00000 n 0000622953 00000 n 0000621343 00000 n 0000621485 00000 n 0000621623 00000 n 0000623218 00000 n 0000625371 00000 n 0000623323 00000 n 0000625331 00000 n 0000623465 00000 n 0000623607 00000 n 0000625587 00000 n 0000627527 00000 n 0000625692 00000 n 0000627487 00000 n 0000625834 00000 n 0000625976 00000 n 0000627743 00000 n 0000629886 00000 n 0000627848 00000 n 0000629828 00000 n 0000627990 00000 n 0000628132 00000 n 0000628272 00000 n 0000628412 00000 n 0000630102 00000 n 0000630646 00000 n 0000630125 00000 n 0000630843 00000 n 0000634148 00000 n 0000630947 00000 n 0000631029 00000 n 0000634036 00000 n 0000631171 00000 n 0000631313 00000 n 0000631455 00000 n 0000631597 00000 n 0000631739 00000 n 0000631883 00000 n 0000632027 00000 n 0000632169 00000 n 0000632311 00000 n 0000632449 00000 n 0000634364 00000 n 0000637807 00000 n 0000634469 00000 n 0000637767 00000 n 0000634613 00000 n 0000634757 00000 n 0000638023 00000 n 0000640765 00000 n 0000638046 00000 n 0000640725 00000 n 0000638189 00000 n 0000638332 00000 n 0000640981 00000 n 0000643619 00000 n 0000641086 00000 n 0000643525 00000 n 0000641228 00000 n 0000641370 00000 n 0000641511 00000 n 0000641652 00000 n 0000641795 00000 n 0000641938 00000 n 0000642078 00000 n 0000642218 00000 n 0000643835 00000 n 0000646371 00000 n 0000643940 00000 n 0000646286 00000 n 0000644082 00000 n 0000644224 00000 n 0000644362 00000 n 0000644500 00000 n 0000644638 00000 n 0000644778 00000 n 0000644916 00000 n 0000646587 00000 n 0000648892 00000 n 0000646692 00000 n 0000648834 00000 n 0000646834 00000 n 0000646976 00000 n 0000647120 00000 n 0000647264 00000 n 0000649108 00000 n 0000651382 00000 n 0000649213 00000 n 0000651324 00000 n 0000649355 00000 n 0000649497 00000 n 0000649639 00000 n 0000649781 00000 n 0000651598 00000 n 0000654137 00000 n 0000651703 00000 n 0000654061 00000 n 0000651845 00000 n 0000651987 00000 n 0000652128 00000 n 0000652269 00000 n 0000652412 00000 n 0000652555 00000 n 0000654353 00000 n 0000657051 00000 n 0000654458 00000 n 0000656975 00000 n 0000654600 00000 n 0000654742 00000 n 0000654884 00000 n 0000655026 00000 n 0000655169 00000 n 0000655312 00000 n 0000657267 00000 n 0000660051 00000 n 0000657372 00000 n 0000659975 00000 n 0000657514 00000 n 0000657656 00000 n 0000657798 00000 n 0000657940 00000 n 0000658084 00000 n 0000658228 00000 n 0000660267 00000 n 0000662877 00000 n 0000660372 00000 n 0000662801 00000 n 0000660514 00000 n 0000660656 00000 n 0000660798 00000 n 0000660940 00000 n 0000661084 00000 n 0000661228 00000 n 0000663093 00000 n 0000665735 00000 n 0000663198 00000 n 0000665659 00000 n 0000663340 00000 n 0000663482 00000 n 0000663624 00000 n 0000663766 00000 n 0000663910 00000 n 0000664054 00000 n 0000665951 00000 n 0000668767 00000 n 0000666056 00000 n 0000668691 00000 n 0000666198 00000 n 0000666340 00000 n 0000666482 00000 n 0000666624 00000 n 0000666768 00000 n 0000666912 00000 n 0000668983 00000 n 0000672999 00000 n 0000669257 00000 n 0000672896 00000 n 0000669396 00000 n 0000669478 00000 n 0000669619 00000 n 0000669760 00000 n 0000669903 00000 n 0000670045 00000 n 0000670111 00000 n 0000670254 00000 n 0000670397 00000 n 0000670482 00000 n 0000670622 00000 n 0000670762 00000 n 0000673215 00000 n 0000673238 00000 n 0000673317 00000 n 0000673397 00000 n 0000673479 00000 n 0000673563 00000 n 0000673645 00000 n 0000673729 00000 n 0000673811 00000 n 0000673895 00000 n 0000673977 00000 n 0000674061 00000 n 0000674145 00000 n 0000674229 00000 n 0000674313 00000 n 0000674397 00000 n 0000674481 00000 n 0000674565 00000 n 0000674649 00000 n 0000674732 00000 n 0000674816 00000 n 0000674900 00000 n 0000674984 00000 n 0000675068 00000 n 0000675152 00000 n 0000675235 00000 n 0000675319 00000 n 0000675403 00000 n 0000675487 00000 n 0000675571 00000 n 0000675655 00000 n 0000675739 00000 n 0000735259 00000 n 0000675823 00000 n 0000675922 00000 n 0000676003 00000 n 0000676117 00000 n 0000676220 00000 n 0000676457 00000 n 0000676544 00000 n 0000676647 00000 n 0000676800 00000 n 0000676884 00000 n 0000676984 00000 n 0000677083 00000 n 0000677215 00000 n 0000677323 00000 n 0000677459 00000 n 0000677560 00000 n 0000677724 00000 n 0000677822 00000 n 0000677907 00000 n 0000678016 00000 n 0000678124 00000 n 0000678250 00000 n 0000678357 00000 n 0000678617 00000 n 0000678709 00000 n 0000678829 00000 n 0000678940 00000 n 0000679051 00000 n 0000679162 00000 n 0000679274 00000 n 0000679364 00000 n 0000679534 00000 n 0000679622 00000 n 0000679736 00000 n 0000679862 00000 n 0000679976 00000 n 0000680094 00000 n 0000680218 00000 n 0000680320 00000 n 0000680435 00000 n 0000680544 00000 n 0000680663 00000 n 0000680772 00000 n 0000680878 00000 n 0000680991 00000 n 0000681100 00000 n 0000681220 00000 n 0000681325 00000 n 0000681427 00000 n 0000681538 00000 n 0000681650 00000 n 0000681760 00000 n 0000681870 00000 n 0000681979 00000 n 0000682080 00000 n 0000682244 00000 n 0000682348 00000 n 0000682469 00000 n 0000682597 00000 n 0000682726 00000 n 0000682853 00000 n 0000682978 00000 n 0000683077 00000 n 0000683187 00000 n 0000683296 00000 n 0000683388 00000 n 0000683574 00000 n 0000683666 00000 n 0000683772 00000 n 0000683879 00000 n 0000683989 00000 n 0000684096 00000 n 0000684201 00000 n 0000684307 00000 n 0000684416 00000 n 0000684524 00000 n 0000684630 00000 n 0000684738 00000 n 0000684848 00000 n 0000684958 00000 n 0000685074 00000 n 0000685185 00000 n 0000685296 00000 n 0000685405 00000 n 0000685515 00000 n 0000685628 00000 n 0000685737 00000 n 0000685846 00000 n 0000685963 00000 n 0000686060 00000 n 0000686248 00000 n 0000686357 00000 n 0000686472 00000 n 0000686582 00000 n 0000686692 00000 n 0000686802 00000 n 0000686914 00000 n 0000687015 00000 n 0000687123 00000 n 0000687226 00000 n 0000687331 00000 n 0000687432 00000 n 0000687522 00000 n 0000687683 00000 n 0000687781 00000 n 0000687884 00000 n 0000687989 00000 n 0000688102 00000 n 0000688226 00000 n 0000688352 00000 n 0000688463 00000 n 0000688560 00000 n 0000688751 00000 n 0000688850 00000 n 0000688970 00000 n 0000689089 00000 n 0000689200 00000 n 0000689317 00000 n 0000689410 00000 n 0000689604 00000 n 0000689699 00000 n 0000689813 00000 n 0000689942 00000 n 0000690057 00000 n 0000690177 00000 n 0000690302 00000 n 0000690422 00000 n 0000690543 00000 n 0000690668 00000 n 0000690788 00000 n 0000690889 00000 n 0000691047 00000 n 0000691147 00000 n 0000691262 00000 n 0000691374 00000 n 0000691481 00000 n 0000691592 00000 n 0000691706 00000 n 0000691803 00000 n 0000691967 00000 n 0000692074 00000 n 0000692184 00000 n 0000692290 00000 n 0000692398 00000 n 0000692515 00000 n 0000692626 00000 n 0000692741 00000 n 0000692858 00000 n 0000692978 00000 n 0000693094 00000 n 0000693208 00000 n 0000693304 00000 n 0000693450 00000 n 0000693551 00000 n 0000693817 00000 n 0000693941 00000 n 0000694092 00000 n 0000694182 00000 n 0000694293 00000 n 0000694458 00000 n 0000694564 00000 n 0000694675 00000 n 0000694761 00000 n 0000694919 00000 n 0000695009 00000 n 0000695120 00000 n 0000695285 00000 n 0000695391 00000 n 0000695502 00000 n 0000695588 00000 n 0000695734 00000 n 0000695824 00000 n 0000695935 00000 n 0000696100 00000 n 0000696206 00000 n 0000696317 00000 n 0000696447 00000 n 0000696532 00000 n 0000696633 00000 n 0000696733 00000 n 0000696878 00000 n 0000696968 00000 n 0000697079 00000 n 0000697244 00000 n 0000697350 00000 n 0000697461 00000 n 0000697607 00000 n 0000697676 00000 n 0000697773 00000 n 0000697919 00000 n 0000698009 00000 n 0000698120 00000 n 0000698285 00000 n 0000698391 00000 n 0000698502 00000 n 0000698588 00000 n 0000698745 00000 n 0000698835 00000 n 0000698946 00000 n 0000699111 00000 n 0000699217 00000 n 0000699328 00000 n 0000699458 00000 n 0000699549 00000 n 0000699650 00000 n 0000699750 00000 n 0000699907 00000 n 0000699997 00000 n 0000700108 00000 n 0000700273 00000 n 0000700379 00000 n 0000700490 00000 n 0000700620 00000 n 0000700711 00000 n 0000700812 00000 n 0000700912 00000 n 0000701043 00000 n 0000701133 00000 n 0000701246 00000 n 0000701357 00000 n 0000701522 00000 n 0000701628 00000 n 0000701739 00000 n 0000701869 00000 n 0000701969 00000 n 0000702062 00000 n 0000702151 00000 n 0000702266 00000 n 0000702377 00000 n 0000702498 00000 n 0000702612 00000 n 0000702719 00000 n 0000702831 00000 n 0000702941 00000 n 0000703045 00000 n 0000703188 00000 n 0000703337 00000 n 0000703414 00000 n 0000703500 00000 n 0000703603 00000 n 0000703737 00000 n 0000703855 00000 n 0000703997 00000 n 0000704092 00000 n 0000704172 00000 n 0000704253 00000 n 0000704364 00000 n 0000704482 00000 n 0000704588 00000 n 0000704685 00000 n 0000704791 00000 n 0000704888 00000 n 0000704982 00000 n 0000705110 00000 n 0000705183 00000 n 0000705274 00000 n 0000705365 00000 n 0000705450 00000 n 0000705538 00000 n 0000705629 00000 n 0000705714 00000 n 0000705799 00000 n 0000705899 00000 n 0000706029 00000 n 0000706129 00000 n 0000706227 00000 n 0000706372 00000 n 0000706476 00000 n 0000706583 00000 n 0000706692 00000 n 0000706815 00000 n 0000706940 00000 n 0000707092 00000 n 0000707223 00000 n 0000707326 00000 n 0000707439 00000 n 0000707548 00000 n 0000707684 00000 n 0000707775 00000 n 0000707887 00000 n 0000707973 00000 n 0000708064 00000 n 0000708164 00000 n 0000708255 00000 n 0000708343 00000 n 0000708465 00000 n 0000708598 00000 n 0000708705 00000 n 0000708853 00000 n 0000708953 00000 n 0000709048 00000 n 0000709134 00000 n 0000709216 00000 n 0000709311 00000 n 0000709406 00000 n 0000709500 00000 n 0000709594 00000 n 0000709689 00000 n 0000709784 00000 n 0000709879 00000 n 0000709973 00000 n 0000710067 00000 n 0000710161 00000 n 0000710255 00000 n 0000710349 00000 n 0000710443 00000 n 0000710538 00000 n 0000710633 00000 n 0000710727 00000 n 0000710821 00000 n 0000710915 00000 n 0000711009 00000 n 0000711104 00000 n 0000711199 00000 n 0000711294 00000 n 0000711389 00000 n 0000711484 00000 n 0000711579 00000 n 0000711674 00000 n 0000711769 00000 n 0000711864 00000 n 0000711959 00000 n 0000712054 00000 n 0000712149 00000 n 0000712244 00000 n 0000712339 00000 n 0000712434 00000 n 0000712529 00000 n 0000712624 00000 n 0000712719 00000 n 0000712814 00000 n 0000712909 00000 n 0000713004 00000 n 0000713099 00000 n 0000713194 00000 n 0000713289 00000 n 0000713384 00000 n 0000713479 00000 n 0000713574 00000 n 0000713669 00000 n 0000713764 00000 n 0000713859 00000 n 0000713954 00000 n 0000714049 00000 n 0000714144 00000 n 0000714239 00000 n 0000714334 00000 n 0000714429 00000 n 0000714524 00000 n 0000714619 00000 n 0000714714 00000 n 0000714809 00000 n 0000714904 00000 n 0000714999 00000 n 0000715094 00000 n 0000715189 00000 n 0000715284 00000 n 0000715379 00000 n 0000715474 00000 n 0000715569 00000 n 0000715664 00000 n 0000715759 00000 n 0000715854 00000 n 0000715949 00000 n 0000716044 00000 n 0000716139 00000 n 0000716234 00000 n 0000716329 00000 n 0000716424 00000 n 0000716519 00000 n 0000716629 00000 n 0000716732 00000 n 0000716815 00000 n 0000716948 00000 n 0000717087 00000 n 0000717190 00000 n 0000717287 00000 n 0000717403 00000 n 0000717500 00000 n 0000717621 00000 n 0000717727 00000 n 0000717825 00000 n 0000717928 00000 n 0000718025 00000 n 0000718128 00000 n 0000718238 00000 n 0000718332 00000 n 0000718423 00000 n 0000718583 00000 n 0000718740 00000 n 0000718835 00000 n 0000718924 00000 n 0000719001 00000 n 0000719075 00000 n 0000719155 00000 n 0000719247 00000 n 0000719360 00000 n 0000719442 00000 n 0000719542 00000 n 0000719637 00000 n 0000719740 00000 n 0000719822 00000 n 0000719898 00000 n 0000719986 00000 n 0000720090 00000 n 0000720184 00000 n 0000720270 00000 n 0000720356 00000 n 0000720445 00000 n 0000720534 00000 n 0000720635 00000 n 0000720726 00000 n 0000720833 00000 n 0000720987 00000 n 0000721073 00000 n 0000721153 00000 n 0000721265 00000 n 0000721365 00000 n 0000721465 00000 n 0000721569 00000 n 0000721693 00000 n 0000721763 00000 n 0000721864 00000 n 0000721986 00000 n 0000722117 00000 n 0000722233 00000 n 0000722355 00000 n 0000722444 00000 n 0000722547 00000 n 0000722654 00000 n 0000722754 00000 n 0000722851 00000 n 0000722958 00000 n 0000723050 00000 n 0000723169 00000 n 0000723282 00000 n 0000723386 00000 n 0000723481 00000 n 0000723561 00000 n 0000723644 00000 n 0000723760 00000 n 0000723879 00000 n 0000723992 00000 n 0000724071 00000 n 0000724187 00000 n 0000724290 00000 n 0000724402 00000 n 0000724548 00000 n 0000724670 00000 n 0000724801 00000 n 0000724935 00000 n 0000725038 00000 n 0000725184 00000 n 0000725315 00000 n 0000725415 00000 n 0000725515 00000 n 0000725639 00000 n 0000725749 00000 n 0000735315 00000 n trailer << /Root 2 0 R /Info 4 0 R /ID [<92D81592BA61C3046578FD0184924352> <92D81592BA61C3046578FD0184924352>] /Size 3010 >> startxref 735356 %%EOF cl-sql-6.7.2/doc/schemas.xml0000644000175000017500000000232510667176647014673 0ustar kevinkevin cl-sql-6.7.2/doc/ref-fdml.xml0000644000175000017500000023661210667176647014754 0ustar kevinkevin %myents; ]> Functional Data Manipulation Language (FDML) The functional data manipulation interface provided by &clsql; includes functions for inserting, updating and deleting records in existing database tables and executing SQL queries and statements with the results of queries returned as Lisp types. SQL statements expressed as strings may be executed with the query and execute-command functions. The select function, on the other hand, allows for the construction of queries in Lisp using the symbolic SQL syntax. Finally, iterative manipulation of query results is supported by do-query, map-query and an extended clause for the loop macro. *CACHE-TABLE-QUERIES-DEFAULT* *CACHE-TABLE-QUERIES-DEFAULT* Specifies the default behaviour for caching of attribute types. Variable Value Type A valid argument to the action parameter of cache-table-queries, i.e. one of &t; &nil; :flush . Initial Value nil Description Specifies the default behaivour for caching of attribute types. Meaningful values are &t;, &nil; and :flush as described for the action argument to cache-table-queries. Examples None. Affected By None. See Also cache-table-queries Notes None. CACHE-TABLE-QUERIES CACHE-TABLE-QUERIES Control the caching of table attribute types. Function Syntax cache-table-queries table &key action database => Arguments and Values table A string representing a database table, &t; or :default. action &t;, &nil; or :flush. database A database object. This will default to the value of *default-database*. Description Controls the caching of attribute type information on the table specified by table in database which defaults to *default-database*. action specifies the caching behaviour to adopt. If its value is &t; then attribute type information is cached whereas if its value is &nil; then attribute type information is not cached. If action is :flush then all existing type information in the cache for table is removed, but caching is still enabled. table may be a string representing a table for which the caching action is to be taken while the caching action is applied to all tables if table is &t;. Alternatively, when table is :default, the default caching action specified by *cache-table-queries-default* is applied to all tables for which a caching action has not been explicitly set. Examples (setf *cache-table-queries-default* t) => T (create-table [foo] '(([id] integer) ([height] float) ([name] (string 24)) ([comments] varchar))) => (cache-table-queries "foo") => (list-attribute-types "foo") => (("id" :INT4 4 NIL 1) ("height" :FLOAT8 8 NIL 1) ("name" :BPCHAR 24 NIL 1) ("comments" :VARCHAR 255 NIL 1)) (drop-table "foo") => (create-table [foo] '(([id] integer) ([height] float) ([name] (string 36)) ([comments] (string 100)))) => (cache-table-queries "foo" :action :flush) => (list-attribute-types "foo") => (("id" :INT4 4 NIL 1) ("height" :FLOAT8 8 NIL 1) ("name" :BPCHAR 36 NIL 1) ("comments" :BPCHAR 100 NIL 1)) Side Effects The internal attribute cache for database is modified. Affected by *cache-table-queries-default* Exceptional Situations None. See Also *cache-table-queries-default* Notes None. INSERT-RECORDS INSERT-RECORDS Insert tuples of data into a database table. Function Syntax insert-records &key into attributes values av-pairs query database => Arguments and Values into A string, symbol or symbolic SQL expression representing the name of a table existing in database. attributes A list of attribute identifiers or &nil;. values A list of attribute values or &nil;. av-pairs A list of attribute identifier/value pairs or &nil;. query A query expression or &nil;. database A database object. This will default to the value of *default-database*. Description Inserts records into the table specified by into in database which defaults to *default-database*. There are five ways of specifying the values inserted into each row. In the first values contains a list of values to insert and attributes, av-pairs and query are &nil;. This can be used when values are supplied for all attributes in into. In the second, attributes is a list of column names, values is a corresponding list of values and av-pairs and query are &nil;. In the third, attributes, values and query are &nil; and av-pairs is an alist of (attribute value) pairs. In the fourth, values, av-pairs and attributes are &nil; and query is a symbolic SQL query expression in which the selected columns also exist in into. In the fifth method, values and av-pairs are nil and attributes is a list of column names and query is a symbolic SQL query expression which returns values for the specified columns. Examples (select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11] :field-names nil) => NIL (insert-records :into [employee] :attributes '(emplid groupid first_name last_name email ecompanyid managerid) :values '(11 1 "Yuri" "Gagarin" "gagarin@soviet.org" 1 1)) => (select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11] :field-names nil) => (("Yuri" "Gagarin" "gagarin@soviet.org")) Side Effects Modifications are made to the underlying database. Affected by None. Exceptional Situations An error of type sql-database-data-error is signalled if table is not an existing table in database or if the specified attributes are not found. See Also update-records delete-records Notes None. UPDATE-RECORDS UPDATE-RECORDS Updates the values of existing records. Function Syntax update-records table &key attributes values av-pairs where database => Arguments and Values table A string, symbol or symbolic SQL expression representing the name of a table existing in database. attributes A list of attribute identifiers or &nil;. values A list of attribute values or &nil;. av-pairs A list of attribute identifier/value pairs or &nil;. where A symbolic SQL expression. database A database object. This will default to the value of *default-database*. Description Updates the attribute values of existing records satsifying the SQL expression where in the table specified by table in database which defaults to *default-database*. There are three ways of specifying the values to update for each row. In the first, values contains a list of values to use in the update and attributes and av-pairs are &nil;. This can be used when values are supplied for all attributes in table. In the second, attributes is a list of column names, values is a corresponding list of values and av-pairs is &nil;. In the third, attributes and values are &nil; and av-pairs is an alist of (attribute value) pairs. Examples (select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 1] :field-names nil) => (("Vladimir" "Lenin" "lenin@soviet.org")) (update-records [employee] :av-pairs'((first_name "Yuri") (last_name "Gagarin") (email "gagarin@soviet.org")) :where [= [emplid] 1]) => (select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 1] :field-names nil) => (("Yuri" "Gagarin" "gagarin@soviet.org")) Side Effects Modifications are made to the underlying database. Affected by None. Exceptional Situations An error of type sql-database-data-error is signalled if table is not an existing table in database, if the specified attributes are not found or if the SQL statement resulting from the symbolic expression where does not return a Boolean value. If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. See Also insert-records delete-records Notes None. DELETE-RECORDS DELETE-RECORDS Delete records from a database table. Function Syntax delete-records &key from where database => Arguments and Values from A string, symbol or symbolic SQL expression representing the name of a table existing in database. where A symbolic SQL expression. database A database object. This will default to the value of *default-database*. Description Deletes records satisfying the SQL expression where from the table specified by from in database specifies a database which defaults to *default-database*. Examples (select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11] :field-names nil) => (("Yuri" "Gagarin" "gagarin@soviet.org")) (delete-records :from [employee] :where [= [emplid] 11]) => (select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11] :field-names nil) => NIL Side Effects Modifications are made to the underlying database. Affected by None. Exceptional Situations An error of type sql-database-data-error is signalled if from is not an existing table in database or if the SQL statement resulting from the symbolic expression where does not return a Boolean value. See Also insert-records update-records Notes None. EXECUTE-COMMAND EXECUTE-COMMAND Execute an SQL command which returns no values. Generic Function Syntax execute-command sql-expression &key database => Arguments and Values sql-expression An sql expression that represents an SQL statement which will return no values. database A database object. This will default to the value of *default-database*. Description Executes the SQL command sql-expression, which may be a symbolic SQL expression or a string representing any SQL statement apart from a query, on the supplied database which defaults to *default-database*. Examples (execute-command "create table eventlog (time char(30),event char(70))") => (execute-command "create table eventlog (time char(30),event char(70))") >> >> While accessing database #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {480B2B6D}> >> with expression "create table eventlog (time char(30),event char(70))": >> Error NIL: ERROR: amcreate: eventlog relation already exists >> has occurred. >> >> Restarts: >> 0: [ABORT] Return to Top-Level. >> >> Debug (type H for help) >> >> (CLSQL-POSTGRESQL::|(PCL::FAST-METHOD DATABASE-EXECUTE-COMMAND (T POSTGRESQL-DATABASE))| >> #<unused-arg> >> #<unused-arg> >> #<unavailable-arg> >> #<unavailable-arg>) >> Source: (ERROR 'SQL-DATABASE-ERROR :DATABASE DATABASE :EXPRESSION ...) >> 0] 0 (execute-command "drop table eventlog") => Side Effects Whatever effects the execution of the SQL statement has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL statement leads to any errors, an error of type sql-database-error is signalled. See Also query Notes None. QUERY QUERY Execute an SQL query and return the tuples as a list. Generic Function Syntax query query-expression &key database result-types flatp field-names => result Arguments and Values query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set. database A database object. This will default to the value of *default-database*. flatp A Boolean whose default value is &nil;. result-types A field type specifier. The default is :auto;. The purpose of this argument is cause &clsql; to import SQL numeric fields into numeric Lisp objects rather than strings. This reduces the cost of allocating a temporary string and the &clsql; users' inconvenience of converting number strings into number objects. A value of :auto causes &clsql; to automatically convert SQL fields into a numeric format where applicable. The default value of &nil; causes all fields to be returned as strings regardless of the SQL type. Otherwise a list is expected which has a element for each field that specifies the conversion. Valid type identifiers are: :int Field is imported as a signed integer, from 8-bits to 64-bits depending upon the field type. :double Field is imported as a double-float number. t Field is imported as a string. If the list is shorter than the number of fields, the a value of t is assumed for the field. If the list is longer than the number of fields, the extra elements are ignored. field-names A boolean with a default value of &t;. When &t;, this function returns a second value of a list of field names. When &nil;, this function only returns one value - the list of rows. result A list representing the result set obtained. For each tuple in the result set, there is an element in this list, which is itself a list of all the attribute values in the tuple. Description Executes the SQL query expression query-expression, which may be an SQL expression or a string, on the supplied database which defaults to *default-database*. result-types is a list of symbols which specifies the lisp type for each field returned by query-expression. If result-types is &nil; all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field. field-names is &t; by default which means that the second value returned is a list of strings representing the columns selected by query-expression. If field-names is &nil;, the list of column names is not returned as a second value. flatp has a default value of &nil; which means that the results are returned as a list of lists.If FLATP is &t; and only one result is returned for each record selected by query-expression, the results are returned as elements of a list. Examples (query "select emplid,first_name,last_name,height from employee where emplid = 1") => ((1 "Vladimir" "Lenin" 1.5564661d0)), ("emplid" "first_name" "last_name" "height") (query "select emplid,first_name,last_name,height from employee where emplid = 1" :field-names nil) => ((1 "Vladimir" "Lenin" 1.5564661d0)) (query "select emplid,first_name,last_name,height from employee where emplid = 1" :field-names nil :result-types nil) => (("1" "Vladimir" "Lenin" "1.5564661")) (query "select emplid,first_name,last_name,height from employee where emplid = 1" :field-names nil :result-types '(:int t t :double)) => ((1 "Vladimir" "Lenin" 1.5564661)) (query "select last_name from employee where emplid > 5" :flatp t) => ("Andropov" "Chernenko" "Gorbachev" "Yeltsin" "Putin"), ("last_name") (query "select last_name from employee where emplid > 10" :flatp t :field-names nil) => NIL Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. See Also execute-command print-query do-query map-query loop select Notes The field-names and result-types keyword arguments are a &clsql; extension. PRINT-QUERY PRINT-QUERY Prints a tabular report of query results. Function Syntax print-query query-expression &key titles formats sizes stream database => Arguments and Values query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set. database A database object. This will default to the value of *default-database*. titles A list of strings or &nil; which is the default value. formats A list of strings, &nil; or &t; which is the default value. sizes A list of numbers, &nil; or &t; which is the default value. stream An output stream or &t; which is the default value. Description Prints a tabular report of the results returned by the SQL query query-expression, which may be a symbolic SQL expression or a string, in database which defaults to *default-database*. The report is printed onto stream which has a default value of &t; which means that *standard-output* is used. The title argument, which defaults to &nil;, allows the specification of a list of strings to use as column titles in the tabular output. sizes accepts a list of column sizes, one for each column selected by query-expression, to use in formatting the tabular report. The default value of &t; means that minimum sizes are computed. formats is a list of format strings to be used for printing each column selected by query-expression. The default value of formats is &t; meaning that ~A is used to format all columns or ~VA if column sizes are used. Examples (print-query [select [emplid] [first-name] [last-name] [email] :from [employee] :where [< [emplid] 5]] :titles '("ID" "FORENAME" "SURNAME" "EMAIL")) ID FORENAME SURNAME EMAIL 1 Vladimir Lenin lenin@soviet.org 2 Josef Stalin stalin@soviet.org 3 Leon Trotsky trotsky@soviet.org 4 Nikita Kruschev kruschev@soviet.org => (print-query "select emplid,first_name,last_name,email from employee where emplid >= 5" :titles '("ID" "FORENAME" "SURNAME" "EMAIL")) ID FORENAME SURNAME EMAIL 5 Leonid Brezhnev brezhnev@soviet.org 6 Yuri Andropov andropov@soviet.org 7 Konstantin Chernenko chernenko@soviet.org 8 Mikhail Gorbachev gorbachev@soviet.org 9 Boris Yeltsin yeltsin@soviet.org 10 Vladimir Putin putin@soviet.org => Side Effects None. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. See Also query do-query map-query loop select Notes None. SELECT SELECT Executes a query given the supplied constraints. Function Syntax select &rest identifiers &key all distinct from group-by having limit offset order-by set-operation where result-types field-names flatp refresh caching database => result Arguments and Values identifiers A set of sql expressions each of which indicates a column to query. all A Boolean. distinct A Boolean. from One or more SQL expression representing tables. group-by An SQL expression. having An SQL expression. limit A non-negative integer. offset A non-negative integer. order-by An SQL expression. set-operation An SQL expression. where An SQL expression. database A database object. This will default to the value of *default-database*. flatp A Boolean whose default value is &nil;. result-types A field type specifier. The default is :auto. The purpose of this argument is cause &clsql; to import SQL numeric fields into numeric Lisp objects rather than strings. This reduces the cost of allocating a temporary string and the &clsql; users' inconvenience of converting number strings into number objects. A value of :auto causes &clsql; to automatically convert SQL fields into a numeric format where applicable. The default value of &nil; causes all fields to be returned as strings regardless of the SQL type. Otherwise a list is expected which has a element for each field that specifies the conversion. Valid type identifiers are: :int Field is imported as a signed integer, from 8-bits to 64-bits depending upon the field type. :double Field is imported as a double-float number. t Field is imported as a string. If the list is shorter than the number of fields, the a value of t is assumed for the field. If the list is longer than the number of fields, the extra elements are ignored. field-names A boolean with a default value of &t;. When &t;, this function returns a second value of a list of field names. When &nil;, this function only returns one value - the list of rows. refresh This value is only considered when CLOS objects are being selected. A boolean with a default value of &nil;. When the value of the caching keyword is &t;, a second equivalent select call will return the same view class instance objects. When refresh is &t;, then slots of the existing instances are updated as necessary. In such cases, you may wish to override the hook instance-refresh. caching This value is only considered when CLOS objects are being selected. A boolean with a default value of *default-caching*. &clsql; caches objects in accordance with the &commonsql; interface: a second equivalent select call will return the same view class instance objects. result A list representing the result set obtained. For each tuple in the result set, there is an element in this list, which is itself a list of all the attribute values in the tuple. Description Executes a query on database, which has a default value of *default-database*, specified by the SQL expressions supplied using the remaining arguments in args. The select function can be used to generate queries in both functional and object oriented contexts. In the functional case, the required arguments specify the columns selected by the query and may be symbolic SQL expressions or strings representing attribute identifiers. Type modified identifiers indicate that the values selected from the specified column are converted to the specified lisp type. The keyword arguments all, distinct, from, group-by, having, limit, offset, order-by, set-operation and where are used to specify, using the symbolic SQL syntax, the corresponding components of the SQL query generated by the call to select. result-types is a list of symbols which specifies the lisp type for each field returned by the query. If result-types is &nil; all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field. field-names is &t; by default which means that the second value returned is a list of strings representing the columns selected by the query. If field-names is &nil;, the list of column names is not returned as a second value. In the object oriented case, the required arguments to select are symbols denoting View Classes which specify the database tables to query. In this case, select returns a list of View Class instances whose slots are set from the attribute values of the records in the specified table. Slot-value is a legal operator which can be employed as part of the symbolic SQL syntax used in the where keyword argument to select. refresh is &nil; by default which means that the View Class instances returned are retrieved from a cache if an equivalent call to select has previously been issued. If refresh is true, the View Class instances returned are updated as necessary from the database and the generic function instance-refreshed is called to perform any necessary operations on the updated instances. In both object oriented and functional contexts, flatp has a default value of &nil; which means that the results are returned as a list of lists. If flatp is t and only one result is returned for each record selected in the query, the results are returned as elements of a list. Examples (select [first-name] :from [employee] :flatp t :distinct t :field-names nil :result-types nil :order-by [first-name]) => ("Boris" "Josef" "Konstantin" "Leon" "Leonid" "Mikhail" "Nikita" "Vladimir" "Yuri") (select [first-name] [count [*]] :from [employee] :result-types nil :group-by [first-name] :order-by [first-name] :field-names nil) => (("Boris" "1") ("Josef" "1") ("Konstantin" "1") ("Leon" "1") ("Leonid" "1") ("Mikhail" "1") ("Nikita" "1") ("Vladimir" "2") ("Yuri" "1")) (select [last-name] :from [employee] :where [like [email] "%org"] :order-by [last-name] :field-names nil :result-types nil :flatp t) => ("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Lenin" "Putin" "Stalin" "Trotsky" "Yeltsin") (select [max [emplid]] :from [employee] :flatp t :field-names nil :result-types :auto) => (10) (select [avg [height]] :from [employee] :flatp t :field-names nil) => (1.58999584d0) (select [emplid] [last-name] :from [employee] :where [= [emplid] 1]) => ((1 "Lenin")), ("emplid" "last_name") (select [emplid :string] :from [employee] :where [= 1 [emplid]] :field-names nil :flatp t) => ("1") (select [emplid] :from [employee] :order-by [emplid] :where [not [between [* [emplid] 10] [* 5 10] [* 10 10]]] :field-names nil :flatp t) => (1 2 3 4) (select [emplid] :from [employee] :where [in [emplid] '(1 2 3 4)] :flatp t :order-by [emplid] :field-names nil) => (1 2 3 4) (select [emplid] :from [employee] :order-by [emplid] :limit 5 :offset 3 :field-names nil :flatp t) => (4 5 6 7 8) (select [first-name] [last-name] :from [employee] :field-names nil :order-by '(([first-name] :asc) ([last-name] :desc))) => (("Boris" "Yeltsin") ("Josef" "Stalin") ("Konstantin" "Chernenko") ("Leon" "Trotsky") ("Leonid" "Brezhnev") ("Mikhail" "Gorbachev") ("Nikita" "Kruschev") ("Vladimir" "Putin") ("Vladimir" "Lenin") ("Yuri" "Andropov")) (select [last-name] :from [employee] :set-operation [union [select [first-name] :from [employee] :order-by [last-name]]] :flatp t :result-types nil :field-names nil) => ("Andropov" "Boris" "Brezhnev" "Chernenko" "Gorbachev" "Josef" "Konstantin" "Kruschev" "Lenin" "Leon" "Leonid" "Mikhail" "Nikita" "Putin" "Stalin" "Trotsky" "Vladimir" "Yeltsin" "Yuri") Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. See Also query print-query do-query map-query loop instance-refreshed Notes The select function is actually implemented in &clsql; with a single &rest parameter (which is subsequently destructured) rather than the keyword parameters presented here for the purposes of exposition. This means that incorrect or missing keywords or values may not trigger errors in the way that they would if select had been defined using keyword arguments. The field-names and result-types keyword arguments are a &clsql; extension. select is common across the functional and object-oriented data manipulation languages. DO-QUERY DO-QUERY Iterate over all the tuples of a query. Macro Syntax do-query ((&rest args) query-expression &key database result-types &body body => result Arguments and Values args A list of variable names. query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set, where each tuple has as many attributes as function takes arguments. database A database object. This will default to *default-database*. result-types A field type specifier. The default is &nil;. See query for the semantics of this argument. body A body of Lisp code, like in a destructuring-bind form. result The result of executing body. Description Repeatedly executes body within a binding of args on the fields of each row selected by the SQL query query-expression, which may be a string or a symbolic SQL expression, in database which defaults to *default-database*. The body of code is executed in a block named nil which may be returned from prematurely via return or return-from. In this case the result of evaluating the do-query form will be the one supplied to return or return-from. Otherwise the result will be nil. The body of code appears also is if wrapped in a destructuring-bind form, thus allowing declarations at the start of the body, especially those pertaining to the bindings of the variables named in args. result-types is a list of symbols which specifies the lisp type for each field returned by query-expression. If result-types is &nil; all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field. query-expression may be an object query (i.e., the selection arguments refer to View Classes), in which case args are bound to the tuples of View Class instances returned by the object oriented query. Examples (do-query ((salary name) "select salary,name from simple") (format t "~30A gets $~2,5$~%" name (read-from-string salary))) >> Mai, Pierre gets $10000.00 >> Hacker, Random J. gets $08000.50 => NIL (do-query ((salary name) "select salary,name from simple") (return (cons salary name))) => ("10000.00" . "Mai, Pierre") (let ((result '())) (do-query ((name) [select [last-name] :from [employee] :order-by [last-name]]) (push name result)) result) => ("Yeltsin" "Trotsky" "Stalin" "Putin" "Lenin" "Kruschev" "Gorbachev" "Chernenko" "Brezhnev" "Andropov") (let ((result '())) (do-query ((e) [select 'employee :order-by [last-name]]) (push (slot-value e 'last-name) result)) result) => ("Yeltsin" "Trotsky" "Stalin" "Putin" "Lenin" "Kruschev" "Gorbachev" "Chernenko" "Brezhnev" "Andropov") Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. If the number of variable names in args and the number of attributes in the tuples in the result set don't match up, an error is signalled. See Also query map-query print-query loop select Notes The result-types keyword argument is a &clsql; extension. do-query is common across the functional and object-oriented data manipulation languages. LOOP LOOP Extension to Common Lisp Loop to iterate over all the tuples of a query via a loop clause. Loop Clause Syntax {as | for} var [type-spec] being {each | the} {record | records | tuple | tuples} {in | of} query [from database] Arguments and Values var A d-var-spec, as defined in the grammar for loop-clauses in the ANSI Standard for Common Lisp. This allows for the usual loop-style destructuring. type-spec An optional type-spec either simple or destructured, as defined in the grammar for loop-clauses in the ANSI Standard for Common Lisp. query An sql expression that represents an SQL query which is expected to return a (possibly empty) result set, where each tuple has as many attributes as function takes arguments. database An optional database object. This will default to the value of *default-database*. Description This clause is an iteration driver for loop, that binds the given variable (possibly destructured) to the consecutive tuples (which are represented as lists of attribute values) in the result set returned by executing the SQL query expression on the database specified. query may be an object query (i.e., the selection arguments refer to View Classes), in which case the supplied variable is bound to the tuples of View Class instances returned by the object oriented query. Examples (defvar *my-db* (connect '("dent" "newesim" "dent" "dent")) "My database" => *MY-DB* (loop with time-graph = (make-hash-table :test #'equal) with event-graph = (make-hash-table :test #'equal) for (time event) being the tuples of "select time,event from log" from *my-db* do (incf (gethash time time-graph 0)) (incf (gethash event event-graph 0)) finally (flet ((show-graph (k v) (format t "~40A => ~5D~%" k v))) (format t "~&Time-Graph:~%===========~%") (maphash #'show-graph time-graph) (format t "~&~%Event-Graph:~%============~%") (maphash #'show-graph event-graph)) (return (values time-graph event-graph))) >> Time-Graph: >> =========== >> D => 53000 >> X => 3 >> test-me => 3000 >> >> Event-Graph: >> ============ >> CLOS Benchmark entry. => 9000 >> Demo Text... => 3 >> doit-text => 3000 >> C Benchmark entry. => 12000 >> CLOS Benchmark entry => 32000 => #<EQUAL hash table, 3 entries {48350A1D}> => #<EQUAL hash table, 5 entries {48350FCD}> (loop for (forename surname) being each tuple in [select [first-name] [last-name] :from [employee] :order-by [last-name]] collect (concatenate 'string forename " " surname)) => ("Yuri Andropov" "Leonid Brezhnev" "Konstantin Chernenko" "Mikhail Gorbachev" "Nikita Kruschev" "Vladimir Lenin" "Vladimir Putin" "Josef Stalin" "Leon Trotsky" "Boris Yeltsin") (loop for (e) being the records in [select 'employee :where [< [emplid] 4] :order-by [emplid]] collect (slot-value e 'last-name)) => ("Lenin" "Stalin" "Trotsky") Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. Otherwise, any of the exceptional situations of loop applies. See Also query map-query do-query print-query select Notes The database loop keyword is a &clsql; extension. The extended loop syntax is common across the functional and object-oriented data manipulation languages. MAP-QUERY MAP-QUERY Map a function over all the tuples from a query Function Syntax map-query output-type-spec function query-expression &key database result-types => result Arguments and Values output-type-spec A sequence type specifier or nil. function A function designator. function takes a single argument which is the atom value for a query single with a single column or is a list of values for a multi-column query. query-expression An sql expression that represents an SQL query which is expected to return a (possibly empty) result set. database A database object. This will default to the value of *default-database*. result-types A field type specifier. The default is &nil;. See query for the semantics of this argument. result If output-type-spec is a type specifier other than nil, then a sequence of the type it denotes. Otherwise nil is returned. Description Applies function to the successive tuples in the result set returned by executing the SQL query-expression. If the output-type-spec is nil, then the result of each application of function is discarded, and map-query returns nil. Otherwise the result of each successive application of function is collected in a sequence of type output-type-spec, where the jths element is the result of applying function to the attributes of the jths tuple in the result set. The collected sequence is the result of the call to map-query. If the output-type-spec is a subtype of list, the result will be a list. If the result-type is a subtype of vector, then if the implementation can determine the element type specified for the result-type, the element type of the resulting array is the result of upgrading that element type; or, if the implementation can determine that the element type is unspecified (or *), the element type of the resulting array is t; otherwise, an error is signaled. If result-types is &nil; all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field. query-expression may be an object query (i.e., the selection arguments refer to View Classes), in which case the supplied function is applied to the tuples of View Class instances returned by the object oriented query. Examples (map-query 'list #'(lambda (tuple) (multiple-value-bind (salary name) tuple (declare (ignorable name)) (read-from-string salary))) "select salary,name from simple where salary > 8000") => (10000.0 8000.5) (map-query '(vector double-float) #'(lambda (tuple) (multiple-value-bind (salary name) tuple (declare (ignorable name)) (let ((*read-default-float-format* 'double-float)) (coerce (read-from-string salary) 'double-float)) "select salary,name from simple where salary > 8000"))) => #(10000.0d0 8000.5d0) (type-of *) => (SIMPLE-ARRAY DOUBLE-FLOAT (2)) (let (list) (values (map-query nil #'(lambda (tuple) (multiple-value-bind (salary name) tuple (push (cons name (read-from-string salary)) list)) "select salary,name from simple where salary > 8000")) list)) => NIL => (("Hacker, Random J." . 8000.5) ("Mai, Pierre" . 10000.0)) (map-query 'vector #'identity [select [last-name] :from [employee] :flatp t :order-by [last-name]]) => #("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Lenin" "Putin" "Stalin" "Trotsky" "Yeltsin") (map-query 'list #'identity [select [first-name] [last-name] :from [employee] :order-by [last-name]]) => (("Yuri" "Andropov") ("Leonid" "Brezhnev") ("Konstantin" "Chernenko") ("Mikhail" "Gorbachev") ("Nikita" "Kruschev") ("Vladimir" "Lenin") ("Vladimir" "Putin") ("Josef" "Stalin") ("Leon" "Trotsky") ("Boris" "Yeltsin")) (map-query 'list #'last-name [select 'employee :order-by [emplid]]) => ("Lenin" "Stalin" "Trotsky" "Kruschev" "Brezhnev" "Andropov" "Chernenko" "Gorbachev" "Yeltsin" "Putin") Side Effects Whatever effects the execution of the SQL query has on the underlying database, if any. Affected by None. Exceptional Situations If the execution of the SQL query leads to any errors, an error of type sql-database-error is signalled. An error of type type-error must be signaled if the output-type-spec is not a recognizable subtype of list, not a recognizable subtype of vector, and not nil. An error of type type-error should be signaled if output-type-spec specifies the number of elements and the size of the result set is different from that number. See Also query do-query print-query loop select Notes The result-types keyword argument is a &clsql; extension. map-query is common across the functional and object-oriented data manipulation languages. cl-sql-6.7.2/doc/fo.xsl0000644000175000017500000000033311251607553013640 0ustar kevinkevin cl-sql-6.7.2/doc/ref-clsql-sys.xml0000644000175000017500000000727310667176647015763 0ustar kevinkevin %myents; ]> <symbol>CLSQL-SYS</symbol> This part gives a reference to the symbols exported from the package CLSQL-SYS, which are not exported from CLSQL package.. These symbols are part of the interface for database back-ends, but not part of the normal user-interface of &clsql;. DATABASE-INITIALIZE-DATABASE-TYPE Back-end part of initialize-database-type. Generic Function Syntax database-initialize-database-type database-type => result Arguments and Values database-type A keyword indicating the database type to initialize. result Either t if the initialization succeeds or nil if it fails. Description This generic function implements the main part of the database type initialization performed by initialize-database-type. After initialize-database-type has checked that the given database type has not been initialized before, as indicated by *initialized-database-types*, it will call this function with the database type as it's sole parameter. Database back-ends are required to define a method on this generic function which is specialized via an eql-specializer to the keyword representing their database type. Database back-ends shall indicate successful initialization by returning t from their method, and nil otherwise. Methods for this generic function are allowed to signal errors of type clsql-error or subtypes thereof. They may also signal other types of conditions, if appropriate, but have to document this. Examples Side Effects All necessary side effects to initialize the database instance. Affected By None. Exceptional Situations Conditions of type clsql-error or other conditions may be signalled, depending on the database back-end. See Also initialize-database-type *initialized-database-types* Notes None. cl-sql-6.7.2/doc/html_chunk.xsl0000644000175000017500000000034410667176647015411 0ustar kevinkevin cl-sql-6.7.2/doc/html.xsl0000644000175000017500000000042110703552706014176 0ustar kevinkevin cl-sql-6.7.2/doc/ref-connect.xml0000644000175000017500000023775711616055736015464 0ustar kevinkevin %myents; ]> Connection and Initialisation This section describes the &clsql; interface for initialising database interfaces of different types, creating and destroying databases and connecting and disconnecting from databases. DATABASE DATABASE The super-type of all &clsql; databases Class Class Precedence List database standard-object t Description This class is the superclass of all &clsql; databases. The different database back-ends derive subclasses of this class to implement their databases. No instances of this class are ever created by &clsql;. *CONNECT-IF-EXISTS* *CONNECT-IF-EXISTS* Default value for the if-exists parameter of connect. Variable Value Type A valid argument to the if-exists parameter of connect, that is, one of :new :warn-new :error :warn-old :old . Initial Value :error Description The value of this variable is used in calls to connect as the default value of the if-exists parameter. See connect for the semantics of the valid values for this variable. Examples None. Affected By None. See Also connect Notes None. *DB-POOL-MAX-FREE-CONNECTIONS* *DB-POOL-MAX-FREE-CONNECTIONS* How many free connections should the connection pool try to keep. Parameter Value Type Integer Initial Value 4 Description Threshold of free-connections in the pool before we disconnect a database rather than returning it to the pool. NIL for no limit. This is really a heuristic that should, on avg keep the free connections about this size. This is not a hard limit, the number of connections in the pool may exceed this value. Examples (setf clsql-sys:*db-pool-max-free-connections* 2) Affected By None See Also connect disconnect Notes *DEFAULT-DATABASE* *DEFAULT-DATABASE* The default database object to use. Variable Value Type Any object of type database, or &nil; to indicate no default database. Initial Value &nil; Description Any function or macro in &clsql; that operates on a database uses the value of this variable as the default value for it's database parameter. The value of this parameter is changed by calls to connect, which sets *default-database* to the database object it returns. It is also changed by calls to disconnect, when the database object being disconnected is the same as the value of *default-database*. In this case disconnect sets *default-database* to the first database that remains in the list of active databases as returned by connected-databases, or &nil; if no further active databases exist. The user may change *default-database* at any time to a valid value of his choice. If the value of *default-database* is &nil;, then all calls to &clsql; functions on databases must provide a suitable database parameter, or an error will be signalled. Examples (connected-databases) => NIL (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48385F55}> (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {483868FD}> (connect '("dent" "newesim" "dent" "dent") :database-type :mysql :if-exists :new) => #<CLSQL-MYSQL:MYSQL-DATABASE {48387265}> *default-database* => #<CLSQL-MYSQL:MYSQL-DATABASE {48387265}> (disconnect) => T *default-database* => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {483868FD}> (disconnect) => T *default-database* => #<CLSQL-MYSQL:MYSQL-DATABASE {48385F55}> (disconnect) => T *default-database* => NIL (connected-databases) => NIL Affected By connect disconnect See Also connected-databases Notes This variable is intended to facilitate working with &clsql; in an interactive fashion at the top-level loop, and because of this, connect and disconnect provide some fairly complex behaviour to keep *default-database* set to useful values. Programmatic use of &clsql; should never depend on the value of *default-database* and should provide correct database objects via the database parameter to functions called. *DEFAULT-DATABASE-TYPE* *DEFAULT-DATABASE-TYPE* The default database type to use Variable Value Type Any keyword representing a valid database back-end of &clsql;, or &nil;. Initial Value &nil; Description The value of this variable is used in calls to initialize-database-type and connect as the default value of the database-type parameter. If the value of this variable is &nil;, then all calls to initialize-database-type or connect will have to specify the database-type to use, or a general-purpose error will be signalled. Examples (setf *default-database-type* :mysql) => :mysql (initialize-database-type) => t Affected By None. See Also intitialize-database-type Notes None. *INITIALIZED-DATABASE-TYPES* *INITIALIZED-DATABASE-TYPES* List of all initialized database types Variable Value Type A list of all initialized database types, each of which represented by it's corresponding keyword. Initial Value &nil; Description This variable is updated whenever initialize-database-type is called for a database type which hasn't already been initialized before, as determined by this variable. In that case the keyword representing the database type is pushed onto the list stored in *INITIALIZED-DATABASE-TYPES*. Attempts to modify the value of this variable will result in undefined behaviour. Examples (setf *default-database-type* :mysql) => :mysql (initialize-database-type) => t *initialized-database-types* => (:MYSQL) Affected By initialize-database-type See Also intitialize-database-type Notes Direct access to this variable is primarily provided because of compatibility with Harlequin's Common SQL. CONNECT CONNECT create a connection to a database. Function Syntax connect connection-spec &key if-exists database-type pool make-default => database Arguments and Values connection-spec A SQL backend specific connection specification supplied as a list or as a string. For the MySQL backend, this list includes an optional associative list of connection options. The options list is parsed and supplied to the MySQL API using mysql_options in between the calls to mysql_init and mysql_real_connect. if-exists This indicates the action to take if a connection to the same database exists already. See below for the legal values and actions. It defaults to the value of *connect-if-exists*. database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* pool A boolean flag. If &t;, acquire connection from a pool of open connections. If the pool is empty, a new connection is created. The default is &nil;. make-default A boolean flag. If &t;, *default-database* is set to the new connection, otherwise *default-database* is not changed. The default is &t;. database The database object representing the connection. Description This function takes a connection specification and a database type and creates a connection to the database specified by those. The type and structure of the connection specification depend on the database type. The parameter if-exists specifies what to do if a connection to the database specified exists already, which is checked by calling find-database on the database name returned by database-name-from-spec when called with the connection-spec and database-type parameters. The possible values of if-exists are: :new Go ahead and create a new connection. :warn-new This is just like :new, but also signals a warning of type clsql-exists-warning, indicating the old and newly created databases. :error This will cause connect to signal a correctable error of type clsql-exists-error. The user may choose to proceed, either by indicating that a new connection shall be created, via the restart create-new, or by indicating that the existing connection shall be used, via the restart use-old. :old This will cause connect to use an old connection if one exists. :warn-old This is just like :old, but also signals a warning of type clsql-exists-warning, indicating the old database used, via the slots old-db and new-db The database name of the returned database object will be the same under string= as that which would be returned by a call to database-name-from-spec with the given connection-spec and database-type parameters. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48036F6D}> (database-name *) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) >> In call to CONNECT: >> There is an existing connection #<CLSQL-MYSQL:MYSQL-DATABASE {48036F6D}> to database dent/newesim/dent. >> >> Restarts: >> 0: [CREATE-NEW] Create a new connection. >> 1: [USE-OLD ] Use the existing connection. >> 2: [ABORT ] Return to Top-Level. >> >> Debug (type H for help) >> >> (CONNECT ("dent" "newesim" "dent" "dent") :IF-EXISTS NIL :DATABASE-TYPE ...) >> Source: >> ; File: /prj/CLSQL/sql/sql.cl >> (RESTART-CASE (ERROR 'CLSQL-EXISTS-ERROR :OLD-DB OLD-DB) >> (CREATE-NEW NIL :REPORT "Create a new connection." >> (SETQ RESULT #)) >> (USE-OLD NIL :REPORT "Use the existing connection." >> (SETQ RESULT OLD-DB))) >> 0] 0 => #<CLSQL-MYSQL:MYSQL-DATABASE {480451F5}> Side Effects A database connection is established, and the resultant database object is registered, so as to appear in the list returned by connected-databases. *default-database* may be rebound to the created object. Affected by *default-database-type* *connect-if-exists* Exceptional Situations If the connection specification is not syntactically or semantically correct for the given database type, an error of type sql-user-error is signalled. If during the connection attempt an error is detected (e.g. because of permission problems, network trouble or any other cause), an error of type sql-database-error is signalled. If a connection to the database specified by connection-spec exists already, conditions are signalled according to the if-exists parameter, as described above. See Also connected-databases disconnect reconnect *connect-if-exists* find-database status Notes The pool and make-default keyword arguments to connect are &clsql; extensions. CONNECTED-DATABASES CONNECTED-DATABASES Return the list of active database objects. Function Syntax connected-databases => databases Arguments and Values databases The list of active database objects. Description This function returns the list of active database objects, i.e. all those database objects created by calls to connect, which have not been closed by calling disconnect on them. The consequences of modifying the list returned by connected-databases are undefined. Examples (connected-databases) => NIL (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {4830BC65}> (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {4830C5AD}> (connected-databases) => (#<CLSQL-MYSQL:MYSQL-DATABASE {4830C5AD}> #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {4830BC65}>) (disconnect) => T (connected-databases) => (#<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {4830BC65}>) (disconnect) => T (connected-databases) => NIL Side Effects None. Affected By connect disconnect Exceptional Situations None. See Also disconnect connect status find-database Notes None. DATABASE-NAME DATABASE-NAME Get the name of a database object Generic Function Syntax database-name database => name Arguments and Values database A database object, either of type database or of type closed-database. name A string describing the identity of the database to which this database object is connected to. Description This function returns the database name of the given database. The database name is a string which somehow describes the identity of the database to which this database object is or has been connected. The database name of a database object is determined at connect time, when a call to database-name-from-spec derives the database name from the connection specification passed to connect in the connection-spec parameter. The database name is used via find-database in connect to determine whether database connections to the specified database exist already. Usually the database name string will include indications of the host, database name, user, or port that where used during the connection attempt. The only important thing is that this string shall try to identify the database at the other end of the connection. Connection specifications parts like passwords and credentials shall not be used as part of the database name. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48391DCD}> (database-name *default-database*) => "dent/newesim/dent" (database-name-from-spec '(nil "template1" "dent" nil) :postgresql) => "/template1/dent" (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-name *default-database*) => "/template1/dent" (database-name-from-spec '("www.pmsf.de" "template1" "dent" nil) :postgresql) => "www.pmsf.de/template1/dent" Side Effects None. Affected By database-name-from-spec Exceptional Situations Will signal an error if the object passed as the database parameter is neither of type database nor of type closed-database. See Also connect find-database connected-databases disconnect status Notes None. DATABASE-NAME-FROM-SPEC DATABASE-NAME-FROM-SPEC Return the database name string corresponding to the given connection specification. Generic Function Syntax database-name-from-spec connection-spec database-type => name Arguments and Values connection-spec A connection specification, whose structure and interpretation are dependent on the database-type. database-type A database type specifier, i.e. a keyword. name A string denoting a database name. Description This generic function takes a connection specification and a database type and returns the database name of the database object that would be created had connect been called with the given connection specification and database types. This function is useful in determining a database name from the connection specification, since the way the connection specification is converted into a database name is dependent on the database type. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48391DCD}> (database-name *default-database*) => "dent/newesim/dent" (database-name-from-spec '(nil "template1" "dent" nil) :postgresql) => "/template1/dent" (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-name *default-database*) => "/template1/dent" (database-name-from-spec '("www.pmsf.de" "template1" "dent" nil) :postgresql) => "www.pmsf.de/template1/dent" (find-database "dent/newesim/dent") => #<CLSQL-MYSQL:MYSQL-DATABASE {484E91C5}> (find-database "/template1/dent") => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (find-database "www.pmsf.de/template1/dent" nil) => NIL (find-database **) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> Side Effects None. Affected by None. Exceptional Situations If the value of connection-spec is not a valid connection specification for the given database type, an error of type clsql-invalid-spec-error might be signalled. See Also connect Notes database-name-from-spec is a &clsql; extension. DATABASE-TYPE DATABASE-TYPE Get the type of a database object. Generic Function Syntax database-type DATABASE => type Arguments and Values database A database object, either of type database or of type closed-database. type A keyword symbol denoting a known database back-end. Description Returns the type of database. Examples (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-type *default-database*) => :postgresql Side Effects None. Affected by None. Exceptional Situations Will signal an error if the object passed as the database parameter is neither of type database nor of type closed-database. See Also connect find-database connected-databases disconnect status Notes database-type is a &clsql; extension. DISCONNECT DISCONNECT close a database connection Function Syntax disconnect &key database error => result Arguments and Values error A boolean flag indicating whether to signal an error if database is non-&nil; but cannot be found. database The database to disconnect, which defaults to the database indicated by *default-database*. result A Boolean indicating whether a connection was successfully disconnected. Description This function takes a database object as returned by connect, and closes the connection. If no matching database is found and error and database are both non-&nil; an error is signaled, otherwise &nil; is returned. If the database is from a pool it will be released to this pool. The status of the object passed is changed to closed after the disconnection succeeds, thereby preventing further use of the object as an argument to &clsql; functions, with the exception of database-name and database-type. If the user does pass a closed database to any other &clsql; function, an error of type sql-fatal-error is signalled. Examples (disconnect :database (find-database "dent/newesim/dent")) => T Side Effects The database object is removed from the list of connected databases as returned by connected-databases. If the database object passed is the same under eq as the value of *default-database*, then *default-database* is set to the first remaining database from connected-databases or to &nil; if no further active database exists. Non-pooled The database connection is closed and the state of the database object is changed to closed. Pooled Unless there are already *db-pool-max-free-connections* free connections in the pool it is returned to the pool, with the backend having an opportunity to run generic cleanup on the connection first. If the max free connections has already been reached then it is disconnected as if it were not in the pool. Affected by *default-database* *db-pool-max-free-connections* Exceptional Situations If during the disconnection attempt an error is detected (e.g. because of network trouble or any other cause), an error of type sql-error might be signalled. See Also connect disconnect-pooled Notes None. DISCONNECT-POOLED DISCONNECT-POOLED closes all pooled database connections Function Syntax disconnect-pooled &optional clear => t Description This function disconnects all database connections that have been placed into the pool by calling connect with :pool &t;. If optional argument clear is non-&nil; then the connection-pool objects are also removed. Examples (disconnect-pool) => T Side Effects Database connections will be closed and *all* entries in the pool are removed. This is done with great prejudice and no thought to thread safety or whether that connection is currently in use. Affected by disconnect Exceptional Situations If during the disconnection attempt an error is detected (e.g. because of network trouble or any other cause), an error of type clsql-error might be signalled. See Also connect disconnect Notes disconnect-pooled is a &clsql; extension. FIND-DATABASE FIND-DATABASE >Locate a database object through it's name. Function Syntax find-database database &optional errorp => result Arguments and Values database A database object or a string, denoting a database name. errorp A generalized boolean. Defaults to t. db-type A keyword symbol denoting a known database back-end. result Either a database object, or, if errorp is &nil;, possibly &nil;. Description find-database locates an active database object given the specification in database. If database is an object of type database, find-database returns this. Otherwise it will search the active databases as indicated by the list returned by connected-databases for a database of type db-type whose name (as returned by database-name is equal as per string= to the string passed as database. If it succeeds, it returns the first database found. If db-type is &nil; all databases matching the string database are considered. If no matching databases are found and errorp is &nil; then &nil; is returned. If errorp is &nil; and one or more matching databases are found, then the most recently connected database is returned as a first value and the number of matching databases is returned as a second value. If no, or more than one, matching databases are found and errorp is true, an error is signalled. Examples (database-name-from-spec '("dent" "newesim" "dent" "dent") :mysql) => "dent/newesim/dent" (connect '("dent" "newesim" "dent" "dent") :database-type :mysql) => #<CLSQL-MYSQL:MYSQL-DATABASE {48391DCD}> (database-name *default-database*) => "dent/newesim/dent" (database-name-from-spec '(nil "template1" "dent" nil) :postgresql) => "/template1/dent" (connect '(nil "template1" "dent" nil) :database-type :postgresql) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (database-name *default-database*) => "/template1/dent" (database-name-from-spec '("www.pmsf.de" "template1" "dent" nil) :postgresql) => "www.pmsf.de/template1/dent" (find-database "dent/newesim/dent") => #<CLSQL-MYSQL:MYSQL-DATABASE {484E91C5}> (find-database "/template1/dent") => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> (find-database "www.pmsf.de/template1/dent" nil) => NIL (find-database **) => #<CLSQL-POSTGRESQL:POSTGRESQL-DATABASE {48392D2D}> Side Effects None. Affected By connected-databases Exceptional Situations Will signal an error of type clsql-error if no matching database can be found, and errorp is true. Will signal an error if the value of database is neither an object of type database nor a string. See Also database-name database-name-from-spec disconnect connect status connected-databases Notes The db-type keyword argument to find-database is a &clsql; extension. INITIALIZE-DATABASE-TYPE INITIALIZE-DATABASE-TYPE Initializes a database type Function Syntax initialize-database-type &key database-type => result Arguments and Values database-type The database type to initialize, i.e. a keyword symbol denoting a known database back-end. Defaults to the value of *default-database-type*. result Either &nil; if the initialization attempt fails, or t otherwise. Description If the back-end specified by database-type has not already been initialized, as seen from *initialized-database-types*, an attempt is made to initialize the database. If this attempt succeeds, or the back-end has already been initialized, the function returns t, and places the keyword denoting the database type onto the list stored in *initialized-database-types*, if not already present. If initialization fails, the function returns &nil;, and/or signals an error of type clsql-error. The kind of action taken depends on the back-end and the cause of the problem. Examples *initialized-database-types* => NIL (setf *default-database-type* :mysql) => :MYSQL (initialize-database-type) >> Compiling LAMBDA (#:G897 #:G898 #:G901 #:G902): >> Compiling Top-Level Form: >> => T *initialized-database-types* => (:MYSQL) (initialize-database-type) => T *initialized-database-types* => (:MYSQL) Side Effects The database back-end corresponding to the database type specified is initialized, unless it has already been initialized. This can involve any number of other side effects, as determined by the back-end implementation (like e.g. loading of foreign code, calling of foreign code, networking operations, etc.). If initialization is attempted and succeeds, the database-type is pushed onto the list stored in *initialized-database-types*. Affected by *default-database-type* *initialized-database-types* Exceptional Situations If an error is encountered during the initialization attempt, the back-end may signal errors of kind clsql-error. See Also *initialized-database-types* *default-database-type* Notes None. RECONNECT RECONNECT Re-establishes the connection between a database object and its RDBMS. Function Syntax reconnect &key database error force => result Arguments and Values database The database to reconnect, which defaults to the database indicated by *default-database*. error A boolean flag indicating whether to signal an error if database is non-nil but cannot be found. The default value is &nil;. force A Boolean indicating whether to signal an error if the database connection has been lost. The default value is &t;. result A Boolean indicating whether the database was successfully reconnected. Description Reconnects database which defaults to *default-database* to the underlying database management system. On success, &t; is returned and the variable *default-database* is set to the newly reconnected database. If database is a database instance, this object is closed. If database is a string, then a connected database whose name matches database is sought in the list of connected databases. If no matching database is found and error and database are both non-&nil; an error is signaled, otherwise &nil; is returned. When the current database connection has been lost, if force is non-&nil; as it is by default, the connection is closed and errors are suppressed. If force is &nil; and the database connection cannot be closed, an error is signalled. Examples *default-database* => #<CLSQL-SQLITE:SQLITE-DATABASE :memory: OPEN {48CFBEA5}> (reconnect) => #<CLSQL-SQLITE:SQLITE-DATABASE :memory: OPEN {48D64105}> Side Effects A database connection is re-established and *default-database* may be rebound to the supplied database object. Affected by *default-database* Exceptional Situations An error may be signalled if the specified database cannot be located or if the database cannot be closed. See Also connect disconnect disconnect-pooled Notes None. STATUS STATUS Print information about connected databases. Function Syntax status &optional full => Arguments and Values full A boolean indicating whether to print additional table information. The default value is &nil;. Description Prints information about the currently connected databases to *STANDARD-OUTPUT*. The argument full is &nil; by default and a value of t means that more detailed information about each database is printed. Examples (status) CLSQL STATUS: 2004-06-13 15:07:39 -------------------------------------------------------- DATABASE TYPE RECORDING -------------------------------------------------------- localhost/test/petrov mysql nil localhost/test/petrov postgresql nil localhost/test/petrov postgresql-socket nil test/petrov odbc nil * :memory: sqlite nil -------------------------------------------------------- (status t) CLSQL STATUS: 2004-06-13 15:08:08 ------------------------------------------------------------------------------- DATABASE TYPE RECORDING POOLED TABLES VIEWS ------------------------------------------------------------------------------- localhost/test/petrov mysql nil nil 7 0 localhost/test/petrov postgresql nil nil 7 0 localhost/test/petrov postgresql-socket nil nil 7 0 test/petrov odbc nil nil 7 0 * :memory: sqlite nil nil 0 0 ------------------------------------------------------------------------------- Side Effects None. Affected by None. Exceptional Situations None. See Also connected-databases connect disconnect *connect-if-exists* find-database Notes None. CREATE-DATABASE CREATE-DATABASE create a database Function Syntax create-database connection-spec &key database-type => success Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* success A boolean flag. If &t;, a new database was successfully created. Description This function creates a database in the database system specified by database-type. Examples (create-database '("localhost" "new" "dent" "dent") :database-type :mysql) => T (create-database '("localhost" "new" "dent" "badpasswd") :database-type :mysql) => Error: While trying to access database localhost/new/dent using database-type MYSQL: Error database-create failed: mysqladmin: connect to server at 'localhost' failed error: 'Access denied for user: 'root@localhost' (Using password: YES)' has occurred. [condition type: CLSQL-ACCESS-ERROR] Side Effects A database will be created on the filesystem of the host. Exceptional Situations An exception will be thrown if the database system does not allow new databases to be created or if database creation fails. See Also destroy-database probe-database list-databases Notes This function may invoke the operating systems functions. Thus, some database systems may require the administration functions to be available in the current PATH. At this time, the :mysql backend requires mysqladmin and the :postgresql backend requires createdb. create-database is a &clsql; extension. DESTROY-DATABASE DESTROY-DATABASE destroys a database Function Syntax destroy-database connection-spec &key database-type => success Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* success A boolean flag. If &t;, the database was successfully destroyed. Description This function destroys a database in the database system specified by database-type. Examples (destroy-database '("localhost" "new" "dent" "dent") :database-type :postgresql) => T (destroy-database '("localhost" "new" "dent" "dent") :database-type :postgresql) => Error: While trying to access database localhost/test2/root using database-type POSTGRESQL: Error database-destroy failed: dropdb: database removal failed: ERROR: database "test2" does not exist has occurred. [condition type: CLSQL-ACCESS-ERROR] Side Effects A database will be removed from the filesystem of the host. Exceptional Situations An exception will be thrown if the database system does not allow databases to be removed, the database does not exist, or if database removal fails. See Also create-database probe-database list-databases Notes This function may invoke the operating systems functions. Thus, some database systems may require the administration functions to be available in the current PATH. At this time, the :mysql backend requires mysqladmin and the :postgresql backend requires dropdb. destroy-database is a &clsql; extension. PROBE-DATABASE PROBE-DATABASE tests for existence of a database Function Syntax probe-database connection-spec &key database-type => success Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* success A boolean flag. If &t;, the database exists in the database system. Description This function tests for the existence of a database in the database system specified by database-type. Examples (probe-database '("localhost" "new" "dent" "dent") :database-type :postgresql) => T Side Effects None Exceptional Situations An exception maybe thrown if the database system does not receive administrator-level authentication since function may need to read the administrative database of the database system. See Also create-database destroy-database list-databases Notes probe-database is a &clsql; extension. LIST-DATABASES LIST-DATABASES List databases matching the supplied connection spec and database type. Function Syntax list-databases connection-spec &key database-type => result Arguments and Values connection-spec A connection specification database-type A database type specifier, i.e. a keyword. This defaults to the value of *default-database-type* result A list of matching databases. Description This function returns a list of databases existing in the database system specified by database-type. Examples (list-databases '("localhost" "new" "dent" "dent") :database-type :postgresql) => ("address-book" "sql-test" "template1" "template0" "test1" "dent" "test") Side Effects None. Affected by None. Exceptional Situations An exception maybe thrown if the database system does not receive administrator-level authentication since function may need to read the administrative database of the database system. See Also create-database destroy-database probe-database Notes list-databases is a &clsql; extension. WITH-DATABASE WITH-DATABASE Execute a body of code with a variable bound to a specified database object. Macro Syntax with-database db-var connection-spec &rest connect-args &body body => result Arguments and Values db-var A variable which is bound to the specified database. connection-spec A vendor specific connection specification supplied as a list or as a string. connect-args Other optional arguments to connect. This macro use a value of &nil; for connect's make-default key, This is in contrast to to the connect function which has a default value of &t; for make-default. body A Lisp code body. result Determined by the result of executing the last expression in body. Description Evaluate body in an environment, where db-var is bound to the database connection given by connection-spec and connect-args. The connection is automatically closed or released to the pool on exit from the body. Examples (connected-databases) => NIL (with-database (db '(":memory:") :database-type :sqlite :make-default nil) (database-name db)) => ":memory:" (connected-databases) => NIL Side Effects See connect and disconnect. Affected by See connect and disconnect. Exceptional Situations See connect and disconnect. See Also connect disconnect disconnect-pooled with-default-database Notes with-database is a &clsql; extension. WITH-DEFAULT-DATABASE WITH-DEFAULT-DATABASE Execute a body of code with *default-database* bound to a specified database. Macro Syntax with-default-database database &rest body => result Arguments and Values database An active database object. body A Lisp code body. result Determined by the result of executing the last expression in body. Description Perform body with DATABASE bound as *default-database*. Examples *default-database* => #<CLSQL-ODBC:ODBC-DATABASE new/dent OPEN {49095CAD}> (let ((database (clsql:find-database ":memory:"))) (with-default-database (database) (database-name *default-database*))) => ":memory:" Side Effects None. Affected by None. Exceptional Situations Calls to &clsql; functions in body may signal errors if database is not an active database object. See Also with-database *default-database* Notes with-default-database is a &clsql; extension. cl-sql-6.7.2/doc/intro.xml0000644000175000017500000002157412570246521014372 0ustar kevinkevin %myents; ]> Introduction Purpose &clsql; is a Common Lisp interface to SQL databases. A number of Common Lisp implementations and SQL databases are supported. The general structure of &clsql; is based on the &commonsql; package by LispWorks Ltd. History The &clsql; project was started by Kevin M. Rosenberg in 2001 to support SQL access on multiple Common Lisp implementations using the &uffi; library. The initial code was based substantially on Pierre R. Mai's excellent &maisql; package. In late 2003, the &usql; library was orphaned by its author, onShore Development, Inc. In April 2004, Marcus Pearce ported the &usql; library to &clsql;. The &usql; library provides a &commonsql;-compatible API for &clsql;. The main changes from &maisql; and &usql; are: Port from the &cmucl; FFI to &uffi; which provide compatibility with the major Common Lisp implementations. Optimized loading of integer and floating-point fields. Additional database backends: &odbc;, &aodbc;, &sqlite; and &sqlite3;. A compatibility layer for &cmucl; specific code. Much improved robustness for the &mysql; back-end along with version 4 client library support. Improved library loading and installation documentation. Improved packages and symbol export. Pooled connections. Integrated transaction support for the classic &maisql; iteration macros. Prerequisites &asdf; &clsql; uses &asdf; to compile and load its components. &asdf; is included in the &cclan; collection. &uffi; &clsql; uses &uffi; as a Foreign Function Interface (FFI) to support multiple &cl; implementations. &md5; &clsql;'s postgresql-socket interface uses Pierre Mai's md5 module. Supported Common Lisp Implementation The implementations that support &clsql; is governed by the supported implementations of &uffi;. The following implementations are supported: &acl; v6.2 through 8.0 on Debian Linux x86 & x86_64 & PowerPC, FreeBSD 4.5, and Microsoft Windows XP. &lw; v4.3 and v4.4 on Debian Linux and Microsoft Windows XP. &cmucl; 18e on Debian Linux, FreeBSD 4.5, and Solaris 2.8. 19c on Debian Linux. &sbcl; 0.8.4 through 0.9.16 on Debian Linux. &scl; 1.1.1 on Debian Linux. &openmcl; 0.14 PowerPC and 1.0pre AMD64 on Debian Linux . Supported &sql; Implementation &clsql; supports the following databases: &mysql; (tested v3.23.51, v4.0.18, 5.0.24). &postgresql; (tested with v7.4 and 8.0 with both direct API and TCP socket connections. &sqlite;. &sqlite3;. Direct &odbc; interface. &oracle; OCI. Allegro's DB interface (&aodbc;). Installation Ensure &asdf; is loaded Simply load the file asdf.lisp. (load "asdf.lisp") Build &c; helper libraries &clsql; uses functions that require 64-bit integer parameters and return values. The &ffi; in most &clsql; implementations do not support 64-bit integers. Thus, C helper libraries are required to break these 64-bit integers into two compatible 32-bit integers. The helper libraries reside in the directories uffi and db-mysql. &mswindows; Files named Makefile.msvc are supplied for building the libraries under Microsoft Windows. Since &mswindows; does not come with that compiler, compiled DLL and LIB library files are supplied with &clsql;. &unix; Files named Makefile are supplied for building the libraries under &unix;. Loading the .asd files automatically invokes make when necessary. So, manual building of the helper libraries is not necessary on most &unix; systems. However, the location of the &mysql; library files and include files may need to adjusted in db-mysql/Makefile on non-Debian systems. Add &uffi; path Unzip or untar the &uffi; distribution which creates a directory for the &uffi; files. Add that directory to &asdf;'s asdf:*central-registry*. You can do that by pushing the pathname of the directory onto this variable. The following example code assumes the &uffi; files reside in the /usr/share/lisp/uffi/ directory. (push #P"/usr/share/lisp/uffi/" asdf:*central-registry*) Add &md5; path If you plan to use the clsql-postgresql-socket interface, you must load the md5 module. Unzip or untar the cl-md5 distribution, which creates a directory for the cl-md5 files. Add that directory to &asdf;'s asdf:*central-registry*. You can do that by pushing the pathname of the directory onto this variable. The following example code assumes the cl-md5 files reside in the /usr/share/lisp/cl-md5/ directory. (push #P"/usr/share/lisp/cl-md5/" asdf:*central-registry*) Add &clsql; path and load module Unzip or untar the &clsql; distribution which creates a directory for the &clsql; files. Add that directory to &asdf;'s asdf:*central-registry*. You can do that by pushing the pathname of the directory onto this variable. The following example code assumes the &clsql; files reside in the /usr/share/lisp/clsql/ directory. You need to load the clsql system. (push #P"/usr/share/lisp/clsql/" asdf:*central-registry*) (asdf:operate 'asdf:load-op 'clsql) ; main CLSQL package Run test suite (optional) The test suite can be executed using the &asdf; test-op operator. If &clsql; has not been loaded with asdf:load-op, the asdf:test-op operator will automatically load &clsql;. A configuration file named .clsql-test.config must be created in your home directory. There are instructures on the format of that file in the tests/README. After creating .clsql-test.config, you can run the test suite with &asdf;: (asdf:operate 'asdf:test-op 'clsql) cl-sql-6.7.2/doc/xinclude.mod0000644000175000017500000000160110667176647015036 0ustar kevinkevin cl-sql-6.7.2/doc/ref-syntax.xml0000644000175000017500000011061511345753563015342 0ustar kevinkevin %myents; ]> The Symbolic SQL Syntax &clsql; provides a symbolic syntax allowing the construction of SQL expressions as lists delimited by square brackets. The syntax is turned off by default. This section describes utilities for enabling and disabling the square bracket reader syntax and for constructing symbolic SQL expressions. Tip: just want it on file-enable-sql-reader-syntax at the top of each file is easiest. ENABLE-SQL-READER-SYNTAX ENABLE-SQL-READER-SYNTAX Globally enable square bracket reader syntax. Macro Syntax enable-sql-reader-syntax => Arguments and Values None. Description Turns on the SQL reader syntax setting the syntax state such that if the syntax is subsequently disabled, restore-sql-reader-syntax-state will enable it again. Examples None. Side Effects Sets the internal syntax state to enabled. Modifies the default readtable. &clsql; tries to keep track of whether the syntax has already been enabled. This can be problematic if the syntax is somehow disabled externally to &clsql; as future attempts to enable the syntax will do nothing--the system thinks it is already enabled. This may happen if there is an enable, but no disable, in a file that is processed with load or compile-file as the lisp implementation will restore the readtable on completion. Or, even if there is a disable but a compiler-error is encountered before running the disable. If you encounter this try running disable-sql-reader-syntax a couple times in the REPL. See file-enable-sql-reader-syntax for an alternative. Affected by None. Exceptional Situations None. See Also disable-sql-reader-syntax locally-enable-sql-reader-syntax locally-disable-sql-reader-syntax restore-sql-reader-syntax-state file-enable-sql-reader-syntax Notes The symbolic SQL syntax is disabled by default. &clsql; differs from &commonsql; in that enable-sql-reader-syntax is defined as a macro rather than a function. DISABLE-SQL-READER-SYNTAX DISABLE-SQL-READER-SYNTAX Globally disable square bracket reader syntax. Macro Syntax disable-sql-reader-syntax => Arguments and Values None. Description Turns off the SQL reader syntax setting the syntax state such that if the syntax is subsequently enabled, restore-sql-reader-syntax-state will disable it again. Examples None. Side Effects Sets the internal syntax state to disabled. Modifies the default readtable. Affected by None. Exceptional Situations None. See Also enable-sql-reader-syntax locally-enable-sql-reader-syntax locally-disable-sql-reader-syntax restore-sql-reader-syntax-state file-enable-sql-reader-syntax Notes The symbolic SQL syntax is disabled by default. &clsql; differs from &commonsql; in that disable-sql-reader-syntax is defined as a macro rather than a function. LOCALLY-ENABLE-SQL-READER-SYNTAX LOCALLY-ENABLE-SQL-READER-SYNTAX Locally enable square bracket reader syntax. Macro Syntax locally-enable-sql-reader-syntax => Arguments and Values None. Description Turns on the SQL reader syntax without changing the syntax state such that restore-sql-reader-syntax-state will re-establish the current syntax state. Examples Intended to be used in a file for code which uses the square bracket syntax without changing the global state. #.(locally-enable-sql-reader-syntax) ... CODE USING SYMBOLIC SQL SYNTAX ... #.(restore-sql-reader-syntax-state) Side Effects Modifies the default readtable. &clsql; tries to keep track of whether the syntax has already been enabled. This can be problematic if the syntax is somehow disabled externally to &clsql; as future attempts to enable the syntax will do nothing--the system thinks it is already enabled. This may happen if there is an enable, but no disable, in a file that is processed with load or compile-file as the lisp implementation will restore the readtable on completion. Or, even if there is a disable but a compiler-error is encountered before running the disable. If you encounter this try running disable-sql-reader-syntax a couple times in the REPL. See file-enable-sql-reader-syntax for an alternative. Affected by None. Exceptional Situations None. See Also enable-sql-reader-syntax disable-sql-reader-syntax locally-disable-sql-reader-syntax restore-sql-reader-syntax-state file-enable-sql-reader-syntax Notes The symbolic SQL syntax is disabled by default. &clsql; differs from &commonsql; in that locally-enable-sql-reader-syntax is defined as a macro rather than a function. LOCALLY-DISABLE-SQL-READER-SYNTAX LOCALLY-DISABLE-SQL-READER-SYNTAX Locally disable square bracket reader syntax. Macro Syntax locally-disable-sql-reader-syntax => Arguments and Values None. Description Turns off the SQL reader syntax without changing the syntax state such that restore-sql-reader-syntax-state will re-establish the current syntax state. Examples Intended to be used in a file for code in which the square bracket syntax should be disabled without changing the global state. #.(locally-disable-sql-reader-syntax) ... CODE NOT USING SYMBOLIC SQL SYNTAX ... #.(restore-sql-reader-syntax-state) Side Effects Modifies the default readtable. Affected by None. Exceptional Situations None. See Also enable-sql-reader-syntax disable-sql-reader-syntax locally-enable-sql-reader-syntax restore-sql-reader-syntax-state file-enable-sql-reader-syntax Notes The symbolic SQL syntax is disabled by default. &clsql; differs from &commonsql; in that locally-disable-sql-reader-syntax is defined as a macro rather than a function. RESTORE-SQL-READER-SYNTAX-STATE RESTORE-SQL-READER-SYNTAX-STATE Restore square bracket reader syntax to its previous state. Macro Syntax restore-sql-reader-syntax-state => Arguments and Values None. Description Enables the SQL reader syntax if enable-sql-reader-syntax has been called more recently than disable-sql-reader-syntax and otherwise disables the SQL reader syntax. By default, the SQL reader syntax is disabled. Examples See locally-enable-sql-reader-syntax and locally-disable-sql-reader-syntax. Side Effects Reverts the internal syntax state. Modifies the default readtable. Affected by The current internal syntax state. Exceptional Situations None. See Also enable-sql-reader-syntax disable-sql-reader-syntax locally-enable-sql-reader-syntax locally-disable-sql-reader-syntax file-enable-sql-reader-syntax Notes The symbolic SQL syntax is disabled by default. &clsql; differs from &commonsql; in that restore-sql-reader-syntax-state is defined as a macro rather than a function. FILE-ENABLE-SQL-READER-SYNTAX FILE-ENABLE-SQL-READER-SYNTAX Enable the square bracket reader syntax for the duration of the file. Macro Syntax file-enable-sql-reader-syntax => Arguments and Values None. Description Uncoditionally enables the SQL reader syntax. Unlike enable-sql-reader-syntax and disable-sql-reader-syntax which try to keep track of whether the syntax has been enabled or disabled and keep track of the old read-table for restoration this function just enables it unconditionally. Once enabled this way there is no corresponding disable function but instead relies on being used in a file context. The spec for load and compile-file states that the *readtable* will be restored after processing the file. Examples Intended to be used at the top of a file that contains sql reader syntax. (in-package :my-package) (clsql:file-enable-sql-reader-syntax) ... ;;functions that use the square bracket syntax. Side Effects Modifies the readtable for #\[ and #\] Affected by None. Exceptional Situations None. See Also enable-sql-reader-syntax disable-sql-reader-syntax locally-enable-sql-reader-syntax locally-disable-sql-reader-syntax Notes Unique to &clsql;, not present in &commonsql;. SQL SQL Construct an SQL string from supplied expressions. Function Syntax sql &rest args => sql-expression Arguments and Values args A set of expressions. sql-expression A string representing an SQL expression. Description Returns an SQL string generated from the expressions args. The expressions are translated into SQL strings and then concatenated with a single space delimiting each expression. Examples (sql nil) => "NULL" (sql 'foo) => "FOO" (sql "bar") => "'bar'" (sql 10) => "10" (sql '(nil foo "bar" 10)) => "(NULL,FOO,'bar',10)" (sql #(nil foo "bar" 10)) => "NULL,FOO,'bar',10" (sql [select [foo] [bar] :from [baz]] 'having [= [foo id] [bar id]] 'and [foo val] '< 5) => "SELECT FOO,BAR FROM BAZ HAVING (FOO.ID = BAR.ID) AND FOO.VAL < 5" Side Effects None. Affected by None. Exceptional Situations An error of type sql-user-error is signalled if any element in args is not of the supported types (a symbol, string, number or symbolic SQL expression) or a list or vector containing only these supported types. See Also sql-expression sql-operation sql-operator Notes None. SQL-EXPRESSION SQL-EXPRESSION Constructs an SQL expression from supplied keyword arguments. Function Syntax sql-expression &key string table alias attribute type => result Arguments and Values string A string. table A symbol representing a database table identifier. alias A table alias. attribute A symbol representing an attribute identifier. type A type specifier. result A object of type sql-expression. Description Returns an SQL expression constructed from the supplied arguments which may be combined as follows: attribute and type; attribute; alias or table and attribute and type; alias or table and attribute; table, attribute and type; table and attribute; table and alias; table; string. Examples (sql-expression :table 'foo :attribute 'bar) => #<CLSQL-SYS:SQL-IDENT-ATTRIBUTE FOO.BAR> (sql-expression :attribute 'baz) => #<CLSQL-SYS:SQL-IDENT-ATTRIBUTE BAZ> Side Effects None. Affected by None. Exceptional Situations An error of type sql-user-error is signalled if an unsupported combination of keyword arguments is specified. See Also sql sql-operation sql-operator Notes None. SQL-OPERATION SQL-OPERATION Constructs an SQL expression from a supplied operator and arguments. Function Syntax sql-operation operator &rest args => result sql-operation 'function func &rest args => result Arguments and Values operator A symbol denoting an SQL operator. func A string denoting an SQL function. args A set of arguments for the specified SQL operator or function. result A object of type sql-expression. Description Returns an SQL expression constructed from the supplied SQL operator or function operator and its arguments args. If operator is passed the symbol 'function then the first value in args is taken to be a valid SQL function and the remaining values in args its arguments. Examples (sql-operation 'select (sql-expression :table 'foo :attribute 'bar) (sql-operation 'sum (sql-expression :table 'foo :attribute 'baz)) :from (sql-expression :table 'foo) :where (sql-operation '> (sql-expression :attribute 'bar) 12) :order-by (sql-operation 'sum (sql-expression :attribute 'baz))) => #<SQL-QUERY SELECT FOO.BAR,SUM(FOO.BAZ) FROM FOO WHERE (BAR > 12) ORDER BY SUM(BAZ)> (sql-operation 'function "strpos" "CLSQL" "SQL") => #<CLSQL-SYS:SQL-FUNCTION-EXP STRPOS('CLSQL','SQL')> Side Effects None. Affected by None. Exceptional Situations An error of type sql-user-error is signalled if operator is not a symbol representing a supported SQL operator. See Also sql sql-expression sql-operator Notes None. SQL-OPERATOR SQL-OPERATOR Returns the symbol for the supplied SQL operator. Function Syntax sql-operator operator => result Arguments and Values operator A symbol denoting an SQL operator. result The Lisp symbol used by &clsql; to represent the specified operator. Description Returns the Lisp symbol corresponding to the SQL operator represented by the symbol operator. If operator does not represent a supported SQL operator or is not a symbol, nil is returned. Examples (sql-operator 'like) => SQL-LIKE Side Effects None. Affected by None. Exceptional Situations None. See Also sql sql-expression sql-operation Notes &clsql;'s symbolic SQL syntax currently has support for the following &commonsql; compatible SQL operators: any some all not union intersect minus except order-by null * + / - like and or in substr || = < > >= <= <> count max min avg sum function between distinct nvl slot-value userenv as well as the pseudo-operator function. The following operators are provided as &clsql; extensions to the &commonsql; API. concat substring limit group-by having not-null exists uplike is == the coalesce view-class Note that some of these operators are not supported by all of the RDBMS supported by &clsql; (see the Appendix for details). cl-sql-6.7.2/doc/ref-recording.xml0000644000175000017500000007021310667176647015777 0ustar kevinkevin %myents; ]> SQL I/O Recording &clsql; provides a facility for recording SQL commands sent to and/or results returned from the underlying RDBMS to user sprecified streams. This is useful for monitoring &clsql; activity and for debugging applications. This section documents the functions provided for enabling and disabling SQL recording as well as for manipulating the streams on to which SQL commands and results are recorded. START-SQL-RECORDING START-SQL-RECORDING Start recording SQL commands or results. Function Syntax start-sql-recording &key type database => Arguments and Values type One of the following keyword symbols: :commands, :results or :both, defaulting to :commands. database A database object. This will default to *default-database*. Description Starts recording of SQL commands sent to and/or results returned from database which defaults to *default-database*. The SQL is output on one or more broadcast streams, initially just *standard-output*, and the functions add-sql-stream and delete-sql-stream may be used to add or delete command or result recording streams. The default value of type is :commands which means that SQL commands sent to database are recorded. If type is :results then SQL results returned from database are recorded. Both commands and results may be recorded by passing type value of :both. Examples (start-sql-recording :type :both) => (select [last-name] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) ;; 2004-07-02 16:42:12 dent/test/dent => SELECT last_name FROM employee WHERE (emplid = 1) ;; 2004-07-02 16:42:12 dent/test/dent <= (Lenin) => ("Lenin") Side Effects The command and result recording broadcast streams associated with database are reinitialised with only *standard-output* as their component streams. Affected by None. Exceptional Situations None. See Also stop-sql-recording sql-recording-p sql-stream add-sql-stream delete-sql-stream list-sql-streams Notes None. STOP-SQL-RECORDING STOP-SQL-RECORDING Stop recording SQL commands or results. Function Syntax stop-sql-recording &key type database => Arguments and Values type One of the following keyword symbols: :commands, :results or :both, defaulting to :commands. database A database object. This will default to *default-database*. Description Stops recording of SQL commands sent to and/or results returned from database which defaults to *default-database*. The default value of type is :commands which means that SQL commands sent to database will no longer be recorded. If type is :results then SQL results returned from database will no longer be recorded. Recording may be stopped for both commands and results by passing type value of :both. Examples (start-sql-recording :type :both) => (select [last-name] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) ;; 2004-07-02 16:42:12 dent/test/dent => SELECT last_name FROM employee WHERE (emplid = 1) ;; 2004-07-02 16:42:12 dent/test/dent <= (Lenin) => ("Lenin") (stop-sql-recording :type :results) => (select [last-name] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) ;; 2004-07-02 16:44:11 dent/test/dent => SELECT last_name FROM employee WHERE (emplid = 1) => ("Lenin") Side Effects The command and result recording broadcast streams associated with database are reinitialised to &nil;. Affected by None. Exceptional Situations None. See Also start-sql-recording sql-recording-p Notes None. SQL-RECORDING-P SQL-RECORDING-P Tests whether SQL commands or results are being recorded. Function Syntax sql-recording-p &key type database => result Arguments and Values type One of the following keyword symbols: :commands, :results, :both or :either defaulting to :commands. database A database object. This will default to *default-database*. result A Boolean. Description Predicate to test whether the SQL recording specified by type is currently enabled for database which defaults to *default-database*. type may be one of :commands, :results, :both or :either, defaulting to :commands, otherwise &nil; is returned. Examples (start-sql-recording :type :commands) => (sql-recording-p :type :commands) => T (sql-recording-p :type :both) => NIL (sql-recording-p :type :either) => T Side Effects None. Affected by start-sql-recording stop-sql-recording Exceptional Situations None. See Also start-sql-recording stop-sql-recording Notes The :both and :either values for the type keyword argument are &clsql; extensions. SQL-STREAM SQL-STREAM Returns the broadcast stream used for recording SQL commands or results. Function Syntax sql-stream &key type database => result Arguments and Values type One of the following keyword symbols: :commands or :results, defaulting to :commands. database A database object. This will default to *default-database*. result A broadcast stream or &nil;. Description Returns the broadcast stream used for recording SQL commands sent to or results returned from database which defaults to *default-database*. type must be one of :commands or :results, defaulting to :commands, and determines whether the stream returned is that used for recording SQL commands or results. Examples (start-sql-recording :type :commands) => (sql-stream :type :commands) => #<Broadcast Stream> (sql-stream :type :results) => NIL Side Effects None. Affected by None. Exceptional Situations An error is signalled if type is not one of :commands or :results. See Also start-sql-recording add-sql-stream delete-sql-stream list-sql-streams Notes None. ADD-SQL-STREAM ADD-SQL-STREAM Add a component to the broadcast streams used for recording SQL commands or results. Function Syntax add-sql-stream stream &key type database => result Arguments and Values stream A stream or &t;. type One of the following keyword symbols: :commands, :results or :both, defaulting to :commands. database A database object. This will default to *default-database*. result The added stream. Description Adds the supplied stream stream (or &t; for *standard-output*) as a component of the recording broadcast stream for the SQL recording type specified by type on database which defaults to *default-database*. type must be one of :commands, :results, or :both, defaulting to :commands, depending on whether the stream is to be added for recording SQL commands, results or both. Examples (start-sql-recording :type :commands) => (with-output-to-string (s) (add-sql-stream s :type :commands) (print-query [select [emplid] [first-name] [last-name] [email] :from [employee]] :stream s)) ;; 2004-07-02 17:38:45 dent/test/dent => SELECT emplid,first_name,last_name,email FROM employee => ";; 2004-07-02 17:38:45 dent/test/dent => SELECT emplid,first_name,last_name,email FROM employee 1 Vladimir Lenin lenin@soviet.org 2 Josef Stalin stalin@soviet.org 3 Leon Trotsky trotsky@soviet.org 4 Nikita Kruschev kruschev@soviet.org 5 Leonid Brezhnev brezhnev@soviet.org 6 Yuri Andropov andropov@soviet.org 7 Konstantin Chernenko chernenko@soviet.org 8 Mikhail Gorbachev gorbachev@soviet.org 9 Boris Yeltsin yeltsin@soviet.org 10 Vladimir Putin putin@soviet.org " Side Effects The specified broadcast stream(s) associated with database are modified. Affected by None. Exceptional Situations None. See Also start-sql-recording sql-stream delete-sql-stream list-sql-streams Notes None. DELETE-SQL-STREAM DELETE-SQL-STREAM Remove a component from the broadcast streams used for recording SQL commands or results. Function Syntax delete-sql-stream stream &KEY type database => result Arguments and Values stream A stream or &t;. stream A stream or &t;. type One of the following keyword symbols: :commands, :results or :both, defaulting to :commands. database A database object. This will default to *default-database*. result The added stream. Description Removes the supplied stream stream from the recording broadcast stream for the SQL recording type specified by type on database which defaults to *default-database*. type must be one of :commands, :results, or :both, defaulting to :commands, depending on whether the stream is to be added for recording SQL commands, results or both. Examples (list-sql-streams :type :both) => (#<Stream for descriptor 7> #<Stream for descriptor 7>) (delete-sql-stream *standard-output* :type :results) => #<Stream for descriptor 7> (list-sql-streams :type :both) => (#<Stream for descriptor 7>) Side Effects The specified broadcast stream(s) associated with database are modified. Affected by None. Exceptional Situations None. See Also start-sql-recording stop-sql-recording sql-recording-p sql-stream add-sql-stream delete-sql-stream list-sql-streams Notes None. LIST-SQL-STREAMS LIST-SQL-STREAMS List the components of the broadcast streams used for recording SQL commands or results. Function Syntax list-sql-streams &key type database => result Arguments and Values type One of the following keyword symbols: :commands, :results or :both, defaulting to :commands. database A database object. This will default to *default-database*. result A list. Description Returns the list of component streams for the broadcast stream recording SQL commands sent to and/or results returned from database which defaults to *default-database*. type must be one of :commands, :results, or :both, defaulting to :commands, and determines whether the listed streams contain those recording SQL commands, results or both. Examples (list-sql-streams :type :both) => NIL (start-sql-recording :type :both) => (list-sql-streams :type :both) => (#<Stream for descriptor 7> #<Stream for descriptor 7>) Side Effects None. Affected by add-sql-stream delete-sql-stream Exceptional Situations An error is signalled if type is passed a value other than :commands, :results or :both. See Also sql-stream add-sql-stream delete-sql-stream Notes None. cl-sql-6.7.2/doc/appendix.xml0000644000175000017500000007130612021503403015027 0ustar kevinkevin %myents; ]> Database Back-ends How CLSQL finds and loads foreign libraries For some database types CLSQL has to load external foreign libaries. These are usually searched for in the standard locations the operating system uses but you can tell &clsql; to look into other directories as well by using the function CLSQL:PUSH-LIBRARY-PATH or by directly manipulating the special variable CLSQL:*FOREIGN-LIBRARY-SEARCH-PATHS*. If, say, the shared library libpq.so needed for PostgreSQL support is located in the directory /opt/foo/ on your machine you'd use (clsql:push-library-path "/opt/foo/") before loading the CLSQL-POSTGRESQL module. (Note the trailing slash above!) If you want to combine this with fully automatic loading of libraries via ASDF a technique like the following works: (defmethod asdf:perform :after ((o asdf:load-op) (c (eql (asdf:find-system 'clsql)))) (funcall (find-symbol (symbol-name '#:push-library-path) (find-package 'clsql)) #p"/opt/foo/")) Additionally, site-specific initialization can be done using an initialization file. If the file /etc/clsql-init.lisp exists, this file will be read after the &clsql; ASDF system is loaded. This file can contain forms to set site-specific paths as well as change &clsql; default values. PostgreSQL Libraries The PostgreSQL back-end requires the PostgreSQL C client library (libpq.so). The location of this library is specified via *postgresql-so-load-path*, which defaults to /usr/lib/libpq.so. Additional flags to ld needed for linking are specified via *postgresql-so-libraries*, which defaults to ("-lcrypt" "-lc"). Initialization Use (asdf:operate 'asdf:load-op 'clsql-postgresql) to load the PostgreSQL back-end. The database type for the PostgreSQL back-end is :postgresql. Connection Specification Syntax of connection-spec (host db user password &optional port options tty) Description of connection-spec For every parameter in the connection-spec, nil indicates that the PostgreSQL default environment variables (see PostgreSQL documentation) will be used, or if those are unset, the compiled-in defaults of the C client library are used. host String representing the hostname or IP address the PostgreSQL server resides on. Use the empty string to indicate a connection to localhost via Unix-Domain sockets instead of TCP/IP. db String representing the name of the database on the server to connect to. user String representing the user name to use for authentication. password String representing the unencrypted password to use for authentication. port String representing the port to use for communication with the PostgreSQL server. options String representing further runtime options for the PostgreSQL server. tty String representing the tty or file to use for debugging messages from the PostgreSQL server. Notes None. PostgreSQL Socket Libraries The PostgreSQL Socket back-end needs no access to the PostgreSQL C client library, since it communicates directly with the PostgreSQL server using the published frontend/backend protocol, version 2.0. This eases installation and makes it possible to dump CMU CL images containing CLSQL and this backend, contrary to backends which require FFI code. Initialization Use (asdf:operate 'asdf:load-op 'clsql-postgresql-socket) to load the PostgreSQL Socket back-end. The database type for the PostgreSQL Socket back-end is :postgresql-socket. Connection Specification Syntax of connection-spec (host db user password &optional port options tty) Description of connection-spec host If this is a string, it represents the hostname or IP address the PostgreSQL server resides on. In this case communication with the server proceeds via a TCP connection to the given host and port. If this is a pathname, then it is assumed to name the directory that contains the server's Unix-Domain sockets. The full name to the socket is then constructed from this and the port number passed, and communication will proceed via a connection to this unix-domain socket. db String representing the name of the database on the server to connect to. user String representing the user name to use for authentication. password String representing the unencrypted password to use for authentication. This can be the empty string if no password is required for authentication. port Integer representing the port to use for communication with the PostgreSQL server. This defaults to 5432. options String representing further runtime options for the PostgreSQL server. tty String representing the tty or file to use for debugging messages from the PostgreSQL server. Notes None. MySQL Libraries The &mysql; back-end requires the &mysql; C client library (libmysqlclient.so). The location of this library is specified via *mysql-so-load-path*, which defaults to /usr/lib/libmysqlclient.so. Additional flags to ld needed for linking are specified via *mysql-so-libraries*, which defaults to ("-lc"). Initialization Use (asdf:operate 'asdf:load-op 'clsql-mysql) to load the &mysql; back-end. The database type for the MySQL back-end is :mysql. Connection Specification Syntax of connection-spec (host db user password &optional port) Description of connection-spec host String representing the hostname or IP address the &mysql; server resides on, or nil to indicate the localhost. db String representing the name of the database on the server to connect to. user String representing the user name to use for authentication, or nil to use the current Unix user ID. password String representing the unencrypted password to use for authentication, or nil if the authentication record has an empty password field. port String representing the port to use for communication with the MySQL server. Notes FDDL drop-index requires a table to be specified with the :on keyword parameter. views are not supported by &mysql;. The :transactions keyword argument to create-table controls whether or not the created table is an InnoDB table which supports transactions. The :owner keyword argument to the FDDL functions for listing and testing for database objects is ignored. FDML Prior to version 4.1, &mysql; does not support nested subqueries in calls to select. Symbolic SQL Syntax &mysql; does not support the || concatenation operator. Use concat instead. &mysql; does not support the substr operator. Use substring instead. &mysql; does not support the intersect and except set operations. &mysql; (version 4.0 and later) does not support string table aliases unless the server is started with ANSI_QUOTES enabled. &odbc; Libraries The &odbc; back-end requires access to an &odbc; driver manager as well as &odbc; drivers for the underlying database server. &clsql; has been tested with unixODBC ODBC Driver Manager as well as Microsoft's ODBC manager. These driver managers have been tested with the psqlODBC driver for &postgresql; and the MyODBC driver for &mysql;. Initialization Use (asdf:operate 'asdf:load-op 'clsql-odbc) to load the &odbc; back-end. The database type for the &odbc; back-end is :odbc. Connection Specification Syntax of connection-spec (dsn user password &key connection-string) Description of connection-spec dsn String representing the ODBC data source name. user String representing the user name to use for authentication. password String representing the unencrypted password to use for authentication. connection-string Raw connection string passed to the underlying ODBC driver. Allows bypassing creating a DSN on the server. Notes FDDL The :owner keyword argument to the FDDL functions for listing and testing for database objects is ignored. Connect Examples ;; assumes a "mssql" DSN is configured on the lisp host, specifying database server ;; and database name. > (clsql:connect '("mssql" "database-user" "database-password") :database-type :odbc) => #<CLSQL-ODBC:ODBC-DATABASE mssql/database-user OPEN {100756D123}> ;; no DSN on the lisp host, specify connection information via :connection-string > (clsql:connect '("friendly-server-name" "friendly-username" "" :connection-string "DRIVER={FreeTDS};SERVER=mssql-server;DATABASE=database-name;UID=database-user;PWD=database-password;PORT=1433;TDS_Version=8.0;APP=clsql") :database-type :odbc) => #<CLSQL-ODBC:ODBC-DATABASE friendly-server-name/friendly-username OPEN {100756D123}> The friendly-server-name and friendly-username are only used when printing the connection object to a stream. &aodbc; Libraries The &aodbc; back-end requires access to the &odbc; interface of &acl; named DBI. This interface is not available in the trial version of &acl; Initialization Use (require 'aodbc-v2) (asdf:operate 'asdf:load-op 'clsql-aodbc) to load the &aodbc; back-end. The database type for the &aodbc; back-end is :aodbc. Connection Specification Syntax of connection-spec (dsn user password) Description of connection-spec dsn String representing the ODBC data source name. user String representing the user name to use for authentication. password String representing the unencrypted password to use for authentication. Notes None. &sqlite; Libraries The &sqlite; back-end requires the &sqlite; shared library file. Its default file name is /usr/lib/libsqlite.so. Initialization Use (asdf:operate 'asdf:load-op 'clsql-sqlite) to load the &sqlite; back-end. The database type for the &sqlite; back-end is :sqlite. Connection Specification Syntax of connection-spec (filename) Description of connection-spec filename String or pathname representing the filename of the &sqlite; database file. Notes Connection Passing filename a value of :memory: will create a database in physical memory instead of using a file on disk. Some operations will be many times faster if database integrity checking is disabled by setting the SYNCHRONOUS flag to OFF (see the SQLITE manual for details). FDDL The :owner keyword argument to the FDDL functions for listing and testing for database objects is ignored. The :column-list keyword argument to create-view is not supported by &sqlite;. Symbolic SQL Syntax &sqlite; does not support the all, some, any and exists subquery operations. &sqlite3; Libraries The &sqlite3; back-end requires the &sqlite3; shared library file. Its default file name is /usr/lib/libsqlite3.so. Initialization Use (asdf:operate 'asdf:load-op 'clsql-sqlite3) to load the &sqlite3; back-end. The database type for the &sqlite3; back-end is :sqlite3. Connection Specification Syntax of connection-spec (filename &optional init-function) Description of connection-spec filename String representing the filename of the &sqlite3; database file. init-function A function designator. init-function takes a single argument of type sqlite3:sqlite3-db, a foreign pointer to the C descriptor of the newly opened database. init-function is called by the back-end immediately after &sqlite3; sqlite3_open library function, and can be used to perform optional database initializations by calling foreign functions in the &sqlite3; library. An example of an initialization function which defines a new collating sequence for text columns is provided in ./examples/sqlite3/init-func/. Notes Connection Passing filename a value of :memory: will create a database in physical memory instead of using a file on disk. Some operations will be many times faster if database integrity checking is disabled by setting the SYNCHRONOUS flag to OFF (see the SQLITE manual for details). FDDL The :owner keyword argument to the FDDL functions for listing and testing for database objects is ignored. The :column-list keyword argument to create-view is not supported by &sqlite3;. Symbolic SQL Syntax &sqlite3; does not support the all, some, any and exists subquery operations. Oracle Libraries The &oracle; back-end requires the &oracle; OCI client library. (libclntsh.so). The location of this library is specified relative to the ORACLE_HOME value in the operating system environment. Library Versions &clsql; has tested sucessfully using the client library from Oracle 9i and Oracle 10g server installations as well as Oracle's 10g Instant Client library. For Oracle 8 and earlier versions, there is vestigial support by pushing the symbol :oci7 onto cl:*features* prior to loading the clsql-oracle &asdf; system. (push :oci7 cl:*features*) (asdf:operate 'asdf:load-op 'clsql-oracle) Initialization Use (asdf:operate 'asdf:load-op 'clsql-oracle) to load the &oracle; back-end. The database type for the Oracle back-end is :oracle. Connection Specification Syntax of connection-spec (global-name user password) Description of connection-spec global-name String representing the global name of the Oracle database. This is looked up through the tnsnames.ora file. user String representing the user name to use for authentication. password String representing the password to use for authentication.. Notes Symbolic SQL Syntax The userenv operator is &oracle; specific. &oracle; does not support the except operator. Use minus instead. &oracle; does not support the all, some, any subquery operations. Transactions By default, &clsql; starts in transaction AUTOCOMMIT mode (see set-autocommit). To begin a transaction in autocommit mode, start-transaction has to be called explicitly. cl-sql-6.7.2/doc/ref-oodml.xml0000644000175000017500000010562412064366222015121 0ustar kevinkevin %myents; ]> Object Oriented Data Manipulation Language (OODML) Object Oriented Data Manipulation Language (OODML) provides a Common Lisp Object System (CLOS) interface to SQL databases. View classes are defined with the OODDL interface and objects are read and written with the OODML. The main function for reading data with the OODML is the select function. The select is also used in the FDML. However, when select is given a view class name, it returns a list of instances of view classes. View class instances can be updated to reflect any changes in the database with the functions update-slot-from-record and update-instance-from-records. To update the database to reflect changes made to instances of view classes, use the functions update-records-from-instance, update-record-from-slot, and update-record-from-slots. The function delete-instance-records deletes the records corresponding to an instance of a view class. *DB-AUTO-SYNC* Enables SQL storage during Lisp object creation. Variable Value Type Boolean Initial Value &nil; Description When this variable is &t; an instance is stored in the SQL database when the instance is created by make-instance. Furthermore, the appropriate database records are updated whenever the slots of a View Class instance are modified. When this variable is &nil;, which is the default value, &clsql; behaves like &commonsql;: instances of view classes are stored or updated in the SQL database only when update-record-from-instance, update-record-from-slot or update-record-from-slots are called. Examples (let ((instance (make-instance 'foo))) (update-records-from-instance instance)) ;; is equivalent to (let ((*db-auto-sync* t)) (make-instance 'foo)) ;; and (progn (setf (slot-value instance 'bar) "baz") (update-record-from-slot instance 'bar)) ;; is equivalent to (let ((*db-auto-sync* t)) (setf (slot-value instance 'bar) "baz")) Affected By None. See Also update-records-from-instance update-record-from-slot update-record-from-slots Notes This is a CLSQL extension to the CommonSQL API. *DEFAULT-CACHING* Controls the default caching behavior. Variable Value Type Boolean Initial Value &t; Description This variable stores the default value of the CACHING keyword for the select. Examples (let ((*default-caching* nil))) (select 'foo)) ;; is equivalent to (select 'foo :caching nil) Affected By None. See Also select Notes This is a CLSQL extension to the &commonsql; API. &commonsql; has caching on at all times. *DEFAULT-UPDATE-OBJECTS-MAX-LEN* The default maximum number of objects each query to perform a join Variable Value Type (or null integer) Initial Value &nil; Description This special variable provides the default value for the max-len argument of the function update-object-joins. Examples (setq *default-update-objects-max-len* 100) Affected By None. See Also update-object-joins Notes None. INSTANCE-REFRESHED User hook to call on object refresh. Generic function Syntax instance-refreshed object => Arguments and Values object The View Class object which is being refreshed. Description Provides a hook which is called within an object oriented call to select with a non-nil value of refresh when the View Class instance object has been updated from the database. A method specialised on standard-db-object is provided which has no effects. Methods specialised on particular View Classes can be used to specify any operations that need to be made on View Classes instances which have been updated in calls to select. Examples (slot-value employee1 'email) => "lenin@soviet.org" (defmethod instance-refreshed ((e employee)) (format t "~&Details for ~A ~A have been updated from the database." (slot-value e 'first-name) (slot-value e 'last-name))) => #<Standard-Method INSTANCE-REFRESHED (EMPLOYEE) {48174D9D}> (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t) => (#<EMPLOYEE {48149995}>) (slot-value (car *) 'email) => "lenin@soviet.org" (update-records [employee] :av-pairs '(([email] "v.lenin@soviet.org")) :where [= [emplid] 1]) => (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t) => (#<EMPLOYEE {48149995}>) (slot-value (car *) 'email) => "lenin@soviet.org" (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :refresh t) Details for Vladimir Lenin have been updated from the database. => (#<EMPLOYEE {48149995}>) (slot-value (car *) 'email) => "v.lenin@soviet.org" Side Effects The user hook function may cause side effects. Exceptional Situations None. See Also select Notes None. DELETE-INSTANCE-RECORDS Delete SQL records represented by a View Class object. Function Syntax delete-instance-records object => Arguments and Values object An instance of a View Class. Description Deletes the records represented by object in the appropriate table of the database associated with object. If object is not yet associated with a database, an error is signalled. Examples (def-view-class tab () ((a :initarg :a :type integer :db-kind :key) (b :initarg :b :type string))) => #<Standard-Db-Class TAB {49B01845}> (create-view-from-class 'tab) => (defvar obj (let ((*db-auto-sync* t)) (make-instance 'tab :a 5 :b "the string"))) => OBJ (start-sql-recording :type :both) => (delete-instance-records obj) ;; 2004-07-17 11:07:19 foo/bar/baz => DELETE FROM tab WHERE tab.a = 5 ;; 2004-07-17 11:07:19 foo/bar/baz <= T => Side Effects Deletes data from the SQL database. Affected by Permissions granted by the SQL database to the user in the database connection. Exceptional Situations An exception may be signaled if the database connection user does not have sufficient privileges to modify the database. An error of type sql-database-error is signalled if object is not associated with an active database. See Also update-records delete-records update-records-from-instance Notes Instances are referenced in the database by values stored in the key slots. If delete-records-from-instance is called with an instance of a class that does not contain any keys, then all records in that table will be deleted. UPDATE-RECORDS-FROM-INSTANCE Update database from view class object. Function Syntax update-records-from-instance object &key database => Arguments and Values object An instance of a View Class. database database object. This will default to the value of *default-database*. Description Using an instance of a View Class, object, update the table that stores its instance data. database specifies the database in which the update is made only if object is not associated with a database. In this case, a record is created in the appropriate table of database using values from the slot values of object, and object becomes associated with database. Examples (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) => ("lenin@soviet.org") (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t))) => *E1* (slot-value *e1* 'email) => "lenin@soviet.org" (setf (slot-value *e1* 'email) "v.lenin@soviet.org") => "v.lenin@soviet.org" (update-records-from-instance *e1*) => (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) => ("v.lenin@soviet.org") Side Effects Modifies the database. Affected by Nothing. Exceptional Situations Database errors. See Also update-record-from-slot update-record-from-slots update-records Notes None. UPDATE-RECORD-FROM-SLOT Updates database from slot value. Function Syntax update-record-from-slot object slot &key database => Arguments and Values object An instance of a View Class. slot The name of a slot in object. database A database object. This will default to the value of *default-database*. Description Updates the value stored in the column represented by the slot, specified by the CLOS slot name slot, of View Class instance object. database specifies the database in which the update is made only if object is not associated with a database. In this case, a record is created in database and the attribute represented by slot is initialised from the value of the supplied slots with other attributes having default values. Furthermore, object becomes associated with database. Examples (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) => ("lenin@soviet.org") (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t))) => *E1* (slot-value *e1* 'email) => "lenin@soviet.org" (setf (slot-value *e1* 'email) "v.lenin@soviet.org") => "v.lenin@soviet.org" (update-record-from-slot *e1* 'email) => (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t) => ("v.lenin@soviet.org") Side Effects Modifies database. Affected By Nothing. Exceptional Situations Database errors. See Also update-record-from-slots update-records-from-instance Notes None. UPDATE-RECORD-FROM-SLOTS Update database from slots of view class object. function syntax update-record-from-slots object slots &key database => Arguments and Values object An instance of a View Class. slots A list of slot names in object. database A database object. This will default to the value of *default-database*. Description Updates the values stored in the columns represented by the slots, specified by the clos slot names slots, of View Class instance object. database specifies the database in which the update is made only if object is not associated with a database. In this case, a record is created in the appropriate table of database and the attributes represented by slots are initialised from the values of the supplied slots with other attributes having default values. Furthermore, object becomes associated with database. Examples (select [last-name] [email] :from [employee] :where [= [emplid] 1] :field-names nil) => (("Lenin" "lenin@soviet.org")) (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t))) => *E1* (slot-value *e1* 'last-name) => "Lenin" (slot-value *e1* 'email) => "lenin@soviet.org" (setf (slot-value *e1* 'last-name) "Ivanovich") => "Ivanovich" (setf (slot-value *e1* 'email) "v.ivanovich@soviet.org") => "v.ivanovich@soviet.org" (update-record-from-slots *e1* '(email last-name)) => (select [last-name] [email] :from [employee] :where [= [emplid] 1] :field-names nil) => (("Ivanovich" "v.ivanovich@soviet.org")) Side Effects Modifies the SQL database. Affected by Nothing. Exceptional Situations Database errors. See Also update-record-from-slot update-records-from-instance Notes None. UPDATE-INSTANCE-FROM-RECORDS Update slot values from database. Function Syntax update-instance-from-records object &key database => object Arguments and Values object An instance of a View Class. database A database object. This will default to the value of *default-database*. Description Updates the slot values of the View Class instance object using the attribute values of the appropriate table of database which defaults to the database associated with object or, if object is not associated with a database, *default-database*. Join slots are updated but instances of the class on which the join is made are not updated. Examples (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t))) => *E1* (slot-value *e1* 'email) => "lenin@soviet.org" (update-records [employee] :av-pairs '(([email] "v.lenin@soviet.org")) :where [= [emplid] 1]) => (update-instance-from-records *e1*) => #<EMPLOYEE {4806B53D}> (slot-value *e1* 'email) => "v.lenin@soviet.org" Side Effects Slot values of object may be modified. Affected by Data in SQL database. Exceptional Situations If database is not able to be read. See Also update-slot-from-record update-objects-joins Notes None. UPDATE-SLOT-FROM-RECORD Update objects slot from database. Function Syntax update-slot-from-record object slot &key database => object Arguments and Values object An instance of a View Class. slot The name of a slot in object. database A database object. This will default to the value of *default-database*. Description Updates the slot value, specified by the CLOS slot name slot, of the View Class instance object using the attribute values of the appropriate table of database which defaults to the database associated with object or, if object is not associated with a database, *default-database*. Join slots are updated but instances of the class on which the join is made are not updated. Examples (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t))) => *E1* (slot-value *e1* 'email) => "lenin@soviet.org" (update-records [employee] :av-pairs '(([email] "v.lenin@soviet.org")) :where [= [emplid] 1]) => (update-slot-from-record *e1* 'email) => #<EMPLOYEE {4806B53D}> (slot-value *e1* 'email) => "v.lenin@soviet.org" Side Effects Modifies the slot value of the object. Affected by Data in SQL database. Exceptional Situations Database errors. See Also update-instance-from-records update-objects-joins Notes None. UPDATE-OBJECTS-JOINS Updates joined slots of objects. Function Syntax update-objects-joins objects &key slots force-p class-name max-len => Arguments and Values objects A list of instances of a View Class. slots * :immediate (default) - refresh join slots with :retrieval :immediate * :deferred - refresh join slots created with :retrieval :deferred * :all,t - refresh all join slots regardless of :retrieval * list of symbols - which explicit slots to refresh * a single symobl - what slot to refresh force-p A Boolean, defaulting to &t;. class-name A list of instances of a View Class. max-len A non-negative integer or &nil; defaulting to *default-update-objects-max-len*. When non-nil this is essentially a batch size for the max number of objects to query from the database at a time. If we need more than max-len we loop till we have all the objects Description Updates from the records of the appropriate database tables the join slots specified by SLOTS in the supplied list of View Class instances OBJECTS. A simpler method of causing a join-slot to be requeried is to set it to unbound, then request it again. This function has efficiency gains where join-objects are shared among the `objects` (querying all join-objects, then attaching them appropriately to each of the `objects`) Examples (defvar *addresses* (select 'deferred-employee-address :order-by [ea_join aaddressid] :flatp t)) => *ADDRESSES* (slot-boundp (car *addresses*) 'address) => NIL (update-objects-joins *addresses*) => (slot-boundp (car *addresses*) 'address) => T (slot-value (car *addresses*) 'address) => #<ADDRESS {480B0F1D}> Side Effects The slot values of objects are modified. Affected by *default-update-objects-max-len* Exceptional Situations Database errors. See Also *default-update-objects-max-len* update-instance-from-records update-slot-from-record Notes None. cl-sql-6.7.2/doc/TODO0000644000175000017500000000147211746263021013176 0ustar kevinkevinDOCUMENTATION TO DO LIST 1. Variances from CommonSQL (Ideally, this will be extremely minimal) 2. Underdocumented CommonSQL features: - Retrieval immediate - SQL operators: ||, SUBSTR, MINUS, INTERSECT, UNION, NVL 3. CLSQL extensions to CommonSQL - SQL operators: group-by, limit, not-null, ==, is, having, the, uplike, view-class, coalesce, except, exists, substring, concat - SELECT: additional keyword arguments accepted include :INNER-JOIN and :ON. 4. Documenting lower level, non-CommonSQL functions (some of this is already done). - connection pools - database-query-result-set 5. Notes on any peculiarities of each of the backends (e.g., unsupported features, notable extensions etc.). - MYSQL - SQLITE - ODBC - ORACLE 6. Incorporate the threading-warnings.txt into the docs. cl-sql-6.7.2/doc/global-index.xml0000644000175000017500000002156210667176647015621 0ustar kevinkevin %myents; ]> Index Alphabetical Index for package CLSQL Clickable index of all symbols *BACKEND-WARNING-BEHAVIOR* *CACHE-TABLE-QUERIES-DEFAULT* *CONNECT-IF-EXISTS* *DB-AUTO-SYNC* *DEFAULT-DATABASE* *DEFAULT-DATABASE-TYPE* *DEFAULT-UPDATE-OBJECTS-MAX-LEN* *DEFAULT-STRING-LENGTH* *INITIALIZED-DATABASE-TYPES* ADD-SQL-STREAM ADD-TRANSACTION-COMMIT-HOOK ADD-TRANSACTION-ROLLBACK-HOOK ATTRIBUTE-TYPE CACHE-TABLE-QUERIES COMMIT CONNECT CONNECTED-DATABASES CREATE-DATABASE CREATE-INDEX CREATE-SEQUENCE CREATE-TABLE CREATE-VIEW CREATE-VIEW-FROM-CLASS DATABASE DATABASE-NAME DATABASE-NAME-FROM-SPEC DATABASE-TYPE DEF-VIEW-CLASS DELETE-INSTANCE-RECORDS DELETE-RECORDS DELETE-SQL-STREAM DESTROY-DATABASE DISABLE-SQL-READER-SYNTAX DISCONNECT DISCONNECT-POOLED DO-QUERY DROP-INDEX DROP-SEQUENCE DROP-TABLE DROP-VIEW DROP-VIEW-FROM-CLASS ENABLE-SQL-READER-SYNTAX EXECUTE-COMMAND FIND-DATABASE IN-TRANSACTION-P INDEX-EXISTS-P INITIALIZE-DATABASE-TYPE INSERT-RECORDS INSTANCE-REFRESHED LIST-ATTRIBUTE-TYPES LIST-ATTRIBUTES LIST-CLASSES LIST-DATABASES LIST-INDEXES LIST-SEQUENCES LIST-SQL-STREAMS LIST-TABLES LIST-VIEWS LOCALLY-DISABLE-SQL-READER-SYNTAX LOCALLY-ENABLE-SQL-READER-SYNTAX LOOP-FOR-AS-TUPLES MAP-QUERY PROBE-DATABASE QUERY RECONNECT RESTORE-SQL-READER-SYNTAX-STATE ROLLBACK SELECT SEQUENCE-EXISTS-P SEQUENCE-LAST SEQUENCE-NEXT SET-AUTOCOMMIT SET-SEQUENCE-POSITION SQL SQL-CONDITION SQL-CONNECTION-ERROR SQL-DATABASE-DATA-ERROR SQL-DATABASE-ERROR SQL-DATABASE-WARNING SQL-ERROR SQL-EXPRESSION SQL-FATAL-ERROR SQL-OPERATION SQL-OPERATOR SQL-RECORDING-P SQL-STREAM SQL-TEMPORARY-ERROR SQL-TIMEOUT-ERROR SQL-USER-ERROR SQL-WARNING START-SQL-RECORDING START-TRANSACTION STATUS STOP-SQL-RECORDING TABLE-EXISTS-P TRUNCATE-DATABASE UPDATE-INSTANCE-FROM-RECORDS UPDATE-OBJECTS-JOINS UPDATE-RECORD-FROM-SLOT UPDATE-RECORD-FROM-SLOTS UPDATE-RECORDS UPDATE-RECORDS-FROM-INSTANCE UPDATE-SLOT-FROM-RECORD VIEW-EXISTS-P WITH-DATABASE WITH-DEFAULT-DATABASE WITH-TRANSACTION cl-sql-6.7.2/doc/catalog-redhat.xml0000644000175000017500000000265310667176647016133 0ustar kevinkevin cl-sql-6.7.2/doc/glossary.xml0000644000175000017500000001315510667176647015116 0ustar kevinkevin %myents; ]> This glossary is still very thinly populated, and not all references in the main text have been properly linked and coordinated with this glossary. This will hopefully change in future revisions. Attribute A property of objects stored in a database table. Attributes are represented as columns (or fields) in a table. Active database Connection Column Data Definition Language (DDL) The subset of SQL used for defining and examining the structure of a database. Data Manipulation Language (DML) The subset of SQL used for inserting, deleting, updating and fetching data in a database. database Database Object An object of type database. Field Field Types Specifier A value that specifies the type of each field in a query. Foreign Function Interface (FFI) An interface from Common Lisp to a external library which contains compiled functions written in other programming languages, typically C. Query An SQL statement which returns a set of results. RDBMS A Relational DataBase Management System (RDBMS) is a software package for managing a database in which the data is defined, organised and accessed as rows and columns of a table. Record A sequence of attribute values stored in a database table. Row Structured Query Language (SQL) An ANSI standard language for storing and retrieving data in a relational database. SQL Expression Either a string containing a valid SQL statement, or an object of type sql-expression. Table A collection of data which is defined, stored and accessed as tuples of attribute values (i.e., rows and columns). Transaction An atomic unit of one or more SQL statements of which all or none are successfully executed. Tuple View A table display whose structure and content are derived from an existing table via a query. View Class The class standard-db-object or one of its subclasses. cl-sql-6.7.2/doc/ref-ooddl.xml0000644000175000017500000011103312303270414015070 0ustar kevinkevin %myents; ]> Object Oriented Data Definition Language (OODDL) The Object Oriented Data Definition Language (OODDL) provides access to relational SQL tables using Common Lisp Object System (CLOS) objects. SQL tables are mapped to CLOS objects with the SQL columns being mapped to slots of the CLOS object. The mapping between SQL tables and CLOS objects is defined with the macro def-view-class. SQL tables are created with create-view-from-class and SQL tables can be deleted with drop-view-from-class. The above functions refer to the Lisp view of the SQL table. This Lisp view should not be confused with SQL VIEW statement. STANDARD-DB-OBJECT Superclass for all &clsql; View Classes. Class Class Precedence List standard-db-object standard-object t Description This class is the superclass of all &clsql; View Classes. Class details (defclass STANDARD-DB-OBJECT ()(...)) Slots slot VIEW-DATABASE is of type (OR NULL DATABASE) which stores the associated database for the instance. *DEFAULT-STRING-LENGTH* Default length of SQL strings. Variable Value Type Fixnum Initial Value 255 Description If a slot of a class defined by def-view-class is of the type string or varchar and does not have a length specified, then the value of this variable is used as SQL length. Examples (let ((*default-string-length* 80)) (def-view-class s80 () ((a :type string) (b :type (string 80)) (c :type varchar)))) => #<Standard-Db-Class S80 {480A431D}> (create-view-from-class 's80) => (table-exists-p [s80]) => T The above code causes a SQL table to be created with the SQL command CREATE TABLE (A VARCHAR(80), B CHAR(80), C VARCHAR(80)) Affected By Some SQL backends do not support varchar lengths greater than 255. See Also None. Notes This is a CLSQL extension to the CommonSQL API. CREATE-VIEW-FROM-CLASS Create a SQL table from a View Class. Function Syntax create-view-from-class view-class-name &key database transactions => Arguments and Values view-class-name The name of a View Class that has been defined with def-view-class. database The database in which to create the SQL table. This will default to the value of *default-database*. transactions When &nil; specifies that a table type which does not support transactions should be used. Description Creates a table as defined by the View Class view-class-name in database. Examples (def-view-class foo () ((a :type (string 80)))) => #<Standard-Db-Class FOO {4807F7CD}> (create-view-from-class 'foo) => (list-tables) => ("FOO") Side Effects Causes a table to be created in the SQL database. Affected by Most SQL database systems will signal an error if a table creation is attempted when a table with the same name already exists. The SQL user, as specified in the database connection, must have sufficient permission for table creation. Exceptional Situations A condition will be signaled if the table can not be created in the SQL database. See Also def-view-class drop-view-from-class Notes Currently, only &mysql; supports transactionless tables. &clsql; provides the ability to create such tables for applications which would benefit from faster table access and do not require transaction support. The case of the table name is determined by the type of the database. &mysql;, for example, creates databases in upper-case while &postgresql; uses lowercase. DEF-VIEW-CLASS Defines CLOS classes with mapping to SQL database. Macro Syntax def-view-class name superclasses slots &rest class-options => class Arguments and Values name The class name. superclasses The superclasses for the defined class. slots The class slot definitions. class options The class options. class The defined class. Slot Options :db-kind - specifies the kind of database mapping which is performed for this slot and defaults to :base which indicates that the slot maps to an ordinary column of the database table. A :db-kind value of :key indicates that this slot is a special kind of :base slot which maps onto a column which is one of the unique keys for the database table, the value :join indicates this slot represents a join onto another View Class which contains View Class objects, and the value :virtual indicates a standard CLOS slot which does not map onto columns of the database table. :db-info - if a slot is specified with :db-kind :join, the slot option :db-info contains a property list which specifies the nature of the join. The valid members of the list are: :join-class class-name - the name of the class to join on. :home-key slot-name - the name of the slot of this class for joining :foreign-key slot-name - the name of the slot of the :join-class for joining :target-slot target-slot - this is an optional parameter. If specified, then the join slot of the defining class will contain instances of this target slot rather than of the join class. This can be useful when the :join-class is an intermediate class in a many-to-many relationship and the application is actually interested in the :target-slot. :retrieval time - The default value is :deferred, which defers filling this slot until the value is accessed. The other valid value is :immediate which performs the SQL query when the instance of the class is created. In this case, the :set is automatically set to &nil; :set set - This controls what is stored in the join slot. The default value is &t;. When set is &t; and target-slot is undefined, the join slot will contain a list of instances of the join class. Whereas, if target-slot is defined, then the join slot will contain a list of pairs of (target-value join-instance). When set is &nil;, the join slot will contain a single instances. :type - for slots of :db-kind :base or :key, the :type slot option has a special interpretation such that Lisp types, such as string, integer and float are automatically converted into appropriate SQL types for the column onto which the slot maps. This behaviour may be overridden using the :db-type slot option. The valid values are: string - a variable length character field up to *default-string-length* characters. (string n) - a fixed length character field n characters long. varchar - a variable length character field up to *default-string-length* characters. (varchar n) - a variable length character field up to n characters in length. char - a single character field integer - signed integer at least 32-bits wide (integer n) float (float n) long-float number (number n) (number n p) tinyint - An integer column 8-bits wide. [not supported by all database backends] smallint - An integer column 16-bits wide. [not supported by all database backends] bigint - An integer column 64-bits wide. [not supported by all database backends] universal-time - an integer field sufficiently wide to store a universal-time. On most databases, a slot of this type assigned a SQL type of BIGINT wall-time - a slot which stores a date and time in a SQL timestamp column. &clsql; provides a number of time manipulation functions to support objects of type wall-time. date - a slot which stores the date (without any time of day resolution) in a column. &clsql; provides a number of time manipulation functions that operate on date values. duration - stores a duration structure. &clsql; provides routines for wall-time and duration processing. boolean - stores a &t; or &nil; value. generalized-boolean - similar to a boolean in that either a &t; or &nil; value is stored in the SQL database. However, any Lisp object can be stored in the Lisp object. A Lisp value of &nil; is stored as FALSE in the database, any other Lisp value is stored as TRUE. keyword - stores a keyword symbol - stores a symbol list - stores a list by writing it to a string. The items in the list must be able to be readable written. vector - stores a vector similarly to list array - stores a array similarly to list :column - specifies the name of the SQL column which the slot maps onto, if :db-kind is not :virtual, and defaults to the slot name. If the slot name is used for the SQL column name, any hypens in the slot name are converted to underscore characters. :void-value - specifies the value to store in the Lisp instance if the SQL value is NULL and defaults to NIL. :db-constraints - is a keyword symbol representing an SQL column constraint expression or a list of such symbols. The following column constraints are supported: :not-null, :primary-key, :unique, :unsigned (&mysql; specific), :zerofill (&mysql; specific) and :auto-increment (&mysql; specific). :db-type - a string to specify the SQL column type. If specified, this string overrides the SQL column type as computed from the :type slot value. :db-reader - If a string, then when reading values from the database, the string will be used for a format string, with the only value being the value from the database. The resulting string will be used as the slot value. If a function then it will take one argument, the value from the database, and return the value that should be put into the slot. If a symbol, then the symbol-function of the symbol will be used. :db-writer - If a string, then when reading values from the slot for the database, the string will be used for a format string, with the only value being the value of the slot. The resulting string will be used as the column value in the database. If a function then it will take one argument, the value of the slot, and return the value that should be put into the database. If a symbol, then the symbol-function of the symbol will be used. Class Options :base-table - specifies the name of the SQL database table. The default value is the class name. Like slot names, hypens in the class name are converted to underscore characters. :normalizedp - specifies whether this class uses normalized inheritance from parent classes. Defaults to nil, i.e. non-normalized schemas. When true, SQL database tables that map to this class and parent classes are joined on their primary keys to get the full set of database columns for this class. This means that the primary key of the base class will be copied to all subclasses as we insert so that all parent classes of an instance will have the same value in their primary key slots (see tests/ds-nodes.lisp and oodml.lisp) Description Creates a View Class called name whose slots slots can map onto the attributes of a table in a database. If superclasses is &nil; then the superclass of class will be standard-db-object, otherwise superclasses is a list of superclasses for class which must include standard-db-object or a descendent of this class. Normalized inheritance schemas Specifying that :normalizedp is T tells &clsql; to normalize the database schema for inheritance. What this means is shown in the examples below. With :normalizedp equal to NIL (the default) the class inheritance would result in the following: (def-view-class node () ((title :accessor title :initarg :title :type (varchar 240)))) SQL table NODE: +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | TITLE | varchar(240) | YES | | NULL | | +-------+--------------+------+-----+---------+-------+ (def-view-class user (node) ((user-id :accessor user-id :initarg :user-id :type integer :db-kind :key :db-constraints (:not-null)) (nick :accessor nick :initarg :nick :type (varchar 64)))) SQL table USER: +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | USER_ID | int(11) | NO | PRI | | | | NICK | varchar(64) | YES | | NULL | | | TITLE | varchar(240) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ Using :normalizedp T, both view-classes need a primary key to join them on: (def-view-class node () ((node-id :accessor node-id :initarg :node-id :type integer :db-kind :key :db-constraints (:not-null)) (title :accessor title :initarg :title :type (varchar 240)))) SQL table NODE: +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | NODE_ID | int(11) | NO | PRI | | | | TITLE | varchar(240) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ (def-view-class user (node) ((user-id :accessor user-id :initarg :user-id :type integer :db-kind :key :db-constraints (:not-null)) (nick :accessor nick :initarg :nick :type (varchar 64))) (:normalizedp t)) SQL table USER: +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | USER_ID | int(11) | NO | PRI | | | | NICK | varchar(64) | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ In this second case, all slots of the view-class 'node are also available in view-class 'user, and can be used as one would expect. For example, with the above normalized view-classes 'node and 'user, and SQL tracing turned on: CLSQL> (setq test-user (make-instance 'user :node-id 1 :nick "test-user" :title "This is a test user")) ]]> CLSQL> (update-records-from-instance test-user :database db) INSERT INTO NODE (NODE_ID,TITLE) VALUES (1,'This is a test user') ;; .. <= T ;; .. => INSERT INTO USER (USER_ID,NICK) VALUES (1,'test-user') ;; .. <= T 1 ]]> CLSQL> (node-id test-user) 1 CLSQL> (title test-user) "This is a test user" CLSQL> (nick test-user) "test-user" Notes from a refactor of this code. There are many assumptions that need to be met for normalized classes to work * The each of the classes should have its own single key column (of a different name) that will contain an identical value. EG: node has a node-id, setting which is a node has a node-id and a setting-id which must be equal. You cannot use node-id as the primary key on both tables (as I would have expected). The exception to this seems to be if your class has no slots at all, then you dont need to have a single key column, because your class is fully represented in the db by its parent(s) * more than one parent class per normalized class should be considered experimental and untested (vaya con Dios) * There are a few code paths that just dont pay any attention to normalized classes eg: delete-records-for-instance Examples The following examples are from the &clsql; test suite. (def-view-class person (thing) ((height :db-kind :base :accessor height :type float :initarg :height) (married :db-kind :base :accessor married :type boolean :initarg :married) (birthday :type clsql:wall-time :initarg :birthday) (bd-utime :type clsql:universal-time :initarg :bd-utime) (hobby :db-kind :virtual :initarg :hobby :initform nil))) (def-view-class employee (person) ((emplid :db-kind :key :db-constraints :not-null :type integer :initarg :emplid) (groupid :db-kind :key :db-constraints :not-null :type integer :initarg :groupid) (first-name :accessor first-name :type (varchar 30) :initarg :first-name) (last-name :accessor last-name :type (varchar 30) :initarg :last-name) (email :accessor employee-email :type (varchar 100) :initarg :email) (ecompanyid :type integer :initarg :companyid) (company :accessor employee-company :db-kind :join :db-info (:join-class company :home-key ecompanyid :foreign-key companyid :set nil)) (managerid :type integer :initarg :managerid) (manager :accessor employee-manager :db-kind :join :db-info (:join-class employee :home-key managerid :foreign-key emplid :set nil)) (addresses :accessor employee-addresses :db-kind :join :db-info (:join-class employee-address :home-key emplid :foreign-key aemplid :target-slot address :set t))) (:base-table employee)) (def-view-class company () ((companyid :db-kind :key :db-constraints :not-null :type integer :initarg :companyid) (groupid :db-kind :key :db-constraints :not-null :type integer :initarg :groupid) (name :type (varchar 100) :initarg :name) (presidentid :type integer :initarg :presidentid) (president :reader president :db-kind :join :db-info (:join-class employee :home-key presidentid :foreign-key emplid :set nil)) (employees :reader company-employees :db-kind :join :db-info (:join-class employee :home-key (companyid groupid) :foreign-key (ecompanyid groupid) :set t)))) (def-view-class address () ((addressid :db-kind :key :db-constraints :not-null :type integer :initarg :addressid) (street-number :type integer :initarg :street-number) (street-name :type (varchar 30) :void-value "" :initarg :street-name) (city :column "city_field" :void-value "no city" :type (varchar 30) :initarg :city) (postal-code :column zip :type integer :void-value 0 :initarg :postal-code)) (:base-table addr)) ;; many employees can reside at many addressess (def-view-class employee-address () ((aemplid :type integer :initarg :emplid) (aaddressid :type integer :initarg :addressid) (verified :type boolean :initarg :verified) (address :db-kind :join :db-info (:join-class address :home-key aaddressid :foreign-key addressid :retrieval :immediate))) (:base-table "ea_join")) (def-view-class deferred-employee-address () ((aemplid :type integer :initarg :emplid) (aaddressid :type integer :initarg :addressid) (verified :type boolean :initarg :verified) (address :db-kind :join :db-info (:join-class address :home-key aaddressid :foreign-key addressid :retrieval :deferred :set nil))) (:base-table "ea_join")) Side Effects Creates a new CLOS class. Affected by Nothing. Exceptional Situations None. See Also create-view-from-class standard-db-object drop-view-from-class Notes The actual SQL type for a column depends up the database type in which the SQL table is stored. As an example, the view class type (varchar 100) specifies a SQL column type VARCHAR(100) in &mysql; and a column type VARCHAR2(100) in &oracle; The actual lisp type for a slot may be different than the value specified by the :type attribute. For example, a slot declared with ":type (string 30)" actually sets the slots Lisp type as (or null string). This is to allow a &nil; value or a string shorter than 30 characters to be stored in the slot. DROP-VIEW-FROM-CLASS Delete table from SQL database. Function Syntax drop-view-from-class view-class-name &key database => Arguments and Values view-class-name The name of the View Class. database database object. This will default to the value of *default-database*. Description Removes a table defined by the View Class view-class-name from database which defaults to *default-database*. Examples (list-tables) => ("FOO" "BAR") (drop-view-from-class 'foo) => (list-tables) => ("BAR") Side Effects Deletes a table from the SQL database. Affected by Whether the specified table exists in the SQL database. Exceptional Situations A condition may be signalled if the table does not exist in the SQL database or if the SQL connection does not have sufficient permissions to delete tables. See Also create-view-from-class def-view-class Notes None. LIST-CLASSES List classes for tables in SQL database. Function Syntax list-classes &key test root-class database => classes Arguments and Values test a function used to filter the search. By default, identity is used which will return all classes. root-class specifies the root class to the search. By default, standard-db-object is used which is the root for all view classes. database The database to search for view classes. This will default to the value of *default-database*. classes List of view classes. Description Returns a list of all the View Classes which have been defined in the Lisp session and are connected to database and which descended from the class root-class and which satisfy the function test. Examples (list-classes) => (#<clsql-sys::standard-db-class big> #<clsql-sys::standard-db-class employee-address> #<clsql-sys::standard-db-class address> #<clsql-sys::standard-db-class company> #<clsql-sys::standard-db-class employee>) (list-classes :test #'(lambda (c) (> (length (symbol-name (class-name c))) 3))) => (#<clsql-sys::standard-db-class employee-address> #<clsql-sys::standard-db-class address> #<clsql-sys::standard-db-class company> #<clsql-sys::standard-db-class employee>) Side Effects None. Affected by Which view classes have been defined in the Lisp session. Exceptional Situations None. See Also def-view-class Notes None. cl-sql-6.7.2/doc/Makefile0000644000175000017500000000665111345753563014164 0ustar kevinkevin#!/usr/bin/make ############################################################################### # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for the clsql documentation # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ############################################################################### DOCFILE_BASE_DEFAULT:=clsql DOCFILE_EXT_DEFAULT:=xml # Standard docfile processing DEBIAN=$(shell expr "`cat /etc/issue 2> /dev/null`" : '.*Debian.*') SUSE=$(shell expr "`cat /etc/issue 2> /dev/null`" : '.*SuSE.*') SUSE91=$(shell expr "`cat /etc/issue 2> /dev/null`" : '.*SuSE Linux 9.1.*') REDHAT=$(shell expr "`cat /etc/issue 2> /dev/null`" : '.*Red Hat.*') MANDRAKE=$(shell expr "`cat /etc/issue 2> /dev/null`" : '.*Mandrake.*') DARWIN=$(shell expr "`uname -a`" : '.*Darwin.*') UBUNTU=$(shell expr "`cat /etc/issue 2> /dev/null`" : '.*Ubuntu.*') ifneq (${DEBIAN},0) OS:=debian else ifneq (${SUSE91},0) OS=suse91 else ifneq (${SUSE},0) OS=suse else ifneq (${REDHAT},0) OS=redhat else ifneq (${MANDRAKE},0) OS=mandrake else ifneq (${DARWIN},0) OS=darwin else ifneq (${UBUNTU},0) OS:=debian endif endif endif endif endif endif endif ifndef DOCFILE_BASE DOCFILE_BASE=${DOCFILE_BASE_DEFAULT} endif ifndef DOCFILE_EXT DOCFILE_EXT=${DOCFILE_EXT_DEFAULT} endif DOCFILE:=${DOCFILE_BASE}.${DOCFILE_EXT} FOFILE:=${DOCFILE_BASE}.fo PDFFILE:=${DOCFILE_BASE}.pdf PSFILE:=${DOCFILE_BASE}.ps DVIFILE:=${DOCFILE_BASE}.dvi TXTFILE:=${DOCFILE_BASE}.txt HTMLFILE:=${DOCFILE_BASE}.html TMPFILES:=${DOCFILE_BASE}.aux ${DOCFILE_BASE}.out ${DOCFILE_BASE}.log DOCFILES:=$(shell echo *.xml *.xsl) ifeq ($(XSLTPROC),) XSLTPROC:=xsltproc endif CATALOG:=`pwd`/catalog-${OS}.xml CHECK:=XML_CATALOG_FILES="$(CATALOG)" xmllint --noout --xinclude --postvalid $(DOCFILE) || exit 1 .PHONY: all all: html pdf .PHONY: dist dist: html pdf .PHONY: doc doc: html pdf .PHONY: check check: @echo "Operating system detected: ${OS}" @$(CHECK) .PHONY: html html: html.tar.gz html.tar.gz: $(DOCFILES) Makefile @rm -rf html @mkdir html @XML_CATALOG_FILES="$(CATALOG)" $(XSLTPROC) --stringparam chunker.output.encoding UTF-8 \ --xinclude --output html/ html_chunk.xsl $(DOCFILE) @GZIP='-9' tar czf html.tar.gz html .PHONY: fo fo: ${FOFILE} ${FOFILE}: $(DOCFILES) Makefile @XML_CATALOG_FILES="$(CATALOG)" xsltproc --xinclude --stringparam fop1.extensions 1 --output $(FOFILE) fo.xsl $(DOCFILE) .PHONY: pdf pdf: ${PDFFILE} ${PDFFILE}: ${DOCFILES} Makefile @$(MAKE) fo @fop $(FOFILE) -pdf $(PDFFILE) > /dev/null .PHONY: dvi dvi: ${DVIFILE} .PHONY: ps ps: ${PSFILE} ${PSFILE}: ${DOCFILES} Makefile @$(MAKE) fo @fop $(FOFILE) -ps $(PSFILE) > /dev/null .PHONY: txt txt: ${TXTFILE} ${TXTFILE}: ${FOFILE} @XML_CATALOG_FILES="$(CATALOG)" xsltproc --xinclude --output ${HTMLFILE} html.xsl $(DOCFILE) lynx -dump ${HTMLFILE} > ${TXTFILE} .PHONY: clean clean: @rm -f *~ *.bak *.orig \#*\# .\#* texput.log @rm -rf html ${PSFILE} ${HTMLFILE} @rm -f ${TMPFILES} ${FOFILE} @rm -f ${DVIFILE} ${TXTFILE} .PHONY: distclean distclean: clean cl-sql-6.7.2/doc/preface.xml0000644000175000017500000000113510667176647014653 0ustar kevinkevin %myents; ]> Preface This guide provides reference to the features of &clsql;. The first chapter provides an introduction to &clsql; and installation instructions. The reference sections document all user accessible symbols with examples of usage. There is a glossary of commonly used terms with their definitions. cl-sql-6.7.2/doc/entities.inc0000644000175000017500000000324110667176647015043 0ustar kevinkevinASDF"> CLOCC"> CCLAN"> UFFI"> FFI"> CLSQL"> MaiSQL"> SQL"> UncommonSQL"> CommonSQL"> MySQL"> PostgreSQL"> SQLite version 2"> SQLite version 3"> Oracle"> ODBC"> AODBC"> CMUCL"> SCL"> MD5"> SBCL"> OpenMCL"> Lispworks"> AllegroCL"> ANSI Common Lisp"> T"> NIL"> NULL"> C"> UNIX"> Microsoft Windows"> cl-sql-6.7.2/doc/README0000644000175000017500000000057111345753563013377 0ustar kevinkevinBuilding the documentation: You will need the following packages: * xsltproc * docbook * docbook-xml * docbook-xsl * docbook-xsl-doc-html * fop These are the debian/ubuntu package names; on other systems there are probably similar. General Build: > make Check the validity of the source > make check Build just the html: > make html Build just the pdf: > make pdf cl-sql-6.7.2/clsql-postgresql.asd0000644000175000017500000000304011332141035015731 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-postgresql.asd ;;;; Purpose: ASDF file for CLSQL PostgresSQL backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-postgresql-system (:use #:asdf #:cl)) (in-package #:clsql-postgresql-system) #+(and allegro macosx) (push "so" excl::*load-foreign-types*) (defsystem clsql-postgresql :name "cl-sql-postgresql" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp PostgreSQL API Driver" :long-description "cl-sql-postgresql package provides a the database driver for the PostgreSQL API." :depends-on (clsql clsql-uffi) :components ((:module :db-postgresql :components ((:file "postgresql-package") (:file "postgresql-loader" :depends-on ("postgresql-package")) (:file "postgresql-api" :depends-on ("postgresql-loader")) (:file "postgresql-sql" :depends-on ("postgresql-api")))))) cl-sql-6.7.2/db-postgresql-socket/0000755000175000017500000000000014327126007016011 5ustar kevinkevincl-sql-6.7.2/db-postgresql-socket/postgresql-socket-api.lisp0000644000175000017500000011011412562771754023156 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-api.lisp ;;;; Purpose: Low-level PostgreSQL interface using sockets ;;;; Authors: Kevin M. Rosenberg based on original code by Pierre R. Mai ;;;; Created: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:postgresql-socket) ;; KMR: 2011-06-12 ;; FIXME: The file has code specific to sb-unicode and CCL ;; to assume UTF8 encoded strings. ;; Best fix would be to use the user-specified encoding that is now ;; stored in the database object and use the UFFI 2.x encoding functions ;; to convert strings to/from octet vectors. This allows encoding ;; other than UTF8 and also works on all CL implementations that ;; support wide character strings (uffi:def-enum pgsql-ftype ((:bytea 17) (:int2 21) (:int4 23) (:int8 20) (:float4 700) (:float8 701))) (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :postgresql-socket))) "T if foreign library was able to be loaded successfully. Always true for socket interface" t) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :postgresql-socket))) t) ;;; Message I/O stuff (defmacro define-message-constants (description &rest clauses) (assert (evenp (length clauses))) (loop with seen-characters = nil for (name char) on clauses by #'cddr for char-code = (char-code char) for doc-string = (format nil "~A (~:C): ~A" description char name) if (member char seen-characters) do (error "Duplicate message type ~@C for group ~A" char description) else collect `(defconstant ,name ,char-code ,doc-string) into result-clauses and do (push char seen-characters) finally (return `(progn ,@result-clauses)))) (eval-when (:compile-toplevel :load-toplevel :execute) (define-message-constants "Backend Message Constants" +ascii-row-message+ #\D +authentication-message+ #\R +backend-key-message+ #\K +binary-row-message+ #\B +completed-response-message+ #\C +copy-in-response-message+ #\G +copy-out-response-message+ #\H +cursor-response-message+ #\P +empty-query-response-message+ #\I +error-response-message+ #\E +function-response-message+ #\V +notice-response-message+ #\N +notification-response-message+ #\A +ready-for-query-message+ #\Z +row-description-message+ #\T)) #+scl (declaim (inline read-byte write-byte)) (defun send-socket-value-int32 (socket value) (declare (type stream socket) (type (unsigned-byte 32) value)) (write-byte (ldb (byte 8 24) value) socket) (write-byte (ldb (byte 8 16) value) socket) (write-byte (ldb (byte 8 8) value) socket) (write-byte (ldb (byte 8 0) value) socket) nil) (defun send-socket-value-int16 (socket value) (declare (type stream socket) (type (unsigned-byte 16) value)) (write-byte (ldb (byte 8 8) value) socket) (write-byte (ldb (byte 8 0) value) socket) nil) (defun send-socket-value-int8 (socket value) (declare (type stream socket) (type (unsigned-byte 8) value)) (write-byte (ldb (byte 8 0) value) socket) nil) (defun send-socket-value-char-code (socket value) (declare (type stream socket) (type character value)) (write-byte (ldb (byte 8 0) (char-code value)) socket) nil) (defun send-socket-value-string (socket value) (declare (type stream socket) (type string value)) #-(or sb-unicode ccl) (loop for char across value for code = (char-code char) do (write-byte code socket) finally (write-byte 0 socket)) #+ccl (write-sequence (ccl:encode-string-to-octets value :external-format :utf-8) socket) #+ccl (write-byte 0 socket) #+sb-unicode (write-sequence (sb-ext:string-to-octets value :null-terminate t) socket) nil) (defun send-socket-value-limstring (socket value limit) (declare (type stream socket) (type string value) (type fixnum limit)) (let ((length (length value))) (dotimes (i (min length limit)) (let ((code (char-code (char value i)))) (write-byte code socket))) (dotimes (i (- limit length)) (write-byte 0 socket))) nil) (defun read-socket-value-int32 (socket) (declare (type stream socket)) (declare (optimize (speed 3))) (let ((result 0)) (declare (type (unsigned-byte 32) result)) (setf (ldb (byte 8 24) result) (read-byte socket)) (setf (ldb (byte 8 16) result) (read-byte socket)) (setf (ldb (byte 8 8) result) (read-byte socket)) (setf (ldb (byte 8 0) result) (read-byte socket)) result)) (defun read-socket-value-int16 (socket) (declare (type stream socket)) (let ((result 0)) (declare (type (unsigned-byte 16) result)) (setf (ldb (byte 8 8) result) (read-byte socket)) (setf (ldb (byte 8 0) result) (read-byte socket)) result)) (defun read-socket-value-int8 (socket) (declare (type stream socket)) (read-byte socket)) (defun read-socket-value-string (socket) (declare (type stream socket)) #-(or sb-unicode ccl) (with-output-to-string (out) (loop for code = (read-byte socket) until (zerop code) do (write-char (code-char code) out))) #+ccl (let ((bytes (make-array 64 :element-type '(unsigned-byte 8) :adjustable t :fill-pointer 0))) (loop for code = (read-byte socket) until (zerop code) do (vector-push-extend code bytes)) (ccl:decode-string-from-octets bytes :external-format :utf-8)) #+sb-unicode (let ((bytes (make-array 64 :element-type '(unsigned-byte 8) :adjustable t :fill-pointer 0))) (loop for code = (read-byte socket) until (zerop code) do (vector-push-extend code bytes)) (sb-ext:octets-to-string bytes))) (defmacro define-message-sender (name (&rest args) &rest clauses) (let ((socket-var (gensym)) (body nil)) (dolist (clause clauses) (let* ((type (first clause)) (fn (intern (concatenate 'string (symbol-name '#:send-socket-value-) (symbol-name type))))) (push `(,fn ,socket-var ,@(rest clause)) body))) `(defun ,name (,socket-var ,@args) ,@(nreverse body)))) (define-message-sender send-startup-message (database user &optional (command-line "") (backend-tty "")) (int32 296) ; Length (int32 #x00020000) ; Version 2.0 (limstring database 64) (limstring user 32) (limstring command-line 64) (limstring "" 64) ; Unused (limstring backend-tty 64)) (define-message-sender send-terminate-message () (char-code #\X)) (define-message-sender send-unencrypted-password-message (password) (int32 (+ 5 (length password))) (string password)) (define-message-sender send-query-message (query) (char-code #\Q) (string query)) (define-message-sender send-encrypted-password-message (crypted-password) (int32 (+ 5 (length crypted-password))) (string crypted-password)) (define-message-sender send-cancel-request (pid key) (int32 16) ; Length (int32 80877102) ; Magic (int32 pid) (int32 key)) (defun read-bytes (socket length) "Read a byte array of the given length from a stream." (declare (type stream socket) (type fixnum length) (optimize (speed 3) (safety 0))) (let ((result (make-array length :element-type '(unsigned-byte 8)))) (read-sequence result socket) result)) (defun read-socket-sequence (stream length &optional (allow-wide t)) (declare (stream stream) (optimize (speed 3) (safety 0))) #-(or sb-unicode ccl) (let ((result (make-string length))) (dotimes (i length result) (declare (fixnum i)) (setf (char result i) (code-char (read-byte stream))))) #+ccl (let ((bytes (make-array length :element-type '(unsigned-byte 8)))) (declare (type (simple-array (unsigned-byte 8) (*)) bytes)) (read-sequence bytes stream) (if allow-wide (ccl:decode-string-from-octets bytes :external-format :utf-8) (map 'string #'code-char bytes))) #+sb-unicode (let ((bytes (make-array length :element-type '(unsigned-byte 8)))) (declare (type (simple-array (unsigned-byte 8) (*)) bytes)) (read-sequence bytes stream) (if allow-wide (sb-ext:octets-to-string bytes) (map 'string #'code-char bytes)))) ;;; Support for encrypted password transmission #-scl (eval-when (:compile-toplevel :load-toplevel :execute) (defvar *crypt-library-loaded* nil) (unless *crypt-library-loaded* (uffi:load-foreign-library (uffi:find-foreign-library "libcrypt" '(#+(or 64bit x86-64) "/usr/lib64/" "/usr/lib/" "/usr/local/lib/" "/lib/")) :supporting-libraries '("c")) (setq *crypt-library-loaded* t))) (in-package :postgresql-socket) (uffi:def-function ("crypt" crypt) ((key :cstring) (salt :cstring)) :returning :cstring) (defun crypt-password (password salt) "Encrypt a password for transmission to a PostgreSQL server." (uffi:with-cstring (password-cstring password) (uffi:with-cstring (salt-cstring salt) (uffi:convert-from-cstring (crypt password-cstring salt-cstring))))) ;;;; Condition hierarchy (define-condition postgresql-condition (condition) ((connection :initarg :connection :reader postgresql-condition-connection) (message :initarg :message :reader postgresql-condition-message)) (:report (lambda (c stream) (format stream "~@<~A occurred on connection ~A. ~:@_Reason: ~A~:@>" (type-of c) (postgresql-condition-connection c) (postgresql-condition-message c))))) (define-condition postgresql-error (error postgresql-condition) ()) (define-condition postgresql-fatal-error (postgresql-error) ()) (define-condition postgresql-login-error (postgresql-fatal-error) ()) (define-condition postgresql-warning (warning postgresql-condition) ()) (define-condition postgresql-notification (postgresql-condition) () (:report (lambda (c stream) (format stream "~@" (postgresql-condition-connection c) (postgresql-condition-message c))))) ;;; Structures (defstruct postgresql-connection host port database user password options tty socket pid key) (defstruct postgresql-cursor connection name fields) ;;; Socket stuff (defconstant +postgresql-server-default-port+ 5432 "Default port of PostgreSQL server.") (defvar *postgresql-server-socket-timeout* 60 "Timeout in seconds for reads from the PostgreSQL server.") #+(or cmu scl) (defun open-postgresql-socket (host port) (etypecase host (pathname ;; Directory to unix-domain socket (ext:connect-to-unix-socket (namestring (make-pathname :name ".s.PGSQL" :type (princ-to-string port) :defaults host)))) (string (ext:connect-to-inet-socket host port)))) #+sbcl (defun open-postgresql-socket (host port) (etypecase host (pathname ;; Directory to unix-domain socket (let ((sock (make-instance 'sb-bsd-sockets:local-socket :type :stream))) (sb-bsd-sockets:socket-connect sock (namestring (make-pathname :name ".s.PGSQL" :type (princ-to-string port) :defaults host))) sock)) (string (let ((sock (make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp))) (sb-bsd-sockets:socket-connect sock (sb-bsd-sockets:host-ent-address (sb-bsd-sockets:get-host-by-name host)) port) sock)))) #+(or cmu scl) (defun open-postgresql-socket-stream (host port) (system:make-fd-stream (open-postgresql-socket host port) :input t :output t :element-type '(unsigned-byte 8) :buffering :none :timeout *postgresql-server-socket-timeout*)) #+sbcl (defun open-postgresql-socket-stream (host port) (sb-bsd-sockets:socket-make-stream (open-postgresql-socket host port) :input t :output t :element-type '(unsigned-byte 8))) #+allegro (defun open-postgresql-socket-stream (host port) (etypecase host (pathname (let ((path (namestring (make-pathname :name ".s.PGSQL" :type (princ-to-string port) :defaults host)))) (socket:make-socket :type :stream :address-family :file :connect :active :remote-filename path :local-filename path))) (string (socket:with-pending-connect (mp:with-timeout (*postgresql-server-socket-timeout* (error "connect failed")) (socket:make-socket :type :stream :address-family :internet :remote-port port :remote-host host :connect :active :nodelay t)))))) #+openmcl (defun open-postgresql-socket-stream (host port) (etypecase host (pathname (let ((path (namestring (make-pathname :name ".s.PGSQL" :type (princ-to-string port) :defaults host)))) (ccl:make-socket :type :stream :address-family :file :connect :active :remote-filename path :local-filename path))) (string (ccl:make-socket :type :stream :address-family :internet :remote-port port :remote-host host :connect :active :nodelay t)))) #+lispworks (defun open-postgresql-socket-stream (host port) (etypecase host (pathname (error "File sockets not supported on Lispworks.")) (string (comm:open-tcp-stream host port :direction :io :element-type '(unsigned-byte 8) :read-timeout *postgresql-server-socket-timeout*)) )) #+clisp (defun open-postgresql-socket-stream (host port) (etypecase host (pathname (error "Not supported")) (string (socket:socket-connect port host :element-type '(unsigned-byte 8) :timeout *postgresql-server-socket-timeout*)))) ;;; Interface Functions (defun open-postgresql-connection (&key (host (cmucl-compat:required-argument)) (port +postgresql-server-default-port+) (database (cmucl-compat:required-argument)) (user (cmucl-compat:required-argument)) options tty password) "Open a connection to a PostgreSQL server with the given parameters. Note that host, database and user arguments must be supplied. If host is a pathname, it is assumed to name a directory containing the local unix-domain sockets of the server, with port selecting which of those sockets to open. If host is a string, it is assumed to be the name of the host running the PostgreSQL server. In that case a TCP connection to the given port on that host is opened in order to communicate with the server. In either case the port argument defaults to `+postgresql-server-default-port+'. Password is the clear-text password to be passed in the authentication phase to the server. Depending on the server set-up, it is either passed in the clear, or encrypted via crypt and a server-supplied salt. In that case the alien function specified by `*crypt-library*' and `*crypt-function-name*' is used for encryption. Note that all the arguments (including the clear-text password argument) are stored in the `postgresql-connection' structure, in order to facilitate automatic reconnection in case of communication troubles." (reopen-postgresql-connection (make-postgresql-connection :host host :port port :options (or options "") :tty (or tty "") :database database :user user :password (or password "")))) (defun byte-sequence-to-hex-string (sequence) (string-downcase (format nil "~{~2,'0X~}" (coerce sequence 'list)))) (defun encrypt-password-md5 (password user salt) (let ((pass1 (byte-sequence-to-hex-string (md5::md5sum-string (concatenate 'string password user))))) (byte-sequence-to-hex-string (md5:md5sum-sequence (concatenate '(vector (unsigned-byte 8)) (map '(vector (unsigned-byte 8)) #'char-code pass1) salt))))) (defun reopen-postgresql-connection (connection) "Reopen the given PostgreSQL connection. Closes any existing connection, if it is still open." (when (postgresql-connection-open-p connection) (close-postgresql-connection connection)) (let ((socket (open-postgresql-socket-stream (postgresql-connection-host connection) (postgresql-connection-port connection)))) (unwind-protect (progn (setf (postgresql-connection-socket connection) socket) (send-startup-message socket (postgresql-connection-database connection) (postgresql-connection-user connection) (postgresql-connection-options connection) (postgresql-connection-tty connection)) (force-output socket) (loop (case (read-socket-value-int8 socket) (#.+authentication-message+ (case (read-socket-value-int32 socket) (0 (return)) ((1 2) (error 'postgresql-login-error :connection connection :message "Postmaster expects unsupported Kerberos authentication.")) (3 (send-unencrypted-password-message socket (postgresql-connection-password connection)) (force-output socket)) (4 (let ((salt (read-socket-sequence socket 2 nil))) (send-encrypted-password-message socket (crypt-password (postgresql-connection-password connection) salt))) (force-output socket)) (5 (let ((salt (read-bytes socket 4))) (let ((pwd (encrypt-password-md5 (postgresql-connection-password connection) (postgresql-connection-user connection) salt))) (send-encrypted-password-message socket (concatenate 'string "md5" pwd)))) (force-output socket)) (t (error 'postgresql-login-error :connection connection :message "Postmaster expects unknown authentication method.")))) (#.+error-response-message+ (let ((message (read-socket-value-string socket))) (error 'postgresql-login-error :connection connection :message message))) (t (error 'postgresql-login-error :connection connection :message "Received garbled message from Postmaster")))) ;; Start backend communication (force-output socket) (loop (case (read-socket-value-int8 socket) (#.+backend-key-message+ (setf (postgresql-connection-pid connection) (read-socket-value-int32 socket) (postgresql-connection-key connection) (read-socket-value-int32 socket))) (#.+ready-for-query-message+ (setq socket nil) (return connection)) (#.+error-response-message+ (let ((message (read-socket-value-string socket))) (error 'postgresql-login-error :connection connection :message message))) (#.+notice-response-message+ (let ((message (read-socket-value-string socket))) (warn 'postgresql-warning :connection connection :message message))) (t (error 'postgresql-login-error :connection connection :message "Received garbled message from Postmaster"))))) (when socket (close socket))))) (defun close-postgresql-connection (connection &optional abort) (unless abort (ignore-errors (send-terminate-message (postgresql-connection-socket connection)))) (close (postgresql-connection-socket connection))) (defun postgresql-connection-open-p (connection) (let ((socket (postgresql-connection-socket connection))) (and socket (streamp socket) (open-stream-p socket)))) (defun ensure-open-postgresql-connection (connection) (unless (postgresql-connection-open-p connection) (reopen-postgresql-connection connection))) (defun process-async-messages (connection) (assert (postgresql-connection-open-p connection)) ;; Process any asnychronous messages (loop with socket = (postgresql-connection-socket connection) while (listen socket) do (case (read-socket-value-int8 socket) (#.+ready-for-query-message+) (#.+notice-response-message+ (let ((message (read-socket-value-string socket))) (warn 'postgresql-warning :connection connection :message message))) (#.+notification-response-message+ (let ((pid (read-socket-value-int32 socket)) (message (read-socket-value-string socket))) (when (= pid (postgresql-connection-pid connection)) (signal 'postgresql-notification :connection connection :message message)))) (t (close-postgresql-connection connection) (error 'postgresql-fatal-error :connection connection :message "Received garbled message from backend"))))) (defun start-query-execution (connection query) (ensure-open-postgresql-connection connection) (process-async-messages connection) (send-query-message (postgresql-connection-socket connection) query) (force-output (postgresql-connection-socket connection))) (defun wait-for-query-results (connection) (assert (postgresql-connection-open-p connection)) (let ((socket (postgresql-connection-socket connection)) (cursor-name nil) (error nil)) (loop (case (read-socket-value-int8 socket) (#.+completed-response-message+ (return (values :completed (read-socket-value-string socket)))) (#.+cursor-response-message+ (setq cursor-name (read-socket-value-string socket))) (#.+row-description-message+ (let* ((count (read-socket-value-int16 socket)) (fields (loop repeat count collect (list (read-socket-value-string socket) (read-socket-value-int32 socket) (read-socket-value-int16 socket) (read-socket-value-int32 socket))))) (return (values :cursor (make-postgresql-cursor :connection connection :name cursor-name :fields fields))))) (#.+copy-in-response-message+ (return :copy-in)) (#.+copy-out-response-message+ (return :copy-out)) (#.+ready-for-query-message+ (when error (error error)) (return nil)) (#.+error-response-message+ (let ((message (read-socket-value-string socket))) (setq error (make-condition 'postgresql-error :connection connection :message message)))) (#.+notice-response-message+ (let ((message (read-socket-value-string socket))) (unless (eq :ignore clsql-sys:*backend-warning-behavior*) (warn 'postgresql-warning :connection connection :message message)))) (#.+notification-response-message+ (let ((pid (read-socket-value-int32 socket)) (message (read-socket-value-string socket))) (when (= pid (postgresql-connection-pid connection)) (signal 'postgresql-notification :connection connection :message message)))) (t (close-postgresql-connection connection) (error 'postgresql-fatal-error :connection connection :message "Received garbled message from backend")))))) (defun read-null-bit-vector (socket count) (let ((result (make-array count :element-type 'bit))) (dotimes (offset (ceiling count 8)) (loop with byte = (read-byte socket) for index from (* offset 8) below (min count (* (1+ offset) 8)) for weight downfrom 7 do (setf (aref result index) (ldb (byte 1 weight) byte)))) result)) (defun read-field (socket type) (let ((length (- (read-socket-value-int32 socket) 4))) (case type ((:int32 :int64) (read-integer-from-socket socket length)) (:double (read-double-from-socket socket length)) (t (read-socket-sequence socket length))))) (uffi:def-constant +char-code-zero+ (char-code #\0)) (uffi:def-constant +char-code-minus+ (char-code #\-)) (uffi:def-constant +char-code-plus+ (char-code #\+)) (uffi:def-constant +char-code-period+ (char-code #\.)) (uffi:def-constant +char-code-lower-e+ (char-code #\e)) (uffi:def-constant +char-code-upper-e+ (char-code #\E)) (defun read-integer-from-socket (socket length) (declare (fixnum length)) (if (zerop length) nil (let ((val 0) (first-char (read-byte socket)) (minusp nil)) (declare (fixnum first-char)) (decf length) ;; read first char (cond ((= first-char +char-code-minus+) (setq minusp t)) ((= first-char +char-code-plus+) ) ;; nothing to do (t (setq val (- first-char +char-code-zero+)))) (dotimes (i length) (declare (fixnum i)) (setq val (+ (* 10 val) (- (read-byte socket) +char-code-zero+)))) (if minusp (- val) val)))) (defmacro ascii-digit (int) (let ((offset (gensym))) `(let ((,offset (- ,int +char-code-zero+))) (declare (fixnum ,int ,offset)) (if (and (>= ,offset 0) (< ,offset 10)) ,offset nil)))) (defun read-double-from-socket (socket length) (declare (fixnum length)) (let ((before-decimal 0) (after-decimal 0) (decimal-count 0) (exponent 0) (decimalp nil) (minusp nil) (result nil) (char (read-byte socket))) (declare (fixnum char exponent decimal-count)) (decf length) ;; already read first character (cond ((= char +char-code-minus+) (setq minusp t)) ((= char +char-code-plus+) ) ((= char +char-code-period+) (setq decimalp t)) (t (setq before-decimal (ascii-digit char)) (unless before-decimal (error "Unexpected value")))) (block loop (dotimes (i length) (setq char (read-byte socket)) ;; (format t "~&len:~D, i:~D, char:~D, minusp:~A, decimalp:~A" length i char minusp decimalp) (let ((weight (ascii-digit char))) (cond ((and weight (not decimalp)) ;; before decimal point (setq before-decimal (+ weight (* 10 before-decimal)))) ((and weight decimalp) ;; after decimal point (setq after-decimal (+ weight (* 10 after-decimal))) (incf decimal-count)) ((and (= char +char-code-period+)) (setq decimalp t)) ((or (= char +char-code-lower-e+) ;; E is for exponent (= char +char-code-upper-e+)) (setq exponent (read-integer-from-socket socket (- length i 1))) (setq exponent (or exponent 0)) (return-from loop)) (t (break "Unexpected value")) ) ))) (setq result (* (+ (coerce before-decimal 'double-float) (* after-decimal (expt 10 (- decimal-count)))) (expt 10 exponent))) (if minusp (- result) result))) #+ignore (defun read-double-from-socket (socket length) (let ((result (make-string length))) (read-socket-sequence result socket) (let ((*read-default-float-format* 'double-float)) (read-from-string result)))) (defun read-cursor-row (cursor types) (let* ((connection (postgresql-cursor-connection cursor)) (socket (postgresql-connection-socket connection)) (fields (postgresql-cursor-fields cursor))) (assert (postgresql-connection-open-p connection)) (loop (let ((code (read-socket-value-int8 socket))) (case code (#.+ascii-row-message+ (return (loop with count = (length fields) with null-vector = (read-null-bit-vector socket count) repeat count for null-bit across null-vector for i from 0 for null-p = (zerop null-bit) if null-p collect nil else collect (read-field socket (nth i types))))) (#.+binary-row-message+ (error "NYI")) (#.+completed-response-message+ (return (values nil (read-socket-value-string socket)))) (#.+error-response-message+ (let ((message (read-socket-value-string socket))) (error 'postgresql-error :connection connection :message message))) (#.+notice-response-message+ (let ((message (read-socket-value-string socket))) (warn 'postgresql-warning :connection connection :message message))) (#.+notification-response-message+ (let ((pid (read-socket-value-int32 socket)) (message (read-socket-value-string socket))) (when (= pid (postgresql-connection-pid connection)) (signal 'postgresql-notification :connection connection :message message)))) (t (close-postgresql-connection connection) (error 'postgresql-fatal-error :connection connection :message "Received garbled message from backend"))))))) (defun map-into-indexed (result-seq func seq) (dotimes (i (length seq)) (declare (fixnum i)) (setf (elt result-seq i) (funcall func (elt seq i) i))) result-seq) (defun copy-cursor-row (cursor sequence types) (let* ((connection (postgresql-cursor-connection cursor)) (socket (postgresql-connection-socket connection)) (fields (postgresql-cursor-fields cursor))) (assert (= (length fields) (length sequence))) (loop (let ((code (read-socket-value-int8 socket))) (case code (#.+ascii-row-message+ (return #+ignore (let* ((count (length sequence)) (null-vector (read-null-bit-vector socket count))) (dotimes (i count) (declare (fixnum i)) (if (zerop (elt null-vector i)) (setf (elt sequence i) nil) (let ((value (read-field socket (nth i types)))) (setf (elt sequence i) value))))) (map-into-indexed sequence #'(lambda (null-bit i) (if (zerop null-bit) nil (read-field socket (nth i types)))) (read-null-bit-vector socket (length sequence))))) (#.+binary-row-message+ (error "NYI")) (#.+completed-response-message+ (return (values nil (read-socket-value-string socket)))) (#.+error-response-message+ (let ((message (read-socket-value-string socket))) (error 'postgresql-error :connection connection :message message))) (#.+notice-response-message+ (let ((message (read-socket-value-string socket))) (warn 'postgresql-warning :connection connection :message message))) (#.+notification-response-message+ (let ((pid (read-socket-value-int32 socket)) (message (read-socket-value-string socket))) (when (= pid (postgresql-connection-pid connection)) (signal 'postgresql-notification :connection connection :message message)))) (t (close-postgresql-connection connection) (error 'postgresql-fatal-error :connection connection :message "Received garbled message from backend"))))))) (defun skip-cursor-row (cursor) (let* ((connection (postgresql-cursor-connection cursor)) (socket (postgresql-connection-socket connection)) (fields (postgresql-cursor-fields cursor))) (loop (let ((code (read-socket-value-int8 socket))) (case code (#.+ascii-row-message+ (loop for null-bit across (read-null-bit-vector socket (length fields)) do (unless (zerop null-bit) (let* ((length (read-socket-value-int32 socket))) (loop repeat (- length 4) do (read-byte socket))))) (return t)) (#.+binary-row-message+ (error "NYI")) (#.+completed-response-message+ (return (values nil (read-socket-value-string socket)))) (#.+error-response-message+ (let ((message (read-socket-value-string socket))) (error 'postgresql-error :connection connection :message message))) (#.+notice-response-message+ (let ((message (read-socket-value-string socket))) (warn 'postgresql-warning :connection connection :message message))) (#.+notification-response-message+ (let ((pid (read-socket-value-int32 socket)) (message (read-socket-value-string socket))) (when (= pid (postgresql-connection-pid connection)) (signal 'postgresql-notification :connection connection :message message)))) (t (close-postgresql-connection connection) (error 'postgresql-fatal-error :connection connection :message "Received garbled message from backend"))))))) (defun run-query (connection query &optional (result-types nil)) (start-query-execution connection query) (multiple-value-bind (status cursor) (wait-for-query-results connection) (assert (eq status :cursor)) (loop for row = (read-cursor-row cursor result-types) while row collect row finally (wait-for-query-results connection)))) #+scl (declaim (ext:maybe-inline read-byte write-byte)) cl-sql-6.7.2/db-postgresql-socket/postgresql-socket-package.lisp0000644000175000017500000000402612562771567024006 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-package.lisp ;;;; Purpose: Package definition for PostgreSQL interface using sockets ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) #+lispworks (require "comm") (defpackage #:postgresql-socket (:use #:cl #:md5) (:export #:pgsql-ftype #:pgsql-ftype#bytea #:pgsql-ftype#int2 #:pgsql-ftype#int4 #:pgsql-ftype#int8 #:pgsql-ftype#float4 #:pgsql-ftype#float8 #:+crypt-library+ #:postgresql-condition #:postgresql-condition-connection #:postgresql-condition-message #:postgresql-error #:postgresql-fatal-error #:postgresql-login-error #:postgresql-warning #:postgresql-notification #:postgresql-connection #:postgresql-connection-p #:postgresql-cursor #:postgresql-cursor-p #:postgresql-cursor-connection #:postgresql-cursor-name #:postgresql-cursor-fields #:+postgresql-server-default-port+ #:open-postgresql-connection #:reopen-postgresql-connection #:close-postgresql-connection #:postgresql-connection-open-p #:ensure-open-postgresql-connection #:start-query-execution #:wait-for-query-results #:read-cursor-row #:copy-cursor-row #:skip-cursor-row )) cl-sql-6.7.2/db-postgresql-socket/postgresql-socket-sql.lisp0000644000175000017500000003256111577737507023220 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-sql.sql ;;;; Purpose: High-level PostgreSQL interface using socket ;;;; Authors: Kevin M. Rosenberg based on original code by Pierre R. Mai ;;;; Created: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage :clsql-postgresql-socket (:use #:common-lisp #:clsql-sys #:postgresql-socket) (:export #:postgresql-socket-database) (:documentation "This is the CLSQL socket interface to PostgreSQL.")) (in-package #:clsql-postgresql-socket) ;; interface foreign library loading routines (clsql-sys:database-type-load-foreign :postgresql-socket) ;; Field type conversion (defun make-type-list-for-auto (cursor) (let* ((fields (postgresql-cursor-fields cursor)) (num-fields (length fields)) (new-types '())) (dotimes (i num-fields) (declare (fixnum i)) (push (canonical-field-type fields i) new-types)) (nreverse new-types))) (defun canonical-field-type (fields index) "Extracts canonical field type from fields list" (let ((oid (cadr (nth index fields)))) (case oid ((#.pgsql-ftype#bytea #.pgsql-ftype#int2 #.pgsql-ftype#int4) :int32) (#.pgsql-ftype#int8 :int64) ((#.pgsql-ftype#float4 #.pgsql-ftype#float8) :double) (otherwise t)))) (defun canonicalize-types (types cursor) (if (null types) nil (let ((auto-list (make-type-list-for-auto cursor))) (cond ((listp types) (canonicalize-type-list types auto-list)) ((eq types :auto) auto-list) (t nil))))) (defun canonicalize-type-list (types auto-list) "Ensure a field type list meets expectations. Essentially if we get a generic term for a type that our auto typer pulls a better type for, use it instead" (let ((length-types (length types))) (loop for i from 0 below (length auto-list) for auto = (nth i auto-list) collect (if (or (>= i length-types) (member (nth i types) (list T :int :double))) auto (nth i types))))) (defun convert-to-clsql-warning (database condition) (ecase *backend-warning-behavior* (:warn (warn 'sql-database-warning :database database :message (postgresql-condition-message condition))) (:error (error 'sql-database-error :database database :message (format nil "Warning upgraded to error: ~A" (postgresql-condition-message condition)))) ((:ignore nil) ;; do nothing ))) (defun convert-to-clsql-error (database expression condition) (error 'sql-database-data-error :database database :expression expression :error-id (type-of condition) :message (postgresql-condition-message condition))) (defmacro with-postgresql-handlers ((database &optional expression) &body body) (let ((database-var (gensym)) (expression-var (gensym))) `(let ((,database-var ,database) (,expression-var ,expression)) (handler-bind ((postgresql-warning (lambda (c) (convert-to-clsql-warning ,database-var c))) (postgresql-error (lambda (c) (convert-to-clsql-error ,database-var ,expression-var c)))) ,@body)))) (defmethod database-initialize-database-type ((database-type (eql :postgresql-socket))) t) (defclass postgresql-socket-database (generic-postgresql-database) ((connection :accessor database-connection :initarg :connection :type postgresql-connection))) (defmethod database-type ((database postgresql-socket-database)) :postgresql-socket) (defmethod database-name-from-spec (connection-spec (database-type (eql :postgresql-socket))) (check-connection-spec connection-spec database-type (host db user password &optional port options tty)) (destructuring-bind (host db user password &optional port options tty) connection-spec (declare (ignore password options tty)) (concatenate 'string (etypecase host (null "localhost") (pathname (namestring host)) (string host)) (when port (concatenate 'string ":" (etypecase port (integer (write-to-string port)) (string port)))) "/" db "/" user))) (defmethod database-connect (connection-spec (database-type (eql :postgresql-socket))) (check-connection-spec connection-spec database-type (host db user password &optional port options tty)) (destructuring-bind (host db user password &optional (port +postgresql-server-default-port+) (options "") (tty "")) connection-spec (handler-case (handler-bind ((postgresql-warning (lambda (c) (warn 'sql-warning :format-control "~A" :format-arguments (list (princ-to-string c)))))) (open-postgresql-connection :host host :port port :options options :tty tty :database db :user user :password password)) (postgresql-error (c) ;; Connect failed (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id (type-of c) :message (postgresql-condition-message c))) (:no-error (connection) ;; Success, make instance (make-instance 'postgresql-socket-database :name (database-name-from-spec connection-spec database-type) :database-type :postgresql-socket :connection-spec connection-spec :connection connection))))) (defmethod database-disconnect ((database postgresql-socket-database)) (close-postgresql-connection (database-connection database)) t) (defmethod database-query (expression (database postgresql-socket-database) result-types field-names) (let ((connection (database-connection database))) (with-postgresql-handlers (database expression) (start-query-execution connection expression) (multiple-value-bind (status cursor) (wait-for-query-results connection) (unless (eq status :cursor) (close-postgresql-connection connection) (error 'sql-database-data-error :database database :expression expression :error-id "missing-result" :message "Didn't receive result cursor for query.")) (setq result-types (canonicalize-types result-types cursor)) (values (loop for row = (read-cursor-row cursor result-types) while row collect row finally (unless (null (wait-for-query-results connection)) (close-postgresql-connection connection) (error 'sql-database-data-error :database database :expression expression :error-id "multiple-results" :message "Received multiple results for query."))) (when field-names (mapcar #'car (postgresql-cursor-fields cursor)))))))) (defmethod database-execute-command (expression (database postgresql-socket-database)) (let ((connection (database-connection database))) (with-postgresql-handlers (database expression) (start-query-execution connection expression) (multiple-value-bind (status result) (wait-for-query-results connection) (when (eq status :cursor) (loop (multiple-value-bind (row stuff) (skip-cursor-row result) (unless row (setq status :completed result stuff) (return))))) (cond ((null status) t) ((eq status :completed) (unless (null (wait-for-query-results connection)) (close-postgresql-connection connection) (error 'sql-database-data-error :database database :expression expression :error-id "multiple-results" :message "Received multiple results for command.")) result) (t (close-postgresql-connection connection) (error 'sql-database-data-error :database database :expression expression :errno "missing-result" :message "Didn't receive completion for command."))))))) (defstruct postgresql-socket-result-set (done nil) (cursor nil) (types nil)) (defmethod database-query-result-set ((expression string) (database postgresql-socket-database) &key full-set result-types) (declare (ignore full-set)) (let ((connection (database-connection database))) (with-postgresql-handlers (database expression) (start-query-execution connection expression) (multiple-value-bind (status cursor) (wait-for-query-results connection) (unless (eq status :cursor) (close-postgresql-connection connection) (error 'sql-database-data-error :database database :expression expression :error-id "missing-result" :message "Didn't receive result cursor for query.")) (values (make-postgresql-socket-result-set :done nil :cursor cursor :types (canonicalize-types result-types cursor)) (length (postgresql-cursor-fields cursor))))))) (defmethod database-dump-result-set (result-set (database postgresql-socket-database)) (if (postgresql-socket-result-set-done result-set) t (with-postgresql-handlers (database) (loop while (skip-cursor-row (postgresql-socket-result-set-cursor result-set)) finally (setf (postgresql-socket-result-set-done result-set) t))))) (defmethod database-store-next-row (result-set (database postgresql-socket-database) list) (let ((cursor (postgresql-socket-result-set-cursor result-set))) (with-postgresql-handlers (database) (if (copy-cursor-row cursor list (postgresql-socket-result-set-types result-set)) t (prog1 nil (setf (postgresql-socket-result-set-done result-set) t) (wait-for-query-results (database-connection database))))))) (defmethod database-create (connection-spec (type (eql :postgresql-socket))) (destructuring-bind (host name user password &optional port options tty) connection-spec (let ((database (database-connect (list host "postgres" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "create database ~A" name) database) (database-disconnect database))))) (defmethod database-destroy (connection-spec (type (eql :postgresql-socket))) (destructuring-bind (host name user password &optional port optional tty) connection-spec (let ((database (database-connect (list host "postgres" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "drop database ~A" name) database) (database-disconnect database))))) (defmethod database-probe (connection-spec (type (eql :postgresql-socket))) (when (find (second connection-spec) (database-list connection-spec type) :test #'string-equal) t)) ;; Database capabilities (defmethod db-backend-has-create/destroy-db? ((db-type (eql :postgresql-socket))) nil) (defmethod db-type-has-fancy-math? ((db-type (eql :postgresql-socket))) t) (defmethod db-type-default-case ((db-type (eql :postgresql-socket))) :lower) (defmethod database-underlying-type ((database postgresql-socket-database)) :postgresql) (when (clsql-sys:database-type-library-loaded :postgresql-socket) (clsql-sys:initialize-database-type :database-type :postgresql-socket)) cl-sql-6.7.2/db-postgresql-socket/Makefile0000644000175000017500000000011510667176647017470 0ustar kevinkevinSUBDIRS := include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/tests/0000755000175000017500000000000014327126007013077 5ustar kevinkevincl-sql-6.7.2/tests/test-basic.lisp0000644000175000017500000002444612303270414016032 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-basic.lisp ;;;; Purpose: Tests for clsql string-based queries and result types ;;;; Author: Kevin M. Rosenberg ;;;; Created: Mar 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (setq *rt-basic* '( (deftest :basic/type/1 (with-dataset *ds-basic* (let ((results '())) (dolist (row (query "select * from TYPE_TABLE" :result-types :auto) results) (destructuring-bind (int float str) row (push (list (integerp int) (typep float 'double-float) (stringp str)) results))))) ((t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t))) (deftest :basic/type/2 (with-dataset *ds-basic* (let ((results '())) (dolist (row (query "select * from TYPE_TABLE" :result-types :auto) results) (destructuring-bind (int float str) row (setq results (cons (list (double-float-equal (transform-float-1 int) float) (double-float-equal (parse-double str) float)) results)))) results)) ((t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t))) (deftest :basic/select/1 (with-dataset *ds-basic* (let ((rows (query "select * from TYPE_TABLE" :result-types :auto))) (values (length rows) (length (car rows))))) 11 3) (deftest :BASIC/SELECT/2 (with-dataset *ds-basic* (let ((results '())) (dolist (row (query "select * from TYPE_TABLE" :result-types nil) results) (destructuring-bind (int float str) row (push (list (stringp int) (stringp float) (stringp str)) results))))) ((t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t) (t t t))) (deftest :basic/select/3 (with-dataset *ds-basic* (let ((results '())) (dolist (row (query "select * from TYPE_TABLE" :result-types nil) results) (destructuring-bind (int float str) row (push (list (double-float-equal (transform-float-1 (parse-integer int)) (parse-double float)) (double-float-equal (parse-double str) (parse-double float))) results))))) ((t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t))) (deftest :basic/map/1 (with-dataset *ds-basic* (let ((results '()) (rows (map-query 'vector #'identity "select * from TYPE_TABLE" :result-types nil))) (declare (type (simple-array list (*)) rows)) (dotimes (i (length rows) results) (push (list (listp (aref rows i)) (length (aref rows i)) (eql (- i 5) (parse-integer (first (aref rows i)) :junk-allowed nil)) (double-float-equal (transform-float-1 (parse-integer (first (aref rows i)))) (parse-double (second (aref rows i))))) results)))) ((t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t))) (deftest :basic/map/2 (with-dataset *ds-basic* (let ((results '()) (rows (map-query 'list #'identity "select * from TYPE_TABLE" :result-types nil))) (dotimes (i (length rows) results) (push (list (listp (nth i rows)) (length (nth i rows)) (eql (- i 5) (parse-integer (first (nth i rows)) :junk-allowed nil)) (double-float-equal (transform-float-1 (parse-integer (first (nth i rows)))) (parse-double (second (nth i rows))))) results)))) ((t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t))) (deftest :basic/map/3 (with-dataset *ds-basic* (let ((results '()) (rows (map-query 'list #'identity "select * from TYPE_TABLE" :result-types :auto))) (dotimes (i (length rows) results) (push (list (listp (nth i rows)) (length (nth i rows)) (eql (- i 5) (first (nth i rows))) (double-float-equal (transform-float-1 (first (nth i rows))) (second (nth i rows)))) results)))) ((t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t) (t 3 t t))) ;; confirm that a query on a single element returns a list of one element (deftest :basic/map/4 (with-dataset *ds-basic* (let ((rows (map-query 'list #'identity "select t_int from TYPE_TABLE" :result-types nil))) (values (consp (first rows)) (length (first rows))))) t 1) (deftest :basic/do/1 (with-dataset *ds-basic* (let ((results '())) (do-query ((int float str) "select * from TYPE_TABLE" :result-types nil) (let ((int-number (parse-integer int))) (setq results (cons (list (double-float-equal (transform-float-1 int-number) (parse-double float)) (double-float-equal (parse-double str) (parse-double float))) results)))) results)) ((t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t))) (deftest :basic/do/2 (with-dataset *ds-basic* (let ((results '())) (do-query ((int float str) "select * from TYPE_TABLE" :result-types :auto) (setq results (cons (list (double-float-equal (transform-float-1 int) float) (double-float-equal (parse-double str) float)) results))) results)) ((t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t))) (deftest :basic/bigint/1 (with-dataset *ds-bigint* (let ((results '())) (dolist (row (query "select * from TYPE_BIGINT" :result-types :auto) results) (destructuring-bind (int bigint) row (push (list (integerp int) (integerp bigint)) results))))) ((t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t) (t t))) (deftest :basic/bigtext/1 (with-dataset *ds-bigtext* (let* ((len 7499) (str (make-string len :initial-element #\a)) (cmd (format nil "INSERT INTO testbigtext (a) VALUES ('~a')" str))) (execute-command cmd) (let ((a (first (query "SELECT a from testbigtext" :flatp t :field-names nil)))) (assert (string= str a) (str a) "mismatch on a. inserted: ~a returned: ~a" len (length a))) )) nil) (deftest :basic/bigtext/2 (flet ((random-char () (let ((alphabet "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") (idx (random 52))) (elt alphabet idx)))) (dotimes (n 10) (with-dataset *ds-bigtext* (let* ((len (random 7500)) (str (coerce (make-array len :initial-contents (loop repeat len collect (random-char))) 'string)) (cmd (format nil "INSERT INTO testbigtext (a) VALUES ('~a')" str))) (execute-command cmd) (let ((a (first (query "SELECT a from testbigtext" :flatp t :field-names nil)))) (assert (string= str a) (str a) "mismatch on randomized bigtext(~a) inserted: ~s returned: ~s" len str a)) )))) nil) (deftest :basic/reallybigintegers/1 (with-dataset *ds-reallybigintegers* (let* ((a (1- (expt 2 64))) (b (- (expt 2 64) 2)) (c (expt 2 63)) (d (expt 2 62)) (sql (format nil "INSERT INTO testreallybigintegers VALUES (~A, ~A, ~A, ~A)" a b c d))) (query sql) (let ((results (query (format nil "SELECT * FROM testreallybigintegers")))) (equal `(,a ,b ,c ,d) (car results))))) t) )) (def-dataset *ds-basic* (:setup (lambda () (ignore-errors (clsql:execute-command "DROP TABLE TYPE_TABLE") (clsql:execute-command "DROP TABLE TYPE_BIGINT")) (clsql:execute-command "CREATE TABLE TYPE_TABLE (t_int integer, t_float double precision, t_str VARCHAR(30))") (dotimes (i 11) (let* ((test-int (- i 5)) (test-flt (transform-float-1 test-int))) (clsql:execute-command (format nil "INSERT INTO TYPE_TABLE VALUES (~a,~a,'~a')" test-int (clsql-sys:number-to-sql-string test-flt) (clsql-sys:number-to-sql-string test-flt) )))))) (:cleanup "DROP TABLE TYPE_TABLE")) (def-dataset *ds-bigint* (:setup (lambda () (ignore-errors (clsql:execute-command "DROP TABLE TYPE_BIGINT")) (clsql:execute-command "CREATE TABLE TYPE_BIGINT (T_INT integer, T_BIGINT BIGINT)") (dotimes (i 11) (clsql:execute-command (format nil "INSERT INTO TYPE_BIGINT VALUES (~a,~a)" (- i 5) (transform-bigint-1 (- i 5))))))) (:cleanup "DROP TABLE TYPE_BIGINT")) ;;;; Testing functions (defun transform-float-1 (i) (coerce (* i (abs (/ i 2)) (expt 10 (* 2 i))) 'double-float)) (defun transform-bigint-1 (i) (* i (expt 10 (* 3 (abs i))))) (defun parse-double (num-str) (let ((*read-default-float-format* 'double-float)) (coerce (read-from-string num-str) 'double-float))) (defun double-float-equal (a b) (if (zerop a) (if (zerop b) t nil) (let ((diff (abs (/ (- a b) a)))) (if (> diff (* 10 double-float-epsilon)) nil t)))) (def-dataset *ds-bigtext* (:setup "CREATE TABLE testbigtext(a varchar(7500))") (:cleanup "DROP TABLE testbigtext")) (def-dataset *ds-reallybigintegers* (:setup (lambda () (ignore-errors (clsql:execute-command "DROP TABLE testreallybigintegers")) (clsql:execute-command "CREATE TABLE testreallybigintegers( a BIGINT UNSIGNED, b BIGINT UNSIGNED, c BIGINT UNSIGNED, d BIGINT UNSIGNED )"))) (:cleanup "DROP TABLE testreallybigintegers")) cl-sql-6.7.2/tests/package.lisp0000644000175000017500000000204212473715066015372 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: package.lisp ;;;; Purpose: Package definition for CLSQL test suite ;;;; Authors: Marcus Pearce and Kevin M. Rosenberg ;;;; Created: March 2004 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-tests (:use #:clsql #:common-lisp #:rtest) (:shadowing-import-from #:clsql-sys #:%get-int ) (:export #:run-tests #:run-tests-append-report-file #:run-benchmarks #:run-benchmarks-append-report-file #:summarize-test-report #:test-connect #:test-setup-database ) (:documentation "Regression tests for CLSQL.")) cl-sql-6.7.2/tests/test-oodml.lisp0000644000175000017500000012171712651763351016077 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ====================================================================== ;;;; File: test-oodml.lisp ;;;; Created: 01/04/2004 ;;;; ;;;; Tests for the CLSQL Object Oriented Data Definition Language ;;;; (OODML). ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ====================================================================== (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (defmacro has-sql-value-conversion-error (() &body body) `(let (*debugger-hook*) (handler-case (progn ,@body nil) (clsql-sys::sql-value-conversion-error (c) (declare (ignore c)) t)))) (setq *rt-oodml* '( (deftest :oodml/read-symbol-value/1-into-this-package (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'symbol 'clsql-tests::foo nil nil) 'symbol nil nil) clsql-tests::foo) (deftest :oodml/read-symbol-value/2-into-another-pacakge (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'symbol 'clsql-sys::foo nil nil) 'symbol nil nil) clsql-sys::foo) (deftest :oodml/read-symbol-value/3-keyword (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'keyword ':foo nil nil) 'keyword nil nil) :foo) (deftest :oodml/read-symbol-value/4-keyword-error (has-sql-value-conversion-error () (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'keyword 'foo nil nil) 'keyword nil nil)) T) (deftest :oodml/read-symbol-value/5-unknown-type-error-1 (has-sql-value-conversion-error () (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'bloop 'foo nil nil) 'bloop nil nil)) t) (deftest :oodml/read-symbol-value/6-unknown-type-error-2 (has-sql-value-conversion-error () (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'bloop 'foo nil nil) '(or integer float) nil nil)) t) (deftest :oodml/read-symbol-value/read-list (clsql-sys::read-sql-value (clsql-sys::database-output-sql-as-type 'list '(("status" "new" "open")) nil nil) 'list nil nil) (("status" "new" "open"))) (deftest :oodml/select/1 (with-dataset *ds-employees* (mapcar #'(lambda (e) (slot-value e 'last-name)) (clsql:select 'employee :order-by [last-name] :flatp t :caching nil))) ("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Lenin" "Putin" "Stalin" "Trotsky" "Yeltsin")) (deftest :oodml/select/2 (with-dataset *ds-employees* (mapcar #'(lambda (e) (slot-value e 'name)) (clsql:select 'company :flatp t :caching nil))) ("Widgets Inc.")) (deftest :oodml/select/3 (with-dataset *ds-employees* (mapcar #'(lambda (e) (slot-value e 'ecompanyid)) (clsql:select 'employee :where [and [= [slot-value 'employee 'ecompanyid] [slot-value 'company 'companyid]] [= [slot-value 'company 'name] "Widgets Inc."]] :flatp t :caching nil))) (1 1 1 1 1 1 1 1 1 1)) (deftest :oodml/select/4 (with-dataset *ds-employees* (mapcar #'(lambda (e) (concatenate 'string (slot-value e 'first-name) " " (slot-value e 'last-name))) (clsql:select 'employee :where [= [slot-value 'employee 'first-name] "Vladimir"] :flatp t :order-by [last-name] :caching nil))) ("Vladimir Lenin" "Vladimir Putin")) (deftest :oodml/select/5 (with-dataset *ds-employees* (length (clsql:select 'employee :where [married] :flatp t :caching nil))) 3) (deftest :oodml/select/6 (with-dataset *ds-employees* (let ((a (caar (clsql:select 'address :where [= 1 [addressid]] :caching nil)))) (values (slot-value a 'street-number) (slot-value a 'street-name) (slot-value a 'city) (slot-value a 'postal-code)))) 10 "Park Place" "Leningrad" 123) (deftest :oodml/select/7 (with-dataset *ds-employees* (let ((a (caar (clsql:select 'address :where [= 2 [addressid]] :caching nil)))) (values (slot-value a 'street-number) (slot-value a 'street-name) (slot-value a 'city) (slot-value a 'postal-code)))) nil "" "no city" 0) (deftest :oodml/select/8 (with-dataset *ds-employees* (mapcar #'(lambda (e) (slot-value e 'married)) (clsql:select 'employee :flatp t :order-by [emplid] :caching nil))) (t t t nil nil nil nil nil nil nil)) (deftest :oodml/select/9 (with-dataset *ds-employees* (mapcar #'(lambda (pair) (list (typep (car pair) 'address) (typep (second pair) 'employee-address) (slot-value (car pair) 'addressid) (slot-value (second pair) 'aaddressid) (slot-value (second pair) 'aemplid))) (employee-addresses employee1))) ((t t 1 1 1) (t t 2 2 1))) (deftest :oodml/select/10 (with-dataset *ds-employees* (mapcar #'(lambda (pair) (list (typep (car pair) 'address) (typep (second pair) 'employee-address) (slot-value (car pair) 'addressid) (slot-value (second pair) 'aaddressid) (slot-value (second pair) 'aemplid))) (employee-addresses employee2))) ((t t 2 2 2))) (deftest :oodml/select/11 (with-dataset *ds-employees* (values (mapcar #'(lambda (x) (slot-value x 'emplid)) (clsql:select 'employee :order-by '(([emplid] :asc)) :flatp t)) (mapcar #'(lambda (x) (slot-value x 'emplid)) (clsql:select 'employee :order-by '(([emplid] :desc)) :flatp t)))) (1 2 3 4 5 6 7 8 9 10) (10 9 8 7 6 5 4 3 2 1)) ;; test retrieval of node, derived nodes etc (deftest :oodml/select/12 (with-dataset *ds-nodes* (length (clsql:select 'node :where [not [null [node-id]]] :flatp t :caching nil))) 11) (deftest :oodml/select/13 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'node :where [= 1 [node-id]] :flatp t :caching nil)))) (values (slot-value a 'node-id) (slot-value a 'title)))) 1 "Bare node") (deftest :oodml/select/14 (with-dataset *ds-nodes* (length (clsql:select 'setting :where [not [null [setting-id]]] :flatp t :caching nil))) 4) (deftest :oodml/select/15 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'setting :where [= 3 [setting-id]] :flatp t :caching nil)))) (values (slot-value a 'node-id) (slot-value a 'setting-id) (slot-value a 'title) (slot-value a 'vars)))) 3 3 "Setting2" "var 2") (deftest :oodml/select/16 (with-dataset *ds-nodes* (length (clsql:select 'user :where [not [null [user-id]]] :flatp t :caching nil))) 2) (deftest :oodml/select/17 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'user :where [= 4 [user-id]] :flatp t :caching nil)))) (values (slot-value a 'node-id) (slot-value a 'user-id) (slot-value a 'title) (slot-value a 'nick)))) 4 4 "user-1" "first user") (deftest :oodml/select/18 (with-dataset *ds-nodes* (length (clsql:select 'theme :where [not [null [theme-id]]] :flatp t :caching nil))) 2) (deftest :oodml/select/19 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'theme :where [= 6 [theme-id]] :flatp t :caching nil)))) (slot-value a 'theme-id))) 6) (deftest :oodml/select/20 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'theme :where [= 7 [theme-id]] :flatp t :caching nil)))) (values (slot-value a 'node-id) (slot-value a 'theme-id) (slot-value a 'title) (slot-value a 'vars) (slot-value a 'doc) ))) 7 7 "theme-2" nil "second theme") ;; Some tests to check weird subclassed nodes (node without own table, or subclassed of same) (deftest :oodml/select/21 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'location :where [= [title] "location-1"] :flatp t :caching nil)))) (values (slot-value a 'node-id) (slot-value a 'title)))) 8 "location-1") (deftest :oodml/select/22 (with-dataset *ds-nodes* (let ((a (car (clsql:select 'subloc :where [not [null [subloc-id]]] :flatp t :caching nil)))) (values (slot-value a 'node-id) (slot-value a 'subloc-id) (slot-value a 'title) (slot-value a 'loc)))) 10 10 "subloc-1" "a subloc") (deftest :oodml/select/23 (with-dataset *ds-artists* (length (clsql:select 'artist :flatp t :caching nil))) 0) ;; test retrieval is deferred (deftest :oodm/retrieval/1 (with-dataset *ds-employees* (every #'(lambda (e) (not (slot-boundp e 'company))) (select 'employee :flatp t :caching nil))) t) (deftest :oodm/retrieval/2 (with-dataset *ds-employees* (every #'(lambda (e) (not (slot-boundp e 'address))) (select 'deferred-employee-address :flatp t :caching nil))) t) ;; :retrieval :immediate should be boundp before accessed (deftest :oodm/retrieval/3 (with-dataset *ds-employees* (every #'(lambda (ea) (slot-boundp ea 'address)) (select 'employee-address :flatp t :caching nil))) t) (deftest :oodm/retrieval/4 (with-dataset *ds-employees* (every #'(lambda (ea) (typep (slot-value ea 'address) 'address)) (select 'employee-address :flatp t :caching nil))) t) (deftest :oodm/retrieval/5 (with-dataset *ds-employees* (every #'(lambda (ea) (typep (slot-value ea 'address) 'address)) (select 'deferred-employee-address :flatp t :caching nil))) t) (deftest :oodm/retrieval/6 (with-dataset *ds-employees* (every #'(lambda (ea) (slot-boundp (slot-value ea 'address) 'addressid)) (select 'employee-address :flatp t :caching nil))) t) (deftest :oodm/retrieval/7 (with-dataset *ds-employees* (every #'(lambda (ea) (slot-boundp (slot-value ea 'address) 'addressid)) (select 'deferred-employee-address :flatp t :caching nil))) t) (deftest :oodm/retrieval/8 (with-dataset *ds-employees* (mapcar #'(lambda (ea) (slot-value (slot-value ea 'address) 'street-number)) (select 'employee-address :flatp t :order-by [aaddressid] :caching nil))) (10 10 nil nil nil nil)) (deftest :oodm/retrieval/9 (with-dataset *ds-employees* (mapcar #'(lambda (ea) (slot-value (slot-value ea 'address) 'street-number)) (select 'deferred-employee-address :flatp t :order-by [aaddressid] :caching nil))) (10 10 nil nil nil nil)) (deftest :oodm/retrieval/10-slot-columns (with-dataset *ds-employees* (mapcar #'title (select 'employee :flatp t :caching nil :where [<= [emplid] 3] :order-by `((,[emplid] :asc))))) (supplicant :adherent cl-user::novice)) ;; tests update-records-from-instance (deftest :oodml/update-records/1 (with-dataset *ds-employees* (values (progn (let ((lenin (car (clsql:select 'employee :where [= 1 [slot-value 'employee 'emplid]] :flatp t :caching nil)))) (format nil "~a ~a: ~a" (first-name lenin) (last-name lenin) (employee-email lenin)))) (progn (setf (slot-value employee1 'first-name) "Dimitriy" (slot-value employee1 'last-name) "Ivanovich" (slot-value employee1 'email) "ivanovich@soviet.org") (clsql:update-records-from-instance employee1) (let ((lenin (car (clsql:select 'employee :where [= 1 [slot-value 'employee 'emplid]] :flatp t :caching nil)))) (format nil "~a ~a: ~a" (first-name lenin) (last-name lenin) (employee-email lenin)))))) "Vladimir Lenin: lenin@soviet.org" "Dimitriy Ivanovich: ivanovich@soviet.org") ;; tests update-record-from-slot (deftest :oodml/update-records/2 (with-dataset *ds-employees* ;(start-sql-recording :type :both) (values (employee-email (car (clsql:select 'employee :where [= 1 [slot-value 'employee 'emplid]] :flatp t :caching nil))) (progn (setf (slot-value employee1 'email) "lenin-nospam@soviet.org") (clsql:update-record-from-slot employee1 'email) (employee-email (car (clsql:select 'employee :where [= 1 [slot-value 'employee 'emplid]] :flatp t :caching nil)))))) "lenin@soviet.org" "lenin-nospam@soviet.org") ;; tests update-record-from-slots (deftest :oodml/update-records/3 (with-dataset *ds-employees* (values (let ((lenin (car (clsql:select 'employee :where [= 1 [slot-value 'employee 'emplid]] :flatp t :caching nil)))) (format nil "~a ~a: ~a" (first-name lenin) (last-name lenin) (employee-email lenin))) (progn (setf (slot-value employee1 'first-name) "Dimitriy" (slot-value employee1 'last-name) "Ivanovich" (slot-value employee1 'email) "ivanovich@soviet.org") (clsql:update-record-from-slots employee1 '(first-name last-name email)) (let ((lenin (car (clsql:select 'employee :where [= 1 [slot-value 'employee 'emplid]] :flatp t :caching nil)))) (format nil "~a ~a: ~a" (first-name lenin) (last-name lenin) (employee-email lenin)))))) "Vladimir Lenin: lenin@soviet.org" "Dimitriy Ivanovich: ivanovich@soviet.org") (deftest :oodml/update-records/4 (with-dataset *ds-nodes* (flet ((print-fresh-node () (let ((base (car (clsql:select 'node :where [= 1 [slot-value 'node 'node-id]] :flatp t :caching nil)))) (format nil "~a ~a" (slot-value base 'node-id) (slot-value base 'title))))) (values (print-fresh-node) (let ((base (car (clsql:select 'node :where [= 1 [slot-value 'node 'node-id]] :flatp t :caching nil)))) (setf (slot-value base 'title) "Altered title") (clsql:update-records-from-instance base) (print-fresh-node))))) "1 Bare node" "1 Altered title") (deftest :oodml/update-records/4-slots ;just like 4, but use slots fns. (with-dataset *ds-nodes* (flet ((print-fresh-setting () (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (format nil "~a ~a ~a" (slot-value node 'setting-id) (slot-value node 'title) (slot-value node 'vars))))) (values (print-fresh-setting) (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title") (setf (slot-value node 'vars) "Altered vars") (clsql-sys:update-record-from-slot node 'title) (clsql-sys:update-record-from-slot node 'vars) (print-fresh-setting)) (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Setting2") (setf (slot-value node 'vars) "var 2") (clsql:update-records-from-instance node) (clsql-sys:update-record-from-slots node '(vars title)) (print-fresh-setting))))) "3 Setting2 var 2" "3 Altered title Altered vars" "3 Setting2 var 2") (deftest :oodml/update-records/5 (with-dataset *ds-nodes* (flet ((print-fresh-setting () (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (format nil "~a ~a ~a" (slot-value node 'setting-id) (slot-value node 'title) (slot-value node 'vars))))) (values (print-fresh-setting) (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title") (setf (slot-value node 'vars) "Altered vars") (clsql:update-records-from-instance node) (print-fresh-setting))))) "3 Setting2 var 2" "3 Altered title Altered vars") (deftest :oodml/update-records/5-slots (with-dataset *ds-nodes* (flet ((print-fresh-setting () (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (format nil "~a ~a ~a" (slot-value node 'setting-id) (slot-value node 'title) (slot-value node 'vars))))) (values (print-fresh-setting) (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title") (setf (slot-value node 'vars) "Altered vars") (clsql-sys:update-record-from-slot node 'title) (clsql-sys:update-record-from-slot node 'vars) (print-fresh-setting)) (let ((node (car (clsql:select 'setting :where [= 3 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Setting2") (setf (slot-value node 'vars) "var 2") (clsql-sys:update-record-from-slots node '(title vars)) (print-fresh-setting))))) "3 Setting2 var 2" "3 Altered title Altered vars" "3 Setting2 var 2") (deftest :oodml/update-records/6 (with-dataset *ds-nodes* (flet ((print-fresh-setting () (let ((node (car (clsql:select 'setting :where [= 7 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (format nil "~a ~a ~a" (slot-value node 'setting-id) (slot-value node 'title) (or (slot-value node 'vars) "NIL"))))) (values (print-fresh-setting) (let ((node (car (clsql:select 'setting :where [= 7 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title") (setf (slot-value node 'vars) "Altered vars") (clsql:update-records-from-instance node) (print-fresh-setting)) (let ((node (car (clsql:select 'setting :where [= 7 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "theme-2") (setf (slot-value node 'vars) nil) (clsql:update-records-from-instance node) (print-fresh-setting))))) "7 theme-2 NIL" "7 Altered title Altered vars" "7 theme-2 NIL") (deftest :oodml/update-records/7 (with-dataset *ds-nodes* (flet ((print-fresh-user () "requery to get what the db has, and print out." (let ((node (car (clsql:select 'user :where [= 5 [slot-value 'user 'user-id]] :flatp t :caching nil)))) (format nil "~a ~a ~a" (slot-value node 'user-id) (slot-value node 'title) (slot-value node 'nick))))) (values (print-fresh-user) (let ((node (car (clsql:select 'user :where [= 5 [slot-value 'user 'user-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title") (setf (slot-value node 'nick) "Altered nick") (clsql:update-records-from-instance node) (print-fresh-user))))) "5 user-2 second user" "5 Altered title Altered nick") (deftest :oodml/update-records/8 (with-dataset *ds-nodes* (flet ((print-fresh-theme () (let ((node (car (clsql:select 'theme :where [= 6 [slot-value 'theme 'theme-id]] :flatp t :caching nil)))) (with-slots (node-id setting-id theme-id title vars doc) node (format nil "~a ~a ~a ~a ~a ~a" node-id setting-id theme-id title (or vars "NIL") doc))))) (values (print-fresh-theme) (let ((node (car (clsql:select 'setting :where [= 6 [slot-value 'setting 'setting-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title") (setf (slot-value node 'vars) nil) (clsql:update-records-from-instance node) (print-fresh-theme)) (let ((node (car (clsql:select 'theme :where [= 6 [slot-value 'theme 'theme-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "Altered title again") (setf (slot-value node 'doc) "altered doc") (clsql:update-records-from-instance node) (print-fresh-theme)) (let ((node (car (clsql:select 'theme :where [= 6 [slot-value 'theme 'theme-id]] :flatp t :caching nil)))) (setf (slot-value node 'title) "theme-1") (setf (slot-value node 'vars) "empty") (setf (slot-value node 'doc) "first theme") (clsql:update-records-from-instance node) (print-fresh-theme))))) "6 6 6 theme-1 empty first theme" "6 6 6 Altered title NIL first theme" "6 6 6 Altered title again NIL altered doc" "6 6 6 theme-1 empty first theme") (deftest :oodml/update-records/9 (with-dataset *ds-nodes* (flet ((print-fresh-subloc () (let ((sl (car (clsql:select 'subloc :where [= 10 [slot-value 'subloc 'subloc-id]] :flatp t :caching nil)))) (unless sl (error "Couldn't find expected sublocation")) (format nil "~a ~a ~a" (slot-value sl 'subloc-id) (slot-value sl 'title) (slot-value sl 'loc))))) (values (print-fresh-subloc) (let ((sl (car (clsql:select 'subloc :where [= 10 [slot-value 'subloc 'subloc-id]] :flatp t :caching nil)))) (setf (slot-value sl 'title) "Altered subloc title") (setf (slot-value sl 'loc) "Altered loc") (clsql:update-records-from-instance sl) (print-fresh-subloc))))) "10 subloc-1 a subloc" "10 Altered subloc title Altered loc") (deftest :oodml/update-records/9-slots ;like 9, but use slots fns. (with-dataset *ds-nodes* (flet ((print-fresh-subloc () (let ((sl (car (clsql:select 'subloc :where [= 10 [slot-value 'subloc 'subloc-id]] :flatp t :caching nil)))) (unless sl (error "In psfl: found no sublocation with id = 10")) (format nil "~a ~a ~a" (slot-value sl 'subloc-id) (slot-value sl 'title) (slot-value sl 'loc))))) (values (print-fresh-subloc) (let ((sl (car (clsql:select 'subloc :where [= 10 [slot-value 'subloc 'subloc-id]] :flatp t :caching nil)))) (unless sl (error "Select for modification: Found no sublocation with id = 10")) (setf (slot-value sl 'title) "Altered subloc title") (setf (slot-value sl 'loc) "Altered loc") (clsql:update-record-from-slot sl 'title) (clsql:update-record-from-slot sl 'loc) (print-fresh-subloc)) (let ((sl (car (clsql:select 'subloc :where [= 10 [slot-value 'subloc 'subloc-id]] :flatp t :caching nil)))) (unless sl (error "Select for next modification: Found no sublocation with id = 10")) (setf (slot-value sl 'title) "subloc-1") (setf (slot-value sl 'loc) "a subloc") (clsql:update-record-from-slots sl '(title loc)) (print-fresh-subloc))))) "10 subloc-1 a subloc" "10 Altered subloc title Altered loc" "10 subloc-1 a subloc") ;; Verify that we can set a float to nil and then read it back ;; (was failing in Postgresql at somepoint) (deftest :oodml/update-records/10 (with-dataset *ds-employees* (let ((emp (first (clsql:select 'employee :where [= [emplid] 1] :flatp t)))) (setf (height emp) nil) (clsql-sys:update-record-from-slot emp 'height) (values (clsql:select [height] :from [employee] :where [= [emplid] 1]) (progn (setf (height emp) 42.0) (clsql-sys:update-record-from-slot emp 'height) (clsql:select [height] :from [employee] :where [= [emplid] 1])) (progn (setf (height emp) 24.13d0) (clsql-sys:update-record-from-slot emp 'height) (clsql:select [height] :from [employee] :where [= [emplid] 1]))))) ((nil)) ((42.0d0)) ((24.13d0))) (deftest :oodml/update-records/11 (with-dataset *ds-artists* (clsql:update-records-from-instance artist1) (list (name artist1) (artist_id artist1))) ("Mogwai" 1)) (deftest :oodml/update-records/12 (with-dataset *ds-artists* (clsql:update-records-from-instance artist1) (list (name artist1) (genre artist1))) ("Mogwai" "Unknown")) ;; tests update-instance-from-records (deftest :oodml/update-instance/1 (with-dataset *ds-employees* (values (format nil "~a ~a: ~a" (slot-value employee1 'first-name) (slot-value employee1 'last-name) (slot-value employee1 'email)) (progn (clsql:update-records [employee] :av-pairs '(([first-name] "Ivan") ([last-name] "Petrov") ([email] "petrov@soviet.org")) :where [= [emplid] 1]) (clsql:update-instance-from-records employee1) (format nil "~a ~a: ~a" (slot-value employee1 'first-name) (slot-value employee1 'last-name) (slot-value employee1 'email))))) "Vladimir Lenin: lenin@soviet.org" "Ivan Petrov: petrov@soviet.org") ;; tests update-slot-from-record (deftest :oodml/update-instance/2 (with-dataset *ds-employees* (values (slot-value employee1 'email) (progn (clsql:update-records [employee] :av-pairs '(([email] "lenin-nospam@soviet.org")) :where [= [emplid] 1]) (clsql:update-slot-from-record employee1 'email) (slot-value employee1 'email)))) "lenin@soviet.org" "lenin-nospam@soviet.org") ;; tests normalizedp update-instance-from-records (deftest :oodml/update-instance/3 (with-dataset *ds-nodes* (values (with-output-to-string (out) (format out "~a ~a ~a ~a" (slot-value theme2 'theme-id) (slot-value theme2 'title) (or (slot-value theme2 'vars) "NIL") (slot-value theme2 'doc))) (progn (clsql:update-records [node] :av-pairs '(([title] "Altered title")) :where [= [node-id] 7]) (clsql:update-records [setting] :av-pairs '(([vars] "Altered vars")) :where [= [setting-id] 7]) (clsql:update-records [theme] :av-pairs '(([doc] "Altered doc")) :where [= [theme-id] 7]) (clsql:update-instance-from-records theme2) (with-output-to-string (out) (format out "~a ~a ~a ~a" (slot-value theme2 'theme-id) (slot-value theme2 'title) (slot-value theme2 'vars) (slot-value theme2 'doc)))))) "7 theme-2 NIL second theme" "7 Altered title Altered vars Altered doc") (deftest :oodml/update-instance/4 (with-dataset *ds-nodes* (values (progn (setf loc2 (car (clsql:select 'location :where [= [node-id] 9] :flatp t :caching nil))) (format nil "~a ~a" (slot-value loc2 'node-id) (slot-value loc2 'title))) (progn (clsql:update-records [node] :av-pairs '(([title] "Altered title")) :where [= [node-id] 9]) (clsql:update-instance-from-records loc2) (format nil "~a ~a" (slot-value loc2 'node-id) (slot-value loc2 'title))))) "9 location-2" "9 Altered title") (deftest :oodml/update-instance/5 (with-dataset *ds-nodes* (values (format nil "~a ~a ~a" (slot-value subloc2 'subloc-id) (slot-value subloc2 'title) (slot-value subloc2 'loc)) (progn (clsql:update-records [node] :av-pairs '(([title] "Altered title")) :where [= [node-id] 11]) (clsql:update-records [subloc] :av-pairs '(([loc] "Altered loc")) :where [= [subloc-id] 11]) (clsql:update-instance-from-records subloc2) (format nil "~a ~a ~a" (slot-value subloc2 'subloc-id) (slot-value subloc2 'title) (slot-value subloc2 'loc))))) "11 subloc-2 second subloc" "11 Altered title Altered loc") ;; tests update-slot-from-record with normalizedp stuff (deftest :oodml/update-instance/6 (with-dataset *ds-nodes* (values (slot-value theme1 'doc) (slot-value theme1 'vars) (progn (clsql:update-records [theme] :av-pairs '(([doc] "altered doc")) :where [= [theme-id] 6]) (clsql:update-slot-from-record theme1 'doc) (slot-value theme1 'doc)) (progn (clsql:update-records [setting] :av-pairs '(([vars] "altered vars")) :where [= [setting-id] 6]) (clsql:update-slot-from-record theme1 'vars) (slot-value theme1 'vars)))) "first theme" "empty" "altered doc" "altered vars") (deftest :oodml/update-instance/7 (flet ((print-loc (l) (format nil "~a: ~a" (slot-value l 'node-id) (slot-value l 'title))) (print-subloc (sl) (format nil "~a: ~a" (slot-value sl 'node-id) (slot-value sl 'loc)))) (with-dataset *ds-nodes* (values (print-loc loc2) (print-subloc subloc2) (progn (clsql:update-records [node] :av-pairs '(([title] "altered title")) :where [= [node-id] (node-id loc2)]) (clsql:update-slot-from-record loc2 'title) (print-loc loc2)) (progn (clsql:update-records [subloc] :av-pairs '(([loc] "altered loc")) :where [= [subloc-id] (subloc-id subloc2)]) (clsql:update-slot-from-record subloc2 'loc) (print-subloc subloc2))))) "9: location-2" "11: second subloc" "9: altered title" "11: altered loc") (deftest :oodml/do-query/1 (with-dataset *ds-employees* (let ((result '())) (clsql:do-query ((e) [select 'employee :order-by [emplid]]) (push (slot-value e 'last-name) result)) result)) ("Putin" "Yeltsin" "Gorbachev" "Chernenko" "Andropov" "Brezhnev" "Kruschev" "Trotsky" "Stalin" "Lenin")) (deftest :oodml/do-query/2 (with-dataset *ds-employees* (let ((result '())) (clsql:do-query ((e c) [select 'employee 'company :where [= [slot-value 'employee 'last-name] "Lenin"]]) (push (list (slot-value e 'last-name) (slot-value c 'name)) result)) result)) (("Lenin" "Widgets Inc."))) (deftest :oodml/map-query/1 (with-dataset *ds-employees* (clsql:map-query 'list #'last-name [select 'employee :order-by [emplid]])) ("Lenin" "Stalin" "Trotsky" "Kruschev" "Brezhnev" "Andropov" "Chernenko" "Gorbachev" "Yeltsin" "Putin")) (deftest :oodml/map-query/2 (with-dataset *ds-employees* (clsql:map-query 'list #'(lambda (e c) (list (slot-value e 'last-name) (slot-value c 'name))) [select 'employee 'company :where [= [slot-value 'employee 'last-name] "Lenin"]])) (("Lenin" "Widgets Inc."))) (deftest :oodml/iteration/3 (with-dataset *ds-employees* (loop for (e) being the records in [select 'employee :where [< [emplid] 4] :order-by [emplid]] collect (slot-value e 'last-name))) ("Lenin" "Stalin" "Trotsky")) (deftest :oodml/cache/1 (with-dataset *ds-employees* (let ((*default-caching* t)) (setf (clsql-sys:record-caches *default-database*) nil) (let ((employees (select 'employee))) (every #'(lambda (a b) (eq a b)) employees (select 'employee))))) t) (deftest :oodml/cache/2 (with-dataset *ds-employees* (let* ((*default-caching* t) (employees (select 'employee))) (equal employees (select 'employee :flatp t)))) nil) (deftest :oodml/refresh/1 (with-dataset *ds-employees* (let* ((clsql-sys:*default-caching* t) (addresses (select 'address))) (equal addresses (select 'address :refresh t)))) t) (deftest :oodml/refresh/2 (with-dataset *ds-employees* (let* ((clsql-sys:*default-caching* t) (addresses (select 'address :order-by [addressid] :flatp t :refresh t)) (city (slot-value (car addresses) 'city))) (clsql:update-records [addr] :av-pairs '((city_field "A new city")) :where [= [addressid] (slot-value (car addresses) 'addressid)]) (let* ((new-addresses (select 'address :order-by [addressid] :refresh t :flatp t)) (new-city (slot-value (car addresses) 'city)) ) (clsql:update-records [addr] :av-pairs `((city_field ,city)) :where [= [addressid] (slot-value (car addresses) 'addressid)]) (values (equal addresses new-addresses) city new-city)))) t "Leningrad" "A new city") (deftest :oodml/refresh/3 (with-dataset *ds-employees* (let* ((clsql-sys:*default-caching* t) (addresses (select 'address :order-by [addressid] :flatp t))) (values (equal addresses (select 'address :refresh t :flatp t)) (equal addresses (select 'address :flatp t))))) nil nil) (deftest :oodml/refresh/4 (with-dataset *ds-employees* (let* ((clsql-sys:*default-caching* t) (addresses (select 'address :order-by [addressid] :flatp t :refresh t)) (*db-auto-sync* t)) (make-instance 'address :addressid 1000 :city "A new address city") (let ((new-addresses (select 'address :order-by [addressid] :flatp t :refresh t))) (values (length addresses) (length new-addresses) (eq (first addresses) (first new-addresses)) (eq (second addresses) (second new-addresses)))))) 3 4 t t) (deftest :oodml/uoj/full-set (with-dataset *ds-employees* (progn (let* ((dea-list (select 'deferred-employee-address :caching nil :order-by ["ea_join" aaddressid] :flatp t)) (dea-list-copy (copy-seq dea-list)) (initially-unbound (every #'(lambda (dea) (not (slot-boundp dea 'address))) dea-list))) (update-objects-joins dea-list :slots 'address :max-len nil) (values initially-unbound (equal dea-list dea-list-copy) (every #'(lambda (dea) (slot-boundp dea 'address)) dea-list) (every #'(lambda (dea) (typep (slot-value dea 'address) 'address)) dea-list) (mapcar #'(lambda (dea) (slot-value (slot-value dea 'address) 'addressid)) dea-list))))) t t t t (1 1 2 2 2 3)) (deftest :oodml/uoj/batched (with-dataset *ds-employees* (progn (let* ((dea-list (select 'deferred-employee-address :caching nil :order-by ["ea_join" aaddressid] :flatp t)) (dea-list-copy (copy-seq dea-list)) (initially-unbound (every #'(lambda (dea) (not (slot-boundp dea 'address))) dea-list))) (update-objects-joins dea-list :slots 'address :max-len 2) (values initially-unbound (equal dea-list dea-list-copy) (every #'(lambda (dea) (slot-boundp dea 'address)) dea-list) (every #'(lambda (dea) (typep (slot-value dea 'address) 'address)) dea-list) (mapcar #'(lambda (dea) (slot-value (slot-value dea 'address) 'addressid)) dea-list))))) t t t t (1 1 2 2 2 3)) ;; update-object-joins needs to be fixed for multiple keys #+ignore (deftest :oodml/uoj/multi-key (progn (clsql:update-objects-joins (list company1)) (mapcar #'(lambda (e) (slot-value e 'ecompanyid)) (company-employees company1))) (1 1 1 1 1 1 1 1 1 1)) (deftest :oodml/big/1 (with-dataset *ds-big* (let ((objs (clsql:select 'big :order-by [i] :flatp t))) (values (length objs) (do ((i 0 (1+ i)) (max (expt 2 60)) (rest objs (cdr rest))) ((= i (length objs)) t) (let ((obj (car rest)) (index (1+ i))) (unless (and (eql (slot-value obj 'i) index) (eql (slot-value obj 'bi) (truncate max index))) (print index) (describe obj) (return nil))))))) 555 t) (deftest :oodml/db-auto-sync/1 (with-dataset *ds-employees* (values (progn (make-instance 'employee :emplid 20 :groupid 1 :last-name "Ivanovich") (select [last-name] :from [employee] :where [= [emplid] 20] :flatp t :field-names nil)) (let ((*db-auto-sync* t)) (make-instance 'employee :emplid 20 :groupid 1 :last-name "Ivanovich") (prog1 (select [last-name] :from [employee] :flatp t :field-names nil :where [= [emplid] 20]) (delete-records :from [employee] :where [= [emplid] 20]))))) nil ("Ivanovich")) (deftest :oodml/db-auto-sync/2 (with-dataset *ds-employees* (values (let ((instance (make-instance 'employee :emplid 20 :groupid 1 :last-name "Ivanovich"))) (setf (slot-value instance 'last-name) "Bulgakov") (select [last-name] :from [employee] :where [= [emplid] 20] :flatp t :field-names nil)) (let* ((*db-auto-sync* t) (instance (make-instance 'employee :emplid 20 :groupid 1 :last-name "Ivanovich"))) (setf (slot-value instance 'last-name) "Bulgakov") (prog1 (select [last-name] :from [employee] :flatp t :field-names nil :where [= [emplid] 20]) (delete-records :from [employee] :where [= [emplid] 20]))))) nil ("Bulgakov")) (deftest :oodml/db-auto-sync/3 (with-dataset *ds-nodes* (values (progn (make-instance 'theme :title "test-theme" :vars "test-vars" :doc "test-doc") (select [node-id] :from [node] :where [= [title] "test-theme"] :flatp t :field-names nil)) (let ((*db-auto-sync* t)) (make-instance 'theme :title "test-theme" :vars "test-vars" :doc "test-doc") (prog1 (select [title] :from [node] :where [= [title] "test-theme"] :flatp t :field-names nil) (delete-records :from [node] :where [= [title] "test-theme"]) (delete-records :from [setting] :where [= [vars] "test-vars"]) (delete-records :from [theme] :where [= [doc] "test-doc"]))))) nil ("test-theme")) (deftest :oodml/db-auto-sync/4 (with-dataset *ds-nodes* (values (let ((inst (make-instance 'theme :title "test-theme" :vars "test-vars" :doc "test-doc")) (*print-circle* nil)) (setf (slot-value inst 'title) "alternate-test-theme") (format nil "~a ~a ~a ~a" (or (select [title] :from [node] :where [= [title] "test-theme"] :flatp t :field-names nil) "NIL") (or (select [vars] :from [setting] :where [= [vars] "test-vars"] :flatp t :field-names nil) "NIL") (or (select [doc] :from [theme] :where [= [doc] "test-doc"] :flatp t :field-names nil) "NIL") (or (select [title] :from [node] :where [= [title] "alternate-test-theme"] :flatp t :field-names nil) "NIL"))) (let* ((*db-auto-sync* t) (inst (make-instance 'theme :title "test-theme" :vars "test-vars" :doc "test-doc"))) (setf (slot-value inst 'title) "alternate-test-theme") (prog1 (format nil "~a ~a ~a ~a" (or (select [title] :from [node] :where [= [title] "test-theme"] :flatp t :field-names nil) "NIL") (or (select [vars] :from [setting] :where [= [vars] "test-vars"] :flatp t :field-names nil) "NIL") (or (select [doc] :from [theme] :where [= [doc] "test-doc"] :flatp t :field-names nil) "NIL") (or (select [title] :from [node] :where [= [title] "alternate-test-theme"] :flatp t :field-names nil) "NIL")) (delete-records :from [node] :where [= [title] "alternate-test-theme"]) (delete-records :from [setting] :where [= [vars] "test-vars"]) (delete-records :from [theme] :where [= [doc] "test-doc"]))))) "NIL NIL NIL NIL" "NIL (test-vars) (test-doc) (alternate-test-theme)") (deftest :oodml/setf-slot-value/1 (with-dataset *ds-employees* (let* ((*db-auto-sync* t) (instance (make-instance 'employee :emplid 20 :groupid 1))) (prog1 (setf (slot-value instance 'first-name) "Mikhail" (slot-value instance 'last-name) "Bulgakov") (delete-records :from [employee] :where [= [emplid] 20])))) "Bulgakov") (deftest :oodml/float/1 (with-dataset *ds-employees* (let* ((emp1 (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :caching nil))) (height (slot-value emp1 'height))) (prog1 (progn (setf (slot-value emp1 'height) 1.0E0) (clsql:update-record-from-slot emp1 'height) (= (car (clsql:select [height] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil)) 1)) (setf (slot-value emp1 'height) height) (clsql:update-record-from-slot emp1 'height)))) t) (deftest :oodml/float/2 (with-dataset *ds-employees* (let* ((emp1 (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :caching nil))) (height (slot-value emp1 'height))) (prog1 (progn (setf (slot-value emp1 'height) 1.0S0) (clsql:update-record-from-slot emp1 'height) (= (car (clsql:select [height] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil)) 1)) (setf (slot-value emp1 'height) height) (clsql:update-record-from-slot emp1 'height)))) t) (deftest :oodml/float/3 (with-dataset *ds-employees* (let* ((emp1 (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :caching nil))) (height (slot-value emp1 'height))) (prog1 (progn (setf (slot-value emp1 'height) 1.0F0) (clsql:update-record-from-slot emp1 'height) (= (car (clsql:select [height] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil)) 1)) (setf (slot-value emp1 'height) height) (clsql:update-record-from-slot emp1 'height)))) t) (deftest :oodml/float/4 (with-dataset *ds-employees* (let* ((emp1 (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :caching nil))) (height (slot-value emp1 'height))) (prog1 (progn (setf (slot-value emp1 'height) 1.0D0) (clsql:update-record-from-slot emp1 'height) (= (car (clsql:select [height] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil)) 1)) (setf (slot-value emp1 'height) height) (clsql:update-record-from-slot emp1 'height)))) t) (deftest :oodml/float/5 (with-dataset *ds-employees* (let* ((emp1 (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :caching nil))) (height (slot-value emp1 'height))) (prog1 (progn (setf (slot-value emp1 'height) 1.0L0) (clsql:update-record-from-slot emp1 'height) (= (car (clsql:select [height] :from [employee] :where [= [emplid] 1] :flatp t :field-names nil)) 1)) (setf (slot-value emp1 'height) height) (clsql:update-record-from-slot emp1 'height)))) t) )) cl-sql-6.7.2/tests/test-connection.lisp0000644000175000017500000000521212473715066017115 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-connection.lisp ;;;; Purpose: Tests for CLSQL database connections ;;;; Authors: Marcus Pearce and Kevin M. Rosenberg ;;;; Created: March 2004 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (setq *rt-connection* '( (deftest :connection/1 (let ((database (clsql:find-database (clsql:database-name clsql:*default-database*) :db-type (clsql-sys:database-type clsql:*default-database*)))) (eql (clsql-sys:database-type database) *test-database-type*)) t) (deftest :connection/2 (clsql-sys::string-to-list-connection-spec "localhost/dbname/user/passwd") ("localhost" "dbname" "user" "passwd")) (deftest :connection/3 (clsql-sys::string-to-list-connection-spec "dbname/user@hostname") ("hostname" "dbname" "user")) (deftest :connection/execute-command ;;check that we can issue basic commands. (values (clsql-sys:execute-command "CREATE TABLE DUMMY (foo integer)") (clsql-sys:execute-command "DROP TABLE DUMMY")) nil nil) (deftest :connection/query ;;check that we can do a basic query (first (clsql:query "SELECT 1" :flatp t :field-names nil)) 1) (deftest :connection/query-command ;;queries that are commands (no result set) shouldn't cause breakage (values (clsql-sys:query "CREATE TABLE DUMMY (foo integer)") (clsql-sys:query "DROP TABLE DUMMY")) nil nil) (deftest :connection/pool/procedure-mysql (unwind-protect (progn (clsql-sys:disconnect) (test-connect :pool t) (clsql-sys:execute-command "CREATE PROCEDURE prTest () BEGIN SELECT 1 \"a\",2 \"b\",3 \"c\" ,4 \"d\" UNION SELECT 5,6,7,8; END;") (clsql-sys:disconnect) (test-connect :pool t) (let ((p0 (clsql-sys:query "CALL prTest();" :flatp t))) (clsql-sys:disconnect) (test-connect :pool t) (let ((p1 (clsql-sys:query "CALL prTest();" :flatp t))) (clsql-sys:disconnect) (test-connect :pool t) (values p0 p1)))) (ignore-errors (clsql-sys:execute-command "DROP PROCEDURE prTest;")) (test-connect)) ((1 2 3 4) (5 6 7 8)) ((1 2 3 4) (5 6 7 8))) )) cl-sql-6.7.2/tests/test-i18n.lisp0000644000175000017500000000401511725170505015525 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-i18n.lisp ;;;; Purpose: Tests for passing non-ascii encoded strings to db and back ;;;; Author: Nathan Bird & Kevin M. Rosenberg ;;;; Created: Feb 2010 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (setq *rt-i18n* '( ;;; The point of these two is to require proper encoding support ;;; UTF-8 for example can handle these easily. ;; I show this as a 20char string and 27 bytes in utf-8 (deftest :basic/i18n/1 (let ((uffi:*default-foreign-encoding* :utf-8)) (first (query "SELECT 'Iñtërnâtiônàlizætiøn'" :flatp t :field-names nil))) "Iñtërnâtiônàlizætiøn") ;; the z in this one is even stronger ;; I show this as a 20char string and 28 bytes in utf-8 (deftest :basic/i18n/2 (let ((uffi:*default-foreign-encoding* :utf-8)) (first (query "SELECT 'Iñtërnâtiônàližætiøn'" :flatp t :field-names nil))) "Iñtërnâtiônàližætiøn") (deftest :basic/i18n/big/1 (let ((test-string (with-output-to-string (str) (dotimes (n 250) (write-sequence "Iñtërnâtiônàližætiøn" str))))) (with-dataset *ds-bigtext* (clsql-sys:execute-command (format nil "INSERT INTO testbigtext (a) VALUES ('~a')" test-string)) (let ((res (first (clsql:query "SELECT a from testbigtext" :flatp t :field-names nil)))) (assert (equal test-string res) (test-string res) "Returned internationalization string was incorrect. Test :basic/i18n/big/1"))))) )) cl-sql-6.7.2/tests/ds-employees.lisp0000644000175000017500000003761312473715066016421 0ustar kevinkevin(in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (defparameter company1 nil) (defparameter employee1 nil) (defparameter employee2 nil) (defparameter employee3 nil) (defparameter employee4 nil) (defparameter employee5 nil) (defparameter employee6 nil) (defparameter employee7 nil) (defparameter employee8 nil) (defparameter employee9 nil) (defparameter employee10 nil) (defparameter address1 nil) (defparameter address2 nil) (defparameter address3 nil) (defparameter employee-address1 nil) (defparameter employee-address2 nil) (defparameter employee-address3 nil) (defparameter employee-address4 nil) (defparameter employee-address5 nil) (defparameter employee-address6 nil) (defclass thing () ((extraterrestrial :initform nil :initarg :extraterrestrial))) (def-view-class person (thing) ((height :db-kind :base :accessor height :type float :initarg :height) (married :db-kind :base :accessor married :type boolean :initarg :married) (birthday :type clsql:wall-time :initarg :birthday) (bd-utime :type clsql:universal-time :initarg :bd-utime) (hobby :db-kind :virtual :initarg :hobby :initform nil))) (def-view-class employee (person) ((emplid :db-kind :key :db-constraints (:not-null :unique) :type integer :initarg :emplid) (groupid :db-kind :key :db-constraints :not-null :type integer :initarg :groupid) (title :accessor title :type symbol :initarg :title) (first-name :accessor first-name :type (varchar 30) :initarg :first-name) (last-name :accessor last-name :type (varchar 30) :initarg :last-name) (email :accessor employee-email :type (varchar 100) :initarg :email) (ecompanyid :type integer :initarg :companyid) (company :accessor employee-company :db-kind :join :db-info (:join-class company :home-key ecompanyid :foreign-key companyid :set nil)) (managerid :type integer :initarg :managerid) (manager :accessor employee-manager :db-kind :join :db-info (:join-class employee :home-key managerid :foreign-key emplid :set nil)) (addresses :accessor employee-addresses :db-kind :join :db-info (:join-class employee-address :home-key emplid :foreign-key aemplid :target-slot address :set t))) (:base-table employee)) (def-view-class company () ((companyid :db-kind :key :db-constraints :not-null :type integer :initarg :companyid) (groupid :db-kind :key :db-constraints :not-null :type integer :initarg :groupid) (name :type (varchar 100) :initarg :name) (presidentid :type integer :initarg :presidentid) (president :reader president :db-kind :join :db-info (:join-class employee :home-key presidentid :foreign-key emplid :set nil)) (employees :reader company-employees :db-kind :join :db-info (:join-class employee :home-key (companyid groupid) :foreign-key (ecompanyid groupid) :set t)))) (def-view-class address () ((addressid :db-kind :key :db-constraints :not-null :type integer :initarg :addressid) (street-number :type integer :initarg :street-number) (street-name :type (varchar 30) :void-value "" :initarg :street-name) (city :column "city_field" :void-value "no city" :type (varchar 30) :initarg :city) (postal-code :column zip :type integer :void-value 0 :initarg :postal-code)) (:base-table addr)) ;; many employees can reside at many addressess (def-view-class employee-address () ((aemplid :type integer :initarg :emplid) (aaddressid :type integer :initarg :addressid) (verified :type boolean :initarg :verified) (address :db-kind :join :db-info (:join-class address :home-key aaddressid :foreign-key addressid :retrieval :immediate)) (employee :db-kind :join :db-info (:join-class employee :home-key aemplid :foreign-key emplid :retrieval :immediate))) (:base-table "ea_join")) (def-view-class deferred-employee-address () ((aemplid :type integer :initarg :emplid) (aaddressid :type integer :initarg :addressid) (verified :type boolean :initarg :verified) (address :db-kind :join :db-info (:join-class address :home-key aaddressid :foreign-key addressid :retrieval :deferred :set nil))) (:base-table "ea_join")) (defun initialize-ds-employees () ;; (start-sql-recording :type :both) (mapc #'clsql:create-view-from-class '(employee company address employee-address)) (setq *test-start-utime* (get-universal-time)) (let* ((*db-auto-sync* t) (now-time (clsql:utime->time *test-start-utime*))) (setf company1 (make-instance 'company :presidentid 1 :companyid 1 :groupid 1 :name "Widgets Inc.") employee1 (make-instance 'employee :emplid 1 :groupid 1 :married t :title 'supplicant :height (1+ (random 1.00)) :bd-utime *test-start-utime* :birthday now-time :first-name "Vladimir" :last-name "Lenin" :email "lenin@soviet.org" :companyid 1) employee2 (make-instance 'employee :emplid 2 :groupid 1 :title :adherent :height (1+ (random 1.00)) :married t :bd-utime *test-start-utime* :birthday now-time :first-name "Josef" :last-name "Stalin" :email "stalin@soviet.org" :managerid 1 :companyid 1) employee3 (make-instance 'employee :emplid 3 :groupid 1 :title 'cl-user::novice :height (1+ (random 1.00)) :married t :bd-utime *test-start-utime* :birthday now-time :first-name "Leon" :last-name "Trotsky" :email "trotsky@soviet.org" :managerid 1 :companyid 1) employee4 (make-instance 'employee :emplid 4 :groupid 1 :height (1+ (random 1.00)) :married nil :bd-utime *test-start-utime* :birthday now-time :first-name "Nikita" :last-name "Kruschev" :email "kruschev@soviet.org" :managerid 1 :companyid 1) employee5 (make-instance 'employee :emplid 5 :groupid 1 :married nil :height (1+ (random 1.00)) :bd-utime *test-start-utime* :birthday now-time :first-name "Leonid" :last-name "Brezhnev" :email "brezhnev@soviet.org" :managerid 1 :companyid 1) employee6 (make-instance 'employee :emplid 6 :groupid 1 :married nil :height (1+ (random 1.00)) :bd-utime *test-start-utime* :birthday now-time :first-name "Yuri" :last-name "Andropov" :email "andropov@soviet.org" :managerid 1 :companyid 1) employee7 (make-instance 'employee :emplid 7 :groupid 1 :height (1+ (random 1.00)) :married nil :bd-utime *test-start-utime* :birthday now-time :first-name "Konstantin" :last-name "Chernenko" :email "chernenko@soviet.org" :managerid 1 :companyid 1) employee8 (make-instance 'employee :emplid 8 :groupid 1 :height (1+ (random 1.00)) :married nil :bd-utime *test-start-utime* :birthday now-time :first-name "Mikhail" :last-name "Gorbachev" :email "gorbachev@soviet.org" :managerid 1 :companyid 1) employee9 (make-instance 'employee :emplid 9 :groupid 1 :married nil :height (1+ (random 1.00)) :bd-utime *test-start-utime* :birthday now-time :first-name "Boris" :last-name "Yeltsin" :email "yeltsin@soviet.org" :managerid 1 :companyid 1) employee10 (make-instance 'employee :emplid 10 :groupid 1 :married nil :height (1+ (random 1.00)) :bd-utime *test-start-utime* :birthday now-time :first-name "Vladimir" :last-name "Putin" :email "putin@soviet.org" :managerid 1 :companyid 1) address1 (make-instance 'address :addressid 1 :street-number 10 :street-name "Park Place" :city "Leningrad" :postal-code 123) address2 (make-instance 'address :addressid 2) address3 (make-instance 'address :addressid 3) employee-address1 (make-instance 'employee-address :emplid 1 :addressid 1 :verified t) employee-address2 (make-instance 'employee-address :emplid 2 :addressid 2 :verified t) employee-address3 (make-instance 'employee-address :emplid 3 :addressid 1 :verified nil) employee-address4 (make-instance 'employee-address :emplid 1 :addressid 2 :verified nil) employee-address5 (make-instance 'employee-address :emplid 3 :addressid 2) employee-address6 (make-instance 'employee-address :emplid 4 :addressid 3))) ;; sleep to ensure birthdays are no longer at current time ;(sleep 1) ;want to find the test that depends on it, put the sleep there. #|| ;; Lenin manages everyone ; (clsql:add-to-relation employee2 'manager employee1) (clsql:add-to-relation employee3 'manager employee1) (clsql:add-to-relation employee4 'manager employee1) (clsql:add-to-relation employee5 'manager employee1) (clsql:add-to-relation employee6 'manager employee1) (clsql:add-to-relation employee7 'manager employee1) (clsql:add-to-relation employee8 'manager employee1) (clsql:add-to-relation employee9 'manager employee1) (clsql:add-to-relation employee10 'manager employee1) ;; Everyone works for Widgets Inc. ; (clsql:add-to-relation company1 'employees employee1) (clsql:add-to-relation company1 'employees employee2) (clsql:add-to-relation company1 'employees employee3) (clsql:add-to-relation company1 'employees employee4) (clsql:add-to-relation company1 'employees employee5) (clsql:add-to-relation company1 'employees employee6) (clsql:add-to-relation company1 'employees employee7) (clsql:add-to-relation company1 'employees employee8) (clsql:add-to-relation company1 'employees employee9) (clsql:add-to-relation company1 'employees employee10) ;; Lenin is president of Widgets Inc. ; (clsql:add-to-relation company1 'president employee1) ||# ;; store these instances #|| (clsql:update-records-from-instance employee1) (clsql:update-records-from-instance employee2) (clsql:update-records-from-instance employee3) (clsql:update-records-from-instance employee4) (clsql:update-records-from-instance employee5) (clsql:update-records-from-instance employee6) (clsql:update-records-from-instance employee7) (clsql:update-records-from-instance employee8) (clsql:update-records-from-instance employee9) (clsql:update-records-from-instance employee10) (clsql:update-records-from-instance company1) (clsql:update-records-from-instance address1) (clsql:update-records-from-instance address2) ||# ) (def-dataset *ds-employees* (:setup initialize-ds-employees) (:cleanup (lambda () (mapc #'clsql-sys:drop-view-from-class '(employee company address employee-address)) (ignore-errors (clsql-sys:execute-command "DROP TABLE ea_join"))))) cl-sql-6.7.2/tests/utils.lisp0000644000175000017500000000750411616055736015146 0ustar kevinkevin;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: utils.lisp ;;;; Purpose: Classes and utilities for testing ;;;; Author: Kevin M. Rosenberg ;;;; Created: Mar 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (defun %get-int (v) (etypecase v (string (parse-integer v :junk-allowed t)) (integer v) (number (truncate v)))) (defvar *config-pathname* (make-pathname :defaults (user-homedir-pathname) :name ".clsql-test" :type "config")) (defvar +all-db-types+ '(:postgresql :postgresql-socket :postgresql-socket3 :mysql :sqlite :sqlite3 :odbc :oracle #+allegro :aodbc)) (defclass conn-specs () ((aodbc :accessor aodbc-spec :initform nil) (mysql :accessor mysql-spec :initform nil) (postgresql :accessor postgresql-spec :initform nil) (postgresql-socket :accessor postgresql-socket-spec :initform nil) (postgresql-socket3 :accessor postgresql-socket3-spec :initform nil) (sqlite :accessor sqlite-spec :initform nil) (sqlite3 :accessor sqlite3-spec :initform nil) (odbc :accessor odbc-spec :initform nil) (oracle :accessor oracle-spec :initform nil)) (:documentation "Connection specs for CLSQL testing")) (defun read-specs (&optional (path *config-pathname*)) (if (probe-file path) (with-open-file (stream path :direction :input) (let ((specs (make-instance 'conn-specs))) (dolist (spec (read stream) specs) (push (second spec) (slot-value specs (intern (symbol-name (first spec)) (find-package '#:clsql-tests))))))) (progn (warn "CLSQL test config file ~S not found" path) nil))) (defun spec-fn (db-type) (intern (concatenate 'string (symbol-name db-type) (symbol-name '#:-spec)) (find-package '#:clsql-tests))) (defun db-type-spec (db-type specs) (funcall (spec-fn db-type) specs)) (defun summarize-test-report (sexp &optional (output *standard-output*)) (flet ((db-title (db-type underlying-db-type) (format nil "~A~A" db-type (if (eq db-type underlying-db-type) "" (format nil "/~A" underlying-db-type))))) (with-open-file (in sexp :direction :input) (let ((eof (cons nil nil))) (do ((form (read in nil eof) (read in nil eof))) ((eq form eof)) (destructuring-bind (db-type underlying-db-type utime total-tests failed-tests impl-type impl-version machine-type) form (declare (ignorable utime impl-version)) (if failed-tests (format output "~&~A: ~D of ~D tests failed (~A, ~A).~&" (db-title db-type underlying-db-type) (length failed-tests) total-tests machine-type impl-type) (format output "~&~A: All ~D tests passed (~A, ~A).~%" (db-title db-type underlying-db-type) total-tests machine-type impl-type)))))))) cl-sql-6.7.2/tests/test-internal.lisp0000644000175000017500000000610212651763351016567 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-internal.lisp ;;;; Purpose: Tests for internal clsql functions ;;;; Author: Kevin M. Rosenberg ;;;; Created: May 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (setq *rt-internal* '( (deftest :int/convert/1 (clsql-sys::prepared-sql-to-postgresql-sql "SELECT FOO FROM BAR") "SELECT FOO FROM BAR") (deftest :int/convert/2 (clsql-sys::prepared-sql-to-postgresql-sql "SELECT FOO FROM BAR WHERE ID=?") "SELECT FOO FROM BAR WHERE ID=$1") (deftest :int/convert/3 (clsql-sys::prepared-sql-to-postgresql-sql "SELECT FOO FROM \"BAR\" WHERE ID=? AND CODE=?") "SELECT FOO FROM \"BAR\" WHERE ID=$1 AND CODE=$2") (deftest :int/convert/4 (clsql-sys::prepared-sql-to-postgresql-sql "SELECT FOO FROM BAR WHERE ID=\"Match?\" AND CODE=?") "SELECT FOO FROM BAR WHERE ID=\"Match?\" AND CODE=$1") (deftest :int/convert/5 (clsql-sys::prepared-sql-to-postgresql-sql "SELECT 'FOO' FROM BAR WHERE ID='Match?''?' AND CODE=?") "SELECT 'FOO' FROM BAR WHERE ID='Match?''?' AND CODE=$1") (deftest :int/output-caching/1 ;; ensure that key generation and matching is working ;; so that this table doesnt balloon (more than designed) (list (progn (clsql:sql [foo]) (clsql:sql [foo]) (hash-table-count clsql-sys::*output-hash*)) (progn (clsql:sql [foo.bar]) (clsql:sql [foo bar]) (hash-table-count clsql-sys::*output-hash*)) (progn (clsql:sql (clsql-sys:sql-expression :table (clsql-sys::database-identifier 'foo) :attribute (clsql-sys::database-identifier 'bar))) (clsql:sql (clsql-sys:sql-expression :table (clsql-sys::database-identifier 'foo) :attribute (clsql-sys::database-identifier 'bar))) (hash-table-count clsql-sys::*output-hash*))) (1 2 2)) (deftest :int/output-caching/2 ;; ensure that we can disable the output cache and ;; still have everything work (let ((clsql-sys::*output-hash*)) (list (clsql:sql [foo]) (clsql:sql [foo]) (clsql:sql [foo.bar]))) ("FOO" "FOO" "FOO.BAR")) (deftest :currency/read-value/1 (list (clsql-sys::read-decimal-value "$ 10,500.30") (clsql-sys::read-decimal-value "$ 10.500,30") (clsql-sys::read-decimal-value "-10 500,30") (clsql-sys::read-decimal-value "$ 10.500,30")) (1050030/100 1050030/100 -1050030/100 1050030/100)) )) cl-sql-6.7.2/tests/test-pool.lisp0000644000175000017500000000664312473715066015740 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-pool.lisp ;;;; Purpose: Tests for connection pools ;;;; Author: Ryan Davis ;;;; Created: June 27 2011 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) ;; setup a dummy database for the pool to use (pushnew :dummy clsql-sys:*loaded-database-types*) (defclass dummy-database (clsql-sys:database) () (:default-initargs :database-type :dummy)) (defmethod clsql-sys:database-connect (connection-spec (database-type (eql :dummy))) (let ((db (make-instance 'dummy-database :connection-spec connection-spec))) (setf (slot-value db 'clsql-sys::state) :open) db)) (defmethod clsql-sys::database-name-from-spec (connection-spec (database-type (eql :dummy))) "dummy") (defmethod clsql-sys::database-acquire-from-conn-pool ((db dummy-database)) T) (setq *rt-pool* '( (deftest :pool/acquire (let ((pool (clsql-sys::find-or-create-connection-pool nil :dummy)) dbx res) (clsql-sys::clear-conn-pool pool) (flet ((test-result (x) (push x res))) (test-result (length (clsql-sys::all-connections pool))) (test-result (length (clsql-sys::free-connections pool))) (clsql-sys:with-database (db nil :database-type :dummy :pool T) (test-result (not (null db))) (test-result (length (clsql-sys::all-connections pool))) (test-result (length (clsql-sys::free-connections pool))) (setf dbx db)) (test-result (length (clsql-sys::all-connections pool))) (test-result (length (clsql-sys::free-connections pool))) (clsql-sys:with-database (db nil :database-type :dummy :pool T) (test-result (eq db dbx))) ) (nreverse res)) (0 0 T 1 0 1 1 T) ) (deftest :pool/max-free-connections (let ((pool (clsql-sys::find-or-create-connection-pool nil :dummy))) (flet ((run (max-free dbs-to-release) (let ((clsql-sys:*db-pool-max-free-connections* max-free) dbs) (clsql-sys::clear-conn-pool pool) (dotimes (i dbs-to-release dbs) (push (clsql-sys:connect nil :database-type :dummy :pool T :if-exists :new) dbs)) (list (length (clsql-sys::all-connections pool)) (progn (dolist (db dbs) (clsql-sys:disconnect :database db)) (length (clsql-sys::free-connections pool)) ))))) (append (run 5 10) (run nil 10)))) (10 5 10 10) ) (deftest :pool/find-or-create-connection-pool (let ((p (clsql-sys::find-or-create-connection-pool nil :dummy))) (values (null p) (eq p (clsql-sys::find-or-create-connection-pool nil :dummy)) (eq p (clsql-sys::find-or-create-connection-pool :spec :dummy)))) nil T nil) )) cl-sql-6.7.2/tests/ds-artists.lisp0000644000175000017500000000167012303270414016063 0ustar kevinkevin(in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (defparameter artist1 nil) (def-view-class artist () ((artist_id :accessor artist_id :initarg :id :type integer :db-kind :key :db-constraints (:not-null :auto-increment) :autoincrement-sequence 'artist_artist_id_seq) (name :accessor name :initarg :name :type (varchar 20)) (genre :accessor genre :initarg :genre :type (varchar 10) :db-constraints (:default "'Unknown'")))) (defun initialize-ds-artists () (mapc #'clsql:create-view-from-class '(artist)) (setq *test-start-utime* (get-universal-time)) (let* ((*db-auto-sync* nil)) (setf artist1 (make-instance 'artist :name "Mogwai")))) (def-dataset *ds-artists* (:setup initialize-ds-artists) (:cleanup (lambda () (mapc #'clsql-sys:drop-view-from-class '(artist)) (ignore-errors (mapc #'clsql-sys:drop-sequence (list "artist_artist_id_seq")))))) cl-sql-6.7.2/tests/ds-nodes.lisp0000644000175000017500000001022712303270414015500 0ustar kevinkevin(in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (defparameter basenode nil) (defparameter derivednode1 nil) (defparameter derivednode2 nil) (defparameter node nil) (defparameter setting1 nil) (defparameter setting2 nil) (defparameter user1 nil) (defparameter user2 nil) (defparameter theme1 nil) (defparameter theme2 nil) (defparameter loc1 nil) (defparameter loc2 nil) (defparameter subloc1 nil) (defparameter subloc2 nil) ;; classes for testing the normalizedp stuff (def-view-class node () ((node-id :accessor node-id :initarg :node-id :type integer :db-kind :key :db-constraints (:not-null :auto-increment)) (title :accessor title :initarg :title :type (varchar 240)) (createtime :accessor createtime :initarg :createtime :type wall-time :db-constraints (:not-null) :initform (get-time)) (modifiedtime :accessor modifiedtime :initarg :modifiedtime :type wall-time :initform (make-time :year 1900 :month 1 :day 1)))) (def-view-class setting (node) ((setting-id :accessor setting-id :initarg :setting-id :type integer :db-kind :key :db-constraints (:not-null )) (vars :accessor vars :initarg :vars :type (varchar 240))) (:normalizedp t)) (def-view-class user (node) ((user-id :accessor user-id :initarg :user-id :type integer :db-kind :key :db-constraints (:not-null )) (nick :accessor nick :initarg :nick :type (varchar 64))) (:base-table "nodeuser") (:normalizedp t)) (def-view-class theme (setting) ((theme-id :accessor theme-id :initarg :theme-id :type integer :db-kind :key :db-constraints (:not-null )) (doc :accessor doc :initarg :doc :type (varchar 240))) (:normalizedp t)) ;; A class that uses only a superclass db table (def-view-class location (node) () (:base-table node) (:normalizedp t)) (def-view-class subloc (location) ((subloc-id :accessor subloc-id :initarg :subloc-id :type integer :db-kind :key :db-constraints (:not-null )) (loc :accessor loc :initarg :loc :type (varchar 64))) (:normalizedp t)) (defun initialize-ds-nodes () ;; (start-sql-recording :type :both) (mapc #'clsql:create-view-from-class '(node setting user theme location subloc)) (setq *test-start-utime* (get-universal-time)) (let* ((*db-auto-sync* t)) (setf node (make-instance 'node :title "Bare node") setting1 (make-instance 'setting :title "Setting1" :vars "var 1") setting2 (make-instance 'setting :title "Setting2" :vars "var 2") user1 (make-instance 'user :title "user-1" :nick "first user") user2 (make-instance 'user :title "user-2" :nick "second user") theme1 (make-instance 'theme :title "theme-1" :vars "empty" :doc "first theme") theme2 (make-instance 'theme :title "theme-2" :doc "second theme") loc1 (make-instance 'location :title "location-1") loc2 (make-instance 'location :title "location-2") subloc1 (make-instance 'subloc :title "subloc-1" :loc "a subloc") subloc2 (make-instance 'subloc :title "subloc-2" :loc "second subloc")))) (def-dataset *ds-nodes* (:setup initialize-ds-nodes) (:cleanup (lambda () (mapc #'clsql-sys:drop-view-from-class '(node setting user theme location subloc)) (ignore-errors (clsql-sys:execute-command "DROP TABLE nodeuser") (mapc #'clsql-sys:drop-sequence '(node_node_id_seq setting_setting_id_seq subloc_subloc_id_seq theme_theme_id_seq nodeuser_user_id_seq) ))))) cl-sql-6.7.2/tests/test-fdml.lisp0000644000175000017500000006500112473715066015702 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ====================================================================== ;;;; File: test-fdml.lisp ;;;; Author: Marcus Pearce , Kevin Rosenberg ;;;; Created: 30/03/2004 ;;;; ;;;; Tests for the CLSQL Functional Data Manipulation Language ;;;; (FDML). ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ====================================================================== (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) ;;started defining an independent dataset that doesn't depend on the view-classes ;; but there is a *lot* of stuff in the file assuming that dataset. ;; (def-dataset *ds-fdml* ;; (:setup (lambda () ;; (let ((*backend-warning-behavior* ;; (if (member *test-database-type* '(:postgresql :postgresql-socket)) ;; :ignore ;; :warn))) ;; (clsql-sys:execute-command "CREATE TABLE EMPLOYEE ( ;; emplid integer NOT NULL, ;; groupid integer NOT NULL, ;; first_name character varying(30), ;; last_name character varying(30), ;; email character varying(100), ;; ecompanyid integer, ;; managerid integer, ;; height double precision, ;; married boolean, ;; birthday timestamp, ;; bd_utime bigint, ;; CONSTRAINT employeepk PRIMARY KEY (emplid, groupid), ;; CONSTRAINT employee_emplid_key UNIQUE (emplid) ;; )")))) ;; (:sqldata "EMPLOYEE" ;; "emplid,groupid,first_name,last_name,email,height,birthday" ;; "10,1,'a','b','a@b.org',1.9,current_timestamp" ;; "11,1,'x','y','x@y.org',null,current_timestamp" ;; ) ;; (:cleanup "DROP TABLE EMPLOYEE") ;; ) (setq *rt-fdml* '( ;; Computed values are not always classified as numeric by psqlodbc (deftest :fdml/query/1 (with-dataset *ds-employees* (let ((count (caar (clsql:query "SELECT COUNT(*) FROM EMPLOYEE WHERE (EMAIL LIKE '%org')" :field-names nil)))) (%get-int count))) 10) (deftest :fdml/query/2 (with-dataset *ds-employees* (multiple-value-bind (rows field-names) (clsql:query "SELECT FIRST_NAME,LAST_NAME FROM EMPLOYEE WHERE (EMPLID <= 5) ORDER BY LAST_NAME") (values rows (mapcar 'string-upcase field-names)))) (("Leonid" "Brezhnev") ("Nikita" "Kruschev") ("Vladimir" "Lenin") ("Josef" "Stalin") ("Leon" "Trotsky")) ("FIRST_NAME" "LAST_NAME")) (deftest :fdml/query/3 (with-dataset *ds-employees* (caar (clsql:query "SELECT EMPLID FROM EMPLOYEE WHERE LAST_NAME = 'Andropov'" :field-names nil))) 6) (deftest :fdml/query/4 (with-dataset *ds-employees* (typep (caar (clsql:query "SELECT HEIGHT FROM EMPLOYEE WHERE LAST_NAME = 'Andropov'" :field-names nil)) 'float)) t) (deftest :fdml/query/5 (with-dataset *ds-employees* (let ((res (clsql:query (clsql:sql [select [first-name] [sum [emplid]] :from [employee]] [group-by [first-name]] [order-by [sum [emplid]]]) :field-names nil :result-types nil))) (mapcar (lambda (p) (list (car p) (%get-int (second p)))) res))) (("Josef" 2) ("Leon" 3) ("Nikita" 4) ("Leonid" 5) ("Yuri" 6) ("Konstantin" 7) ("Mikhail" 8) ("Boris" 9) ("Vladimir" 11))) (deftest :fdml/query/6 (with-dataset *ds-employees* (let ((res (clsql:query (clsql:sql [union [select [emplid] :from [employee]] [select [groupid] :from [company]]]) :field-names nil :result-types nil :flatp t ))) (values (or (eql *test-database-type* :postgresql-socket3) (every #'stringp res)) (sort (mapcar #'%get-int res) #'<=)))) t (1 2 3 4 5 6 7 8 9 10)) (deftest :fdml/query/7 (with-dataset *ds-employees* (let ((res (car (clsql:query (clsql:sql [intersect [select [emplid] :from [employee]] [select [groupid] :from [company]]]) :field-names nil :result-types nil :flatp t)))) (values (or (stringp res) (eql *test-database-type* :postgresql-socket3)) (nth-value 0 (%get-int res))))) t 1) (deftest :fdml/query/8 (with-dataset *ds-employees* (let ((res (clsql:query (clsql:sql [except [select [emplid] :from [employee]] [select [groupid] :from [company]]]) :field-names nil :result-types nil :flatp t))) (values (or (every #'stringp res) (eql *test-database-type* :postgresql-socket3)) (sort (mapcar #'%get-int res) #'<=)))) t (2 3 4 5 6 7 8 9 10)) ;; compare min, max and average hieghts in inches (they're quite short ;; these guys!) (deftest :fdml/select/1 (with-dataset *ds-employees* (let ((max (clsql:select [function "floor" [/ [* [max [height]] 100] 2.54]] :from [employee] :result-types nil :flatp t)) (min (clsql:select [function "floor" [/ [* [min [height]] 100] 2.54]] :from [employee] :result-types nil :flatp t)) (avg (clsql:select [function "floor" [avg [/ [* [height] 100] 2.54]]] :from [employee] :result-types nil :flatp t))) (apply #'< (mapcar #'%get-int (append min avg max))))) t) (deftest :fdml/select/2 (with-dataset *ds-employees* (clsql:select [first-name] :from [employee] :flatp t :distinct t :field-names nil :result-types nil :order-by [first-name])) ("Boris" "Josef" "Konstantin" "Leon" "Leonid" "Mikhail" "Nikita" "Vladimir" "Yuri")) (deftest :fdml/select/3 (with-dataset *ds-employees* (let ((res (clsql:select [first-name] [count [*]] :from [employee] :result-types nil :group-by [first-name] :order-by [first-name] :field-names nil))) (mapcar (lambda (p) (list (car p) (%get-int (second p)))) res))) (("Boris" 1) ("Josef" 1) ("Konstantin" 1) ("Leon" 1) ("Leonid" 1) ("Mikhail" 1) ("Nikita" 1) ("Vladimir" 2) ("Yuri" 1))) (deftest :fdml/select/4 (with-dataset *ds-employees* (clsql:select [last-name] :from [employee] :where [like [email] "%org"] :order-by [last-name] :field-names nil :result-types nil :flatp t)) ("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Lenin" "Putin" "Stalin" "Trotsky" "Yeltsin")) (deftest :fdml/select/5 (with-dataset *ds-employees* (clsql:select [email] :from [employee] :flatp t :result-types nil :where [in [employee emplid] [select [managerid] :from [employee]]] :field-names nil)) ("lenin@soviet.org")) (deftest :fdml/select/6 (with-dataset *ds-employees* (if (clsql-sys:db-type-has-fancy-math? *test-database-underlying-type*) (mapcar #'%get-int (clsql:select [function "trunc" [height]] :from [employee] :result-types nil :field-names nil :flatp t)) (mapcar #'%get-int (clsql:select [height] :from [employee] :flatp t :field-names nil :result-types nil)))) (1 1 1 1 1 1 1 1 1 1)) (deftest :fdml/select/7 (with-dataset *ds-employees* (let ((result (car (clsql:select [max [emplid]] :from [employee] :flatp t :field-names nil :result-types nil)))) (values (nth-value 0 (%get-int result))))) 10) (deftest :fdml/select/8 (with-dataset *ds-employees* (let ((result (car (clsql:select [min [emplid]] :from [employee] :flatp t :field-names nil :result-types nil)))) (values (nth-value 0 (%get-int result))))) 1) (deftest :fdml/select/9 (with-dataset *ds-employees* (let ((val (car (clsql:select [avg [emplid]] :from [employee] :flatp t :field-names nil :result-types nil)))) (typecase val (string (subseq val 0 3)) (number (format nil "~,1F" val))))) "5.5") (deftest :fdml/select/10 (with-dataset *ds-employees* (clsql:select [last-name] :from [employee] :where [not [in [emplid] [select [managerid] :from [company]]]] :result-types nil :field-names nil :flatp t :order-by [last-name])) ("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Putin" "Stalin" "Trotsky" "Yeltsin")) (deftest :fdml/select/11 (with-dataset *ds-employees* (clsql:select [last-name] :from [employee] :where [married] :flatp t :field-names nil :order-by [emplid] :result-types nil)) ("Lenin" "Stalin" "Trotsky")) (deftest :fdml/select/12 (with-dataset *ds-employees* (let ((v 1)) (clsql:select [last-name] :from [employee] :where [= [emplid] v] :field-names nil :result-types nil))) (("Lenin"))) (deftest :fdml/select/13 (with-dataset *ds-employees* (multiple-value-bind (results field-names) (clsql:select [emplid] [last-name] :from [employee] :where [= [emplid] 1]) (values results (mapcar #'string-downcase field-names)))) ((1 "Lenin")) ("emplid" "last_name")) (deftest :fdml/select/14 (with-dataset *ds-employees* (floatp (car (clsql:select [height] :from [employee] :where [= [emplid] 1] :flatp t)))) t) (deftest :fdml/select/15 (with-dataset *ds-employees* (multiple-value-bind (rows field-names) (clsql:select [addressid] [street-number] [street-name] [city_field] [zip] :from [addr] :where [= 1 [addressid]]) (values rows (mapcar #'string-downcase field-names)))) ((1 10 "Park Place" "Leningrad" 123)) ("addressid" "street_number" "street_name" "city_field" "zip")) (deftest :fdml/select/16 (with-dataset *ds-employees* (clsql:select [emplid] :from [employee] :where [= 1 [emplid]] :field-names nil)) ((1))) (deftest :fdml/select/17 (with-dataset *ds-employees* (clsql:select [emplid] [last-name] :from [employee] :where [= 1 [emplid]] :field-names nil)) ((1 "Lenin"))) (deftest :fdml/select/18 (with-dataset *ds-employees* (clsql:select [emplid :string] [last-name] :from [employee] :where [= 1 [emplid]] :field-names nil)) (("1" "Lenin"))) (deftest :fdml/select/19 (with-dataset *ds-employees* (mapcar #'%get-int (clsql:select [emplid] :from [employee] :order-by [emplid] :where [between [* [emplid] 10] [* 5 10] [* 10 10]] :field-names nil :result-types nil :flatp t))) (5 6 7 8 9 10)) (deftest :fdml/select/20 (with-dataset *ds-employees* (mapcar #'%get-int (clsql:select [emplid] :from [employee] :order-by [emplid] :where [not [between [* [emplid] 10] [* 5 10] [* 10 10]]] :field-names nil :result-types nil :flatp t))) (1 2 3 4)) (deftest :fdml/select/21 (with-dataset *ds-employees* (clsql:select [substring [first-name] 1 4] :from [employee] :flatp t :order-by [emplid] :field-names nil)) ("Vlad" "Jose" "Leon" "Niki" "Leon" "Yuri" "Kons" "Mikh" "Bori" "Vlad")) (deftest :fdml/select/22 (with-dataset *ds-employees* (case *test-database-underlying-type* (:mssql (clsql:select [+ [first-name] " " [last-name]] :from [employee] :flatp t :order-by [emplid] :field-names nil)) (t (clsql:select [|| [first-name] " " [last-name]] :from [employee] :flatp t :order-by [emplid] :field-names nil)))) ("Vladimir Lenin" "Josef Stalin" "Leon Trotsky" "Nikita Kruschev" "Leonid Brezhnev" "Yuri Andropov" "Konstantin Chernenko" "Mikhail Gorbachev" "Boris Yeltsin" "Vladimir Putin")) (deftest :fdml/select/23 (with-dataset *ds-employees* (mapcar #'%get-int (clsql:select [emplid] :from [employee] :where [in [emplid] '(1 2 3 4)] :flatp t :order-by [emplid] :field-names nil :result-types nil))) (1 2 3 4)) (deftest :fdml/select/24 (with-dataset *ds-employees* (clsql:select [distinct [first-name]] :from [employee] :flatp t :order-by [first-name] :field-names nil :result-types nil)) ("Boris" "Josef" "Konstantin" "Leon" "Leonid" "Mikhail" "Nikita" "Vladimir" "Yuri")) (deftest :fdml/select/25 (with-dataset *ds-employees* (clsql:select [first-name] :from (clsql-sys:convert-to-db-default-case "employee" *default-database*) :flatp t :distinct t :field-names nil :result-types nil :order-by [first-name])) ("Boris" "Josef" "Konstantin" "Leon" "Leonid" "Mikhail" "Nikita" "Vladimir" "Yuri")) (deftest :fdml/select/26 (with-dataset *ds-employees* (clsql:select ["table" first-name] ["table" last-name] :from '([employee "table"] [employee "join"]) :where [and [= ["table" first-name] ["join" first-name]] [not [= ["table" emplid] ["join" emplid]]]] :order-by '(["table" last-name]) :result-types nil :field-names nil)) (("Vladimir" "Lenin") ("Vladimir" "Putin"))) (deftest :fdml/select/27 (with-dataset *ds-employees* (mapcar #'%get-int (clsql:select [coalesce [managerid] 10] :from [employee] :order-by [emplid] :field-names nil :result-types nil :flatp t))) (10 1 1 1 1 1 1 1 1 1)) (deftest :fdml/select/28 (with-dataset *ds-employees* (loop for column in `([*] [emplid]) collect (%get-int (car (clsql:select [count column] :from [employee] :flatp t :result-types nil :field-names nil))))) (10 10)) (deftest :fdml/select/29 (with-dataset *ds-employees* (clsql:select [first-name] [last-name] :from [employee] :result-types nil :field-names nil :order-by '(([first-name] :asc) ([last-name] :desc)))) (("Boris" "Yeltsin") ("Josef" "Stalin") ("Konstantin" "Chernenko") ("Leon" "Trotsky") ("Leonid" "Brezhnev") ("Mikhail" "Gorbachev") ("Nikita" "Kruschev") ("Vladimir" "Putin") ("Vladimir" "Lenin") ("Yuri" "Andropov"))) (deftest :fdml/select/30 (with-dataset *ds-employees* (clsql:select [first-name] [last-name] :from [employee] :result-types nil :field-names nil :order-by '(([first-name] :asc) ([last-name] :asc)))) (("Boris" "Yeltsin") ("Josef" "Stalin") ("Konstantin" "Chernenko") ("Leon" "Trotsky") ("Leonid" "Brezhnev") ("Mikhail" "Gorbachev") ("Nikita" "Kruschev") ("Vladimir" "Lenin") ("Vladimir" "Putin") ("Yuri" "Andropov"))) (deftest :fdml/select/31 (with-dataset *ds-employees* (clsql:select [last-name] :from [employee] :set-operation [union [select [first-name] :from [employee] :order-by [last-name]]] :flatp t :result-types nil :field-names nil)) ("Andropov" "Boris" "Brezhnev" "Chernenko" "Gorbachev" "Josef" "Konstantin" "Kruschev" "Lenin" "Leon" "Leonid" "Mikhail" "Nikita" "Putin" "Stalin" "Trotsky" "Vladimir" "Yeltsin" "Yuri")) (deftest :fdml/select/32 (with-dataset *ds-employees* (mapcar #'%get-int (clsql:select [emplid] :from [employee] :where [= [emplid] [any [select [companyid] :from [company]]]] :flatp t :result-types nil :field-names nil))) (1)) (deftest :fdml/select/33 (with-dataset *ds-employees* (clsql:select [last-name] :from [employee] :where [> [emplid] [all [select [groupid] :from [employee]]]] :order-by [last-name] :flatp t :result-types nil :field-names nil)) ("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Putin" "Stalin" "Trotsky" "Yeltsin")) (deftest :fdml/select/34 (with-dataset *ds-employees* (loop for x from 1 below 5 collect (car (clsql:select [last-name] :from [employee] :where [= [emplid] x] :flatp t :result-types nil :field-names nil)))) ("Lenin" "Stalin" "Trotsky" "Kruschev")) ;; test escaping of single quotes (deftest :fdml/select/35 (with-dataset *ds-fddl* (first (clsql:select "What's up doc?" :from [alpha] :flatp t :field-names nil))) "What's up doc?") ;; test proper treatment of backslash (depending on backend) (deftest :fdml/select/36 (with-dataset *ds-fddl* (first (clsql:select "foo\\bar\\baz" :from [alpha] :flatp t :field-names nil))) "foo\\bar\\baz") (deftest :fdml/select/37 (with-dataset *ds-employees* (clsql:select [emplid] :from [employee] :order-by [emplid] :limit 5 :field-names nil :flatp t)) (1 2 3 4 5)) (deftest :fdml/select/38 (with-dataset *ds-employees* (clsql:select [emplid] :from [employee] :order-by [emplid] :limit 5 :offset 3 :field-names nil :flatp t)) (4 5 6 7 8)) (deftest :fdml/do-query/1 (with-dataset *ds-employees* (let ((result '())) (clsql:do-query ((name) [select [last-name] :from [employee] :order-by [last-name]]) (push name result)) result)) ("Yeltsin" "Trotsky" "Stalin" "Putin" "Lenin" "Kruschev" "Gorbachev" "Chernenko" "Brezhnev" "Andropov")) (deftest :fdml/map-query/1 (with-dataset *ds-employees* (clsql:map-query 'list #'identity [select [last-name] :from [employee] :flatp t :order-by [last-name]])) ("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Lenin" "Putin" "Stalin" "Trotsky" "Yeltsin")) (deftest :fdml/map-query/2 (with-dataset *ds-employees* (clsql:map-query 'vector #'identity [select [last-name] :from [employee] :flatp t :order-by [last-name]])) #("Andropov" "Brezhnev" "Chernenko" "Gorbachev" "Kruschev" "Lenin" "Putin" "Stalin" "Trotsky" "Yeltsin")) (deftest :fdml/map-query/3 (with-dataset *ds-employees* (clsql:map-query 'list #'identity [select [last-name] :from [employee] :order-by [last-name]])) (("Andropov") ("Brezhnev") ("Chernenko") ("Gorbachev") ("Kruschev") ("Lenin") ("Putin") ("Stalin") ("Trotsky") ("Yeltsin"))) (deftest :fdml/map-query/4 (with-dataset *ds-employees* (clsql:map-query 'list #'identity [select [first-name] [last-name] :from [employee] :order-by [last-name]])) (("Yuri" "Andropov") ("Leonid" "Brezhnev") ("Konstantin" "Chernenko") ("Mikhail" "Gorbachev") ("Nikita" "Kruschev") ("Vladimir" "Lenin") ("Vladimir" "Putin") ("Josef" "Stalin") ("Leon" "Trotsky") ("Boris" "Yeltsin"))) (deftest :fdml/loop/1 (with-dataset *ds-employees* (loop for (forename surname) being each tuple in [select [first-name] [last-name] :from [employee] :order-by [last-name]] collect (concatenate 'string forename " " surname))) ("Yuri Andropov" "Leonid Brezhnev" "Konstantin Chernenko" "Mikhail Gorbachev" "Nikita Kruschev" "Vladimir Lenin" "Vladimir Putin" "Josef Stalin" "Leon Trotsky" "Boris Yeltsin")) (deftest :fdml/loop/2 (with-dataset *ds-employees* (loop for (addressid) being each tuple in [select [addressid] :from [addr] :order-by [addressid]] collect addressid)) (1 2 3)) (deftest :fdml/loop/3 (with-dataset *ds-employees* (loop for addressid being each tuple in [select [addressid] :from [addr] :order-by [addressid]] collect addressid)) (1 2 3)) ;; inserts a record using all values only and then deletes it (deftest :fdml/insert/1 (with-dataset *ds-employees* (let ((now (get-universal-time))) (clsql:insert-records :into [employee] :values `(11 1 "clsql-sys::astronaut" "Yuri" "Gagarin" "gagarin@soviet.org" 1 1 1.85 t ,(clsql:utime->time now) ,now)) (values (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11]) (progn (clsql:delete-records :from [employee] :where [= [emplid] 11]) (clsql:select [*] :from [employee] :where [= [emplid] 11]))))) (("Yuri" "Gagarin" "gagarin@soviet.org")) nil) ;; inserts a record using attributes and values and then deletes it (deftest :fdml/insert/2 (with-dataset *ds-employees* (progn (clsql:insert-records :into [employee] :attributes '(emplid groupid first_name last_name email ecompanyid managerid) :values '(11 1 "Yuri" "Gagarin" "gagarin@soviet.org" 1 1)) (values (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11]) (progn (clsql:delete-records :from [employee] :where [= [emplid] 11]) (clsql:select [*] :from [employee] :where [= [emplid] 11]))))) (("Yuri" "Gagarin" "gagarin@soviet.org")) nil) ;; inserts a record using av-pairs and then deletes it (deftest :fdml/insert/3 (with-dataset *ds-employees* (progn (clsql:insert-records :into [employee] :av-pairs'((emplid 11) (groupid 1) (first_name "Yuri") (last_name "Gagarin") (email "gagarin@soviet.org") (ecompanyid 1) (managerid 1))) (values (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11]) (progn (clsql:delete-records :from [employee] :where [= [emplid] 11]) (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 11]))))) (("Yuri" "Gagarin" "gagarin@soviet.org")) nil) ;; inserts a records using a query from another table (deftest :fdml/insert/4 (with-dataset *ds-employees* (progn (clsql:create-table [employee2] '(([forename] string) ([surname] string) ([email] string))) (clsql:insert-records :into [employee2] :query [select [first-name] [last-name] [email] :from [employee]] :attributes '(forename surname email)) (prog1 (equal (clsql:select [*] :from [employee2]) (clsql:select [first-name] [last-name] [email] :from [employee])) (clsql:drop-table [employee2] :if-does-not-exist :ignore)))) t) ;; updates a record using attributes and values and then deletes it (deftest :fdml/update/1 (with-dataset *ds-employees* (progn (clsql:update-records [employee] :attributes '(first_name last_name email) :values '("Yuri" "Gagarin" "gagarin@soviet.org") :where [= [emplid] 1]) (values (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 1]) (progn (clsql:update-records [employee] :av-pairs'((first_name "Vladimir") (last_name "Lenin") (email "lenin@soviet.org")) :where [= [emplid] 1]) (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 1]))))) (("Yuri" "Gagarin" "gagarin@soviet.org")) (("Vladimir" "Lenin" "lenin@soviet.org"))) ;; updates a record using av-pairs and then deletes it (deftest :fdml/update/2 (with-dataset *ds-employees* (progn (clsql:update-records [employee] :av-pairs'((first_name "Yuri") (last_name "Gagarin") (email "gagarin@soviet.org")) :where [= [emplid] 1]) (values (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 1]) (progn (clsql:update-records [employee] :av-pairs'((first_name "Vladimir") (last_name "Lenin") (email "lenin@soviet.org")) :where [= [emplid] 1]) (clsql:select [first-name] [last-name] [email] :from [employee] :where [= [emplid] 1]))))) (("Yuri" "Gagarin" "gagarin@soviet.org")) (("Vladimir" "Lenin" "lenin@soviet.org"))) ;; starts a transaction deletes a record and then rolls back the deletion (deftest :fdml/transaction/1 (with-dataset *ds-employees* (let ((results '())) ;; test if we are in a transaction (push (clsql:in-transaction-p) results) ;;start a transaction (clsql:start-transaction) ;; test if we are in a transaction (push (clsql:in-transaction-p) results) ;;Putin has got to go (clsql:delete-records :from [employee] :where [= [last-name] "Putin"]) ;;Should be nil (push (clsql:select [*] :from [employee] :where [= [last-name] "Putin"]) results) ;;Oh no, he's still there (clsql:rollback) ;; test that we are out of the transaction (push (clsql:in-transaction-p) results) ;; Check that we got him back alright (push (clsql:select [email] :from [employee] :where [= [last-name] "Putin"] :flatp t) results) (apply #'values (nreverse results)))) nil t nil nil ("putin@soviet.org")) ;; starts a transaction, updates a record and then rolls back the update (deftest :fdml/transaction/2 (with-dataset *ds-employees* (let ((results '())) ;; test if we are in a transaction (push (clsql:in-transaction-p) results) ;;start a transaction (clsql:start-transaction) ;; test if we are in a transaction (push (clsql:in-transaction-p) results) ;;Putin has got to go (clsql:update-records [employee] :av-pairs '((email "putin-nospam@soviet.org")) :where [= [last-name] "Putin"]) ;;Should be new value (push (clsql:select [email] :from [employee] :where [= [last-name] "Putin"] :flatp t) results) ;;Oh no, he's still there (clsql:rollback) ;; test that we are out of the transaction (push (clsql:in-transaction-p) results) ;; Check that we got him back alright (push (clsql:select [email] :from [employee] :where [= [last-name] "Putin"] :flatp t) results) (apply #'values (nreverse results)))) nil t ("putin-nospam@soviet.org") nil ("putin@soviet.org")) ;; runs an update within a transaction and checks it is committed (deftest :fdml/transaction/3 (with-dataset *ds-employees* (let ((results '())) ;; check status (push (clsql:in-transaction-p) results) ;; update records (push (clsql:with-transaction () (clsql:update-records [employee] :av-pairs '((email "lenin-nospam@soviet.org")) :where [= [emplid] 1])) results) ;; check status (push (clsql:in-transaction-p) results) ;; check that was committed (push (clsql:select [email] :from [employee] :where [= [emplid] 1] :flatp t) results) ;; undo the changes (push (clsql:with-transaction () (clsql:update-records [employee] :av-pairs '((email "lenin@soviet.org")) :where [= [emplid] 1])) results) ;; and check status (push (clsql:in-transaction-p) results) ;; check that was committed (push (clsql:select [email] :from [employee] :where [= [emplid] 1] :flatp t) results) (apply #'values (nreverse results)))) nil nil nil ("lenin-nospam@soviet.org") nil nil ("lenin@soviet.org")) ;; runs a valid update and an invalid one within a transaction and checks ;; that the valid update is rolled back when the invalid one fails. (deftest :fdml/transaction/4 (with-dataset *ds-employees* (let ((results '())) ;; check status (push (clsql:in-transaction-p) results) (handler-case (clsql:with-transaction () ;; valid update (clsql:update-records [employee] :av-pairs '((email "lenin-nospam@soviet.org")) :where [= [emplid] 1]) ;; invalid update which generates an error (clsql:update-records [employee] :av-pairs '((emale "lenin-nospam@soviet.org")) :where [= [emplid] 1])) (clsql:sql-database-error () (progn ;; check status (push (clsql:in-transaction-p) results) ;; and check nothing done (push (clsql:select [email] :from [employee] :where [= [emplid] 1] :flatp t) results) (apply #'values (nreverse results))))))) nil nil ("lenin@soviet.org")) )) cl-sql-6.7.2/tests/datasets.lisp0000644000175000017500000001200312303270414015566 0ustar kevinkevin;;;; Proposed new file in clsql-tests to enable abstracting datasets for reuse. ;;;; ;;;; The core is def-datset and with-dataset that respectively define a set, ;;;; and enable one for a dynamic scope. Datasets will normally be setup and ;;;; torn down in the scope of one test, which may impose a computation ;;;; overhead, but enables simpler tests by not worrying about side-effects ;;;; between tests. ;;;; ;;;; In general datasets should be database agnostic, but because the code ;;;; is only run in the scope of a test, if a test is excluded for a backend ;;;; or some other reason then it is never run hence doesn't cause problems. (in-package #:clsql-tests) (defparameter *dataset-debug-on-error* nil "If we get an error while loading or cleaning up the dataset, should we debug (T) or just print and quit.") (defun generic-error (e) (when (and *dataset-debug-on-error* *debugger-hook*) (invoke-debugger e)) (fresh-line *error-output*) (princ e *error-output*) (throw 'quit-dataset e)) (defmacro def-dataset (name &body body) "Define a dataset" ;;probably just shove this into a param, perhaps a marginal ;; bit of processing first. `(defparameter ,name ',body)) (defmacro with-dataset (name &body body) "Use a dataset in a dynamic scope, e.g. a single test. 1. Before the body: * :setup is run * :data is loaded 2. Body 3. :cleanup always happens" `(catch 'quit-dataset (unwind-protect (progn (restart-case (%dataset-init ,name) (retry-dataset-init () :report ,(format nil "Retry dataset('~a) init: (with any dataset changes)" (symbol-name name)) (%dataset-init ,name)) (skip-this-test () :report "FAIL and run the next test" (throw 'quit-dataset :data-set-failure))) ,@body) (%dataset-cleanup ,name)))) (defun %dataset-dispatch (arg) "For use with def-dataset and with-dataset, tries to DWIM." (etypecase arg (string (clsql-sys:execute-command arg)) ;treat it as a sql command. ((or function symbol) (funcall arg)) ;run functions (list (case (first arg) ((function lambda) (%dataset-dispatch (eval arg))) ;#' forms, lambdas (progn (mapc #'%dataset-dispatch (rest arg))) ; (progn "asdf" "ff") (ignore-errors (ignore-errors (mapc #'%dataset-dispatch (rest arg)))) (t (mapc #'%dataset-dispatch arg))) ;otherwise implicit progn ))) (defun %dataset-init (name) "Run initialization code and fill database for given dataset." ;;find items that looks like '(:setup ...), ;; dispatch the rest. (let ((*backend-warning-behavior* (typecase *default-database* (clsql-sys:generic-postgresql-database :ignore) (t *backend-warning-behavior*))) (setup (rest (find :setup name :key #'first))) (sqldata (rest (find :sqldata name :key #'first))) (objdata (rest (find :objdata name :key #'first)))) (when setup (handler-bind ((warning (lambda (c) (when (eql :ignore *backend-warning-behavior*) (muffle-warning c))))) (%dataset-dispatch setup))) (when sqldata ;;run raw sql insert statements (destructuring-bind (table-name columns &rest values-list) sqldata (dolist (v values-list) (clsql-sys:execute-command (format nil "INSERT INTO ~a (~a) VALUES (~a)" table-name columns v))))) (when objdata ;;presumed to be view-class objects, force them to insert. (dolist (o objdata) (setf (slot-value o 'clsql-sys::view-database) nil) (clsql-sys:update-records-from-instance o))))) (defun %dataset-cleanup (name) "Run cleanup code associated with the given dataset." (restart-case (handler-bind ((error #'generic-error)) (let ((cleanup (rest (find :cleanup name :key #'first)))) (when cleanup (%dataset-dispatch cleanup)))) (retry-dataset-cleanup () :report "Retry dataset cleanup (with any dataset changes)" (%dataset-cleanup name)) (skip-cleanup () nil))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Example Test Code ;;incomplete example taken from test-init ;; (def-dataset *employees* ;; (:setup "CREATE TABLE employee ;; ( ;; emplid integer NOT NULL, ;; groupid integer NOT NULL, ;; first_name character varying(30), ;; last_name character varying(30), ;; email character varying(100), ;; ecompanyid integer, ;; managerid integer, ;; height double, ;; married boolean, ;; birthday timestamp without time zone, ;; bd_utime bigint, ;; CONSTRAINT employeepk PRIMARY KEY (emplid, groupid), ;; CONSTRAINT employee_emplid_key UNIQUE (emplid) ;; ) ;; ") ;; ;;alternatively setup can still be done as ;; ;;(:setup #'(lambda () (create-view-from-class ...))) ;; (:sqldata "employees" "emplid,groupid,married,height,first_name,last_name" ;; "1,1,false,1.5,'Napolean', 'Bonaparte'" ;; (format nil "1,1,true,~a,'Vladimir','Lenin'" (1+ (random 1.00)))) ;; (:cleanup "DROP TABLE EMPLOYEES")) cl-sql-6.7.2/tests/benchmarks.lisp0000644000175000017500000000627612473715066016131 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: benchmarks.lisp ;;;; Purpose: Time performance tests for CLSQL ;;;; Authors: Kevin M. Rosenberg ;;;; Created: March 5, 2004 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (defun run-benchmarks-append-report-file (report-file) (run-function-append-report-file 'run-benchmarks report-file)) (clsql:def-view-class bench () ((a :initarg :a :type integer) (b :initarg :b :type (string 100)) (c :initarg :c :type float))) (defun run-benchmarks (&key (report-stream *standard-output*) (sexp-report-stream nil) (count 10000)) (let ((specs (read-specs)) (*report-stream* report-stream) (*sexp-report-stream* sexp-report-stream)) (unless specs (warn "Not running benchmarks because test configuration file is missing") (return-from run-benchmarks :skipped)) (load-necessary-systems specs) (dolist (db-type +all-db-types+) (dolist (spec (db-type-spec db-type specs)) (do-benchmarks-for-backend db-type spec count)))) (values)) (defun do-benchmarks-for-backend (db-type spec count) (test-setup-database db-type spec) (write-report-banner "Benchmarks" db-type *report-stream* (database-name-from-spec spec db-type)) (create-view-from-class 'bench) (benchmark-init) (benchmark-selects count) (drop-view-from-class 'bench)) (defun benchmark-init () (dotimes (i 10) (execute-command "INSERT INTO BENCH (A,B,C) VALUES (123,'A Medium size string',3.14159)"))) (defun benchmark-selects (n) (let ((*trace-output* *report-stream*)) (format *report-stream* "~&~%*** QUERY ***~%") (time (dotimes (i n) (query "SELECT * FROM BENCH"))) (format *report-stream* "~&~%*** QUERY WITH RESULT-TYPES NIL ***~%") (time (dotimes (i n) (query "SELECT * FROM BENCH" :result-types nil))) (format *report-stream* "~&~%*** QUERY WITH FIELD-NAMES NIL ***~%") (time (dotimes (i n) (query "SELECT * FROM BENCH" :field-names nil))) (with-dataset *ds-employees* (format *report-stream* "~&~%*** JOINED OBJECT QUERY RETRIEVAL IMMEDIATE ***~%") (time (dotimes (i (truncate n 10)) (mapcar #'(lambda (ea) (slot-value ea 'address)) (select 'employee-address :flatp t)))) (format *report-stream* "~&~%*** JOINED OBJECT QUERY RETRIEVAL DEFERRED ***~%") (let* ((slotdef (find 'address (clsql-sys::class-slots (find-class 'employee-address)) :key #'clsql-sys::slot-definition-name)) (dbi (when slotdef (clsql-sys::view-class-slot-db-info slotdef)))) (setf (gethash :retrieval dbi) :deferred) (time (dotimes (i (truncate n 10)) (mapcar #'(lambda (ea) (slot-value ea 'address)) (select 'employee-address :flatp t)))) (setf (gethash :retrieval dbi) :immediate))))) cl-sql-6.7.2/tests/test-init.lisp0000644000175000017500000004365412651763351015733 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ====================================================================== ;;;; File: test-init.lisp ;;;; Authors: Marcus Pearce , Kevin Rosenberg ;;;; Created: 30/03/2004 ;;;; ;;;; Initialisation utilities for running regression tests on CLSQL. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ====================================================================== (in-package #:clsql-tests) (defvar *report-stream* *standard-output* "Stream to send text report.") (defvar *sexp-report-stream* nil "Stream to send sexp report.") (defvar *rt-internal*) (defvar *rt-basic*) (defvar *rt-connection*) (defvar *rt-fddl*) (defvar *rt-fdml*) (defvar *rt-ooddl*) (defvar *rt-oodml*) (defvar *rt-syntax*) (defvar *rt-time*) (defvar *rt-pool*) ;; Below must be set as nil since test-i18n.lisp is not loaded on all platforms. (defvar *rt-i18n* nil) (defvar *test-database-type* nil) (defvar *test-database-underlying-type* nil) (defvar *test-database-user* nil) (defvar *test-false-database-user* "adsfjalsdkfjlakjsdfl" "For testing ownership, a user that isn't the owner.") (defvar *test-start-utime* nil) (defvar *test-connection-spec* nil) (defvar *test-connection-db-type* nil) (defvar *test-report-width* 80 "Width of test report in ems.") (defun find-test-connection-spec (db-type &key position) (nth (or position 0) (db-type-spec db-type (read-specs)))) (defun test-connect (&key (db-type *test-database-type* db-type-p) position pool spec) (unless spec (setf spec (or (and (null db-type-p) *test-connection-spec*) (find-test-connection-spec db-type :position position)))) (when *default-database* (disconnect :database *default-database*)) (setf *test-database-type* db-type *test-database-user* (cond ((member db-type '(:oracle :odbc :aodbc)) (second spec)) ((>= (length spec) 3) (third spec))) *test-connection-spec* spec *default-database* (clsql:connect spec :database-type db-type :make-default t :if-exists :old :pool pool) *test-database-underlying-type* (clsql-sys:database-underlying-type *default-database*)) *default-database*) (defun test-setup-database (db-type &key (spec (find-test-connection-spec db-type))) (when (clsql-sys:db-backend-has-create/destroy-db? db-type) (ignore-errors (destroy-database spec :database-type db-type)) (ignore-errors (create-database spec :database-type db-type))) ;; Connect to the database (test-connect :db-type db-type :spec spec) ;; Ensure database is empty (truncate-database :database *default-database*) ;; If Postgres, turn off notices to console (when (eql db-type :postgresql) (clsql:execute-command "SET client_min_messages = WARNING")) *default-database*) (defun default-suites () "The default list of tests to run." (append *rt-connection* *rt-basic* *rt-fddl* *rt-fdml* *rt-ooddl* *rt-oodml* *rt-syntax* *rt-time* *rt-i18n*)) (defun internal-suites () "The default internal suites that should run without any specific backend" (append *rt-internal* *rt-pool*)) (defvar *error-count* 0) (defvar *error-list* nil) (defun run-function-append-report-file (function report-file) (let* ((report-path (etypecase report-file (pathname report-file) (string (parse-namestring report-file)))) (sexp-report-path (make-pathname :defaults report-path :type "sexp"))) (with-open-file (rs report-path :direction :output :if-exists :append :if-does-not-exist :create) (with-open-file (srs sexp-report-path :direction :output :if-exists :append :if-does-not-exist :create) (funcall function :report-stream rs :sexp-report-stream srs))))) (defun run-tests-append-report-file (report-file) (run-function-append-report-file 'run-tests report-file)) (defun run-tests (&key (report-stream *standard-output*) (sexp-report-stream nil) (suites (append (internal-suites) (default-suites)))) ;; clear SQL-OUTPUT cache (setq clsql-sys::*output-hash* (make-hash-table :test #'equal)) (setf *test-database-underlying-type* nil) (let ((specs (read-specs)) (*report-stream* report-stream) (*sexp-report-stream* sexp-report-stream) (*error-count* 0) (*error-list* nil)) (unless specs (warn "Not running tests because test configuration file is missing") (return-from run-tests :skipped)) (load-necessary-systems specs) ;;run the internal suites (do-tests-for-internals :suites (intersection suites (internal-suites))) ;; run backend-specific tests (let ((suites (intersection suites (default-suites)))) (when suites (dolist (db-type +all-db-types+) (dolist (spec (db-type-spec db-type specs)) (format report-stream "~%~%Start Running Tests Against: ~A ~A~%~%" db-type (ignore-errors (subseq spec 0 2))) (do-tests-for-backend db-type spec :suites suites) (format report-stream "~%~%Finished Running Tests Against: ~A ~A~%~%" db-type (ignore-errors (subseq spec 0 2))))))) (zerop *error-count*))) (defun load-necessary-systems (specs) (dolist (db-type +all-db-types+) (when (db-type-spec db-type specs) (clsql-sys:initialize-database-type :database-type db-type)))) (defun write-report-banner (report-type db-type stream db-name) (format stream "~& ****************************************************************************** *** CLSQL ~A begun at ~A *** ~A *** ~A on ~A *** Database ~:@(~A~) *** Type: ~:@(~A~) backend~A. ****************************************************************************** " report-type (clsql:format-time nil (clsql:utime->time (get-universal-time))) (lisp-implementation-type) (lisp-implementation-version) (machine-type) db-name db-type (if (not (eq db-type *test-database-underlying-type*)) (format nil " with underlying type ~:@(~A~)" *test-database-underlying-type*) "") )) (defun do-tests-for-internals (&key (suites (internal-suites))) (write-report-banner "Test Suite" "CLSQL Internals" *report-stream* "N/A") (%do-tests suites nil)) (defun %do-tests (test-forms db-type) (regression-test:rem-all-tests) (dolist (test-form test-forms) (eval test-form)) (let* ((cl:*print-right-margin* *test-report-width*) (remaining (regression-test:do-tests *report-stream*))) (when (regression-test:pending-tests) (incf *error-count* (length remaining)))) (let ((sexp-error (list db-type *test-database-underlying-type* (get-universal-time) (length test-forms) (regression-test:pending-tests) (lisp-implementation-type) (lisp-implementation-version) (machine-type)))) (when *sexp-report-stream* (write sexp-error :stream *sexp-report-stream* :readably t)) (push sexp-error *error-list*)) ) (defun do-tests-for-backend (db-type spec &key (suites (default-suites)) ) (test-setup-database db-type :spec spec) (unwind-protect (multiple-value-bind (test-forms skip-tests) (compute-tests-for-backend db-type *test-database-underlying-type* :suites suites) (write-report-banner "Test Suite" db-type *report-stream* (database-name-from-spec spec db-type)) (%do-tests test-forms db-type) (format *report-stream* "~&~D of ~D Tests skipped:" (length skip-tests) (length test-forms)) (if skip-tests (let ((max-test-name (length (symbol-name (caar skip-tests))))) (dolist (skipped (cdr skip-tests)) (let ((len (length (symbol-name (car skipped))))) (when (> len max-test-name) (setq max-test-name len)))) (let ((fmt (format nil "~~& ~~~DA ~~A~~%" max-test-name))) (dolist (skipped skip-tests) ;; word-wrap the reason string field (let* ((test (car skipped)) (reason (cdr skipped)) ;; (rlen (length reason)) (rwidth (max 20 (- (or *test-report-width* 80) max-test-name 3))) (rwords (clsql-sys::delimited-string-to-list reason #\space t)) (rformat (format nil "~~{~~<~%~~1,~D:;~~A~~> ~~}" rwidth)) (rwrapped (format nil rformat rwords)) (rlines (clsql-sys::delimited-string-to-list rwrapped #\Newline t))) (dolist (rline rlines) (format *report-stream* fmt (if test (prog1 test (setq test nil)) "") rline)))))) (format *report-stream* " None~%"))) (disconnect))) (defun compute-tests-for-backend (db-type db-underlying-type &key (suites (default-suites))) (let ((test-forms '()) (skip-tests '())) (dolist (test-form (if (listp suites) suites (list suites))) (let ((test (second test-form))) (cond ((and (not (eql db-underlying-type :mysql)) (clsql-sys:in test :connection/query-command :basic/reallybigintegers/1 :connection/pool/procedure-mysql)) (push (cons test "known to work only in MySQL as yet.") skip-tests)) ((and (null (clsql-sys:db-type-has-views? db-underlying-type)) (clsql-sys:in test :fddl/view/1 :fddl/view/2 :fddl/view/3 :fddl/view/4)) (push (cons test "views not supported.") skip-tests)) ((and (null (clsql-sys:db-type-has-boolean-where? db-underlying-type)) (clsql-sys:in test :fdml/select/11 :oodml/select/5)) (push (cons test "boolean where not supported.") skip-tests)) ((and (null (clsql-sys:db-type-has-subqueries? db-underlying-type)) (clsql-sys:in test :fdml/select/5 :fdml/select/10 :fdml/select/32 :fdml/select/33)) (push (cons test "subqueries not supported.") skip-tests)) ((and (null (clsql-sys:db-type-transaction-capable? db-underlying-type *default-database*)) (clsql-sys:in test :fdml/transaction/1 :fdml/transaction/2 :fdml/transaction/3 :fdml/transaction/4)) (push (cons test "transactions not supported.") skip-tests)) ((and (null (clsql-sys:db-type-has-fancy-math? db-underlying-type)) (clsql-sys:in test :fdml/select/1)) (push (cons test "fancy math not supported.") skip-tests)) ((and (eql *test-database-type* :sqlite) (clsql-sys:in test :fddl/view/4 :fdml/select/10 :fdml/select/21 :fdml/select/32 :fdml/select/33)) (push (cons test "not supported by sqlite.") skip-tests)) ((and (eql *test-database-type* :sqlite3) (clsql-sys:in test :fddl/view/4 :fdml/select/10 :fdml/select/21 :fdml/select/32 :fdml/select/33)) (push (cons test "not supported by sqlite3.") skip-tests)) ((and (not (clsql-sys:db-type-has-bigint? db-type)) (clsql-sys:in test :basic/bigint/1)) (push (cons test "bigint not supported.") skip-tests)) ((and (eql *test-database-underlying-type* :mysql) (clsql-sys:in test :fdml/select/26)) (push (cons test "string table aliases not supported on all MySQL versions.") skip-tests)) ((and (eql *test-database-underlying-type* :mysql) (clsql-sys:in test :fdml/select/22 :fdml/query/5 :fdml/query/7 :fdml/query/8)) (push (cons test "not supported by mysql.") skip-tests)) ((and (null (clsql-sys:db-type-has-union? db-underlying-type)) (clsql-sys:in test :fdml/query/6 :fdml/select/31)) (push (cons test "union not supported") skip-tests)) ((and (eq *test-database-type* :oracle) (clsql-sys:in test :fdml/query/8 :fdml/select/21 :fddl/table/6)) (push (cons test "syntax not supported.") skip-tests)) ((and (eq *test-database-type* :odbc) (eq *test-database-underlying-type* :postgresql) (clsql-sys:in test :fddl/owner/1 :fddl/owner/table :fddl/owner/attributes :fddl/owner/attribute-types :fddl/owner/index :fddl/owner/sequence)) (push (cons test "table ownership not supported by postgresql odbc driver.") skip-tests)) ((and (not (member *test-database-underlying-type* '(:postgresql :oracle))) (clsql-sys:in test :fddl/owner/1 :fddl/owner/table :fddl/owner/attributes :fddl/owner/attribute-types :fddl/owner/index :fddl/owner/sequence)) (push (cons test "table ownership not supported.") skip-tests)) ((and (null (clsql-sys:db-type-has-intersect? db-underlying-type)) (clsql-sys:in test :fdml/query/7)) (push (cons test "intersect not supported.") skip-tests)) ((and (null (clsql-sys:db-type-has-except? db-underlying-type)) (clsql-sys:in test :fdml/query/8)) (push (cons test "except not supported.") skip-tests)) ((and (eq *test-database-underlying-type* :mssql) (clsql-sys:in test :fdml/select/9)) (push (cons test "mssql uses integer math for AVG.") skip-tests)) ((and (not (member *test-database-underlying-type* '(:postgresql :mysql :sqlite3 ))) (clsql-sys:in test :fdml/select/37 :fdml/select/38)) (push (cons test "LIMIT keyword not supported in SELECT.") skip-tests)) ((and (not (clsql-sys:db-type-has-auto-increment? db-underlying-type)) (clsql-sys:in test :oodml/select/12 :oodml/select/13 :oodml/select/14 :oodml/select/15 :oodml/select/16 :oodml/select/17 :oodml/select/18 :oodml/select/19 :oodml/select/20 :oodml/select/21 :oodml/select/22 :oodml/select/23 :oodml/update-records/4 :oodml/update-records/4-slots :oodml/update-records/5 :oodml/update-records/5-slots :oodml/update-records/6 :oodml/update-records/7 :oodml/update-records/8 :oodml/update-records/9 :oodml/update-records/9-slots :oodml/update-records/10 :oodml/update-records/11 :OODML/UPDATE-RECORDS/12 :oodml/update-instance/3 :oodml/update-instance/4 :oodml/update-instance/5 :oodml/update-instance/6 :oodml/update-instance/7 :oodml/db-auto-sync/3 :oodml/db-auto-sync/4)) (push (cons test ":auto-increment not supported.") skip-tests)) ((and (not (member *test-database-underlying-type* '(:postgresql :postgresql-socket))) (clsql-sys:in test :time/pg/fdml/usec :time/pg/oodml/no-usec :time/pg/oodml/usec)) (push (cons test "Postgres specific test.") skip-tests)) ((and (eql *test-database-type* :postgresql-socket3) (clsql-sys:in test :BASIC/SELECT/2 :basic/select/3)) (push (cons test "Postgres-socket3 always auto types") skip-tests)) ((and (eql *test-database-type* :postgresql-socket3) (clsql-sys:in test :fdml/select/18)) (push (cons test "Postgres-socket3 doesnt support attribute based type coersion") skip-tests)) ((and (eql *test-database-type* :postgresql-socket3) (clsql-sys:in test :basic/map/1 :basic/map/2 :basic/map/3 :basic/map/4 :basic/do/1 :basic/do/2 :fdml/do-query/1 :fdml/map-query/1 :fdml/map-query/2 :fdml/map-query/3 :fdml/map-query/4 :fdml/loop/1 :fdml/loop/2 :fdml/loop/3 )) (push (cons test "postgresql-socket3 doesnt support cursoring interface") skip-tests)) ((and (member *test-database-underlying-type* '(:mysql)) (clsql-sys:in test :time/cross-platform/msec :time/cross-platform/usec/no-tz :time/cross-platform/usec/tz)) (push (cons test "MySQL doesn't support fractional seconds on timestamp columns (http://forge.mysql.com/worklog/task.php?id=946).") skip-tests)) ((and (member *test-database-underlying-type* '(:mssql)) (clsql-sys:in test :time/cross-platform/usec/no-tz :time/cross-platform/usec/tz)) (push (cons test "MSSQL doesn't support micro-seconds on datetime columns.") skip-tests)) (t (push test-form test-forms))))) (values (nreverse test-forms) (nreverse skip-tests)))) (defun rapid-load (type &optional (position 0)) "Rapid load for interactive testing." (test-setup-database type :spec (find-test-connection-spec type :position position)) *default-database*) (defun rl () (rapid-load :postgresql)) (defun rlm () (rapid-load :mysql)) (defun rlo () (rapid-load :oracle)) cl-sql-6.7.2/tests/test-time.lisp0000644000175000017500000004474012064366222015715 0ustar kevinkevin;;; -*- Mode: Lisp -*- ;;; ;;; Copyright (c) 2000, 2001 onShore Development, Inc. ;;; ;;; Test time functions (time.lisp) (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (def-view-class datetest () ((id :column "id" :type integer :db-kind :key :db-constraints (:not-null :unique) :accessor id :initarg :id :initform nil :db-type "int4") (testtimetz :column "testtimetz" :type clsql-sys:wall-time :db-kind :base :db-constraints nil :accessor testtimetz :initarg :testtimetz :initform nil :db-type "timestamp with time zone") (testtime :column "testtime" :type clsql-sys:wall-time :db-kind :base :db-constraints nil :accessor testtime :initarg :testtime :initform nil :db-type "timestamp without time zone"))) (def-dataset *ds-datetest* (:setup (lambda () (clsql-sys:create-view-from-class 'datetest))) (:cleanup "DROP TABLE datetest")) (def-dataset *cross-platform-datetest* (:setup (lambda () (create-table [datetest] '(([testtime] wall-time))))) (:cleanup (lambda () (drop-table [datetest])))) (setq *rt-time* '( ;; we use parse timestring a lot through here verifying other things ;; start off just checking that. (deftest :time/iso-parse/0 (let* ((time1 (parse-timestring "2010-01-23"))) (decode-time time1)) 0 0 0 0 23 1 2010 6) (deftest :time/iso-parse/1 (let* ((time1 (parse-timestring "2010-01-23T14:56:32Z"))) (decode-time time1)) 0 32 56 14 23 1 2010 6) (deftest :time/iso-parse/2 (let* ((time1 (parse-timestring "2008-02-29 12:46:32"))) (decode-time time1)) 0 32 46 12 29 2 2008 5) (deftest :time/iso-parse/3 (let* ((time1 (parse-timestring "2010-01-23 14:56:32.44"))) (decode-time time1)) 440000 32 56 14 23 1 2010 6) (deftest :time/iso-parse/4 (let* ((time1 (parse-timestring "2010-01-23 14:56:32.0044"))) (decode-time time1)) 4400 32 56 14 23 1 2010 6) (deftest :time/iso-parse/5 (let* ((time1 (parse-timestring "2010-01-23 14:56:32.000003"))) (decode-time time1)) 3 32 56 14 23 1 2010 6) (deftest :time/print-parse/1 ;;make sure when we print and parse we get the same time. (let* ((time (clsql-sys:make-time :year 2010 :month 1 :day 4 :hour 14 :minute 15 :second 44)) (string-time (iso-timestring time)) (time2 (parse-timestring string-time))) (decode-time time2)) 0 44 15 14 4 1 2010 1) (deftest :time/print-parse/2 ;;make sure when we print and parse we get the same time. (let* ((time (clsql-sys:make-time :year 2010 :month 1 :day 4 :hour 14 :minute 15 :second 44 :usec 3)) (string-time (iso-timestring time)) (time2 (parse-timestring string-time))) (decode-time time2)) 3 44 15 14 4 1 2010 1) ;; relations of intervals (deftest :time/1 (let* ((time-1 (clsql:parse-timestring "2002-01-01 10:00:00")) (time-2 (clsql:parse-timestring "2002-01-01 11:00:00")) (time-3 (clsql:parse-timestring "2002-01-01 12:00:00")) (time-4 (clsql:parse-timestring "2002-01-01 13:00:00")) (interval-1 (clsql:make-interval :start time-1 :end time-2)) (interval-2 (clsql:make-interval :start time-2 :end time-3)) (interval-3 (clsql:make-interval :start time-3 :end time-4)) (interval-4 (clsql:make-interval :start time-1 :end time-3)) (interval-5 (clsql:make-interval :start time-2 :end time-4)) (interval-6 (clsql:make-interval :start time-1 :end time-4))) (flet ((my-assert (number relation i1 i2) (declare (ignore number)) (let ((found-relation (clsql:interval-relation i1 i2))) (equal relation found-relation)))) (and (my-assert 1 :contains interval-1 interval-1) (my-assert 2 :precedes interval-1 interval-2) (my-assert 3 :precedes interval-1 interval-3) (my-assert 4 :contained interval-1 interval-4) (my-assert 5 :precedes interval-1 interval-5) (my-assert 6 :contained interval-1 interval-6) (my-assert 7 :follows interval-2 interval-1) (my-assert 8 :contains interval-2 interval-2) (my-assert 9 :precedes interval-2 interval-3) (my-assert 10 :contained interval-2 interval-4) (my-assert 11 :contained interval-2 interval-5) (my-assert 12 :contained interval-2 interval-6) (my-assert 13 :follows interval-3 interval-1) (my-assert 14 :follows interval-3 interval-2) (my-assert 15 :contains interval-3 interval-3) (my-assert 16 :follows interval-3 interval-4) (my-assert 17 :contained interval-3 interval-5) (my-assert 18 :contained interval-3 interval-6) (my-assert 19 :contains interval-4 interval-1) (my-assert 20 :contains interval-4 interval-2) (my-assert 21 :precedes interval-4 interval-3) (my-assert 22 :contains interval-4 interval-4) (my-assert 23 :overlaps interval-4 interval-5) (my-assert 24 :contained interval-4 interval-6) (my-assert 25 :follows interval-5 interval-1) (my-assert 26 :contains interval-5 interval-2) (my-assert 27 :contains interval-5 interval-3) (my-assert 28 :overlaps interval-5 interval-4) (my-assert 29 :contains interval-5 interval-5) (my-assert 30 :contained interval-5 interval-6) (my-assert 31 :contains interval-6 interval-1) (my-assert 32 :contains interval-6 interval-2) (my-assert 33 :contains interval-6 interval-3) (my-assert 34 :contains interval-6 interval-4) (my-assert 35 :contains interval-6 interval-5) (my-assert 36 :contains interval-6 interval-6)))) t) ;; adjacent intervals in list (deftest :time/2 (let* ((interval-list nil) (time-1 (clsql:parse-timestring "2002-01-01 10:00:00")) (time-3 (clsql:parse-timestring "2002-01-01 12:00:00")) (time-4 (clsql:parse-timestring "2002-01-01 13:00:00"))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-1 :end time-3 :type :open))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-3 :end time-4 :type :open))) (clsql:interval-relation (car interval-list) (cadr interval-list))) :precedes) ;; nested intervals in list (deftest :time/3 (let* ((interval-list nil) (time-1 (clsql:parse-timestring "2002-01-01 10:00:00")) (time-2 (clsql:parse-timestring "2002-01-01 11:00:00")) (time-3 (clsql:parse-timestring "2002-01-01 12:00:00")) (time-4 (clsql:parse-timestring "2002-01-01 13:00:00"))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-1 :end time-4 :type :open))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-2 :end time-3 :type :closed))) (let* ((interval (car interval-list)) (interval-contained (when interval (car (clsql:interval-contained interval))))) (when (and interval interval-contained) (and (clsql:time= (clsql:interval-start interval) time-1) (clsql:time= (clsql:interval-end interval) time-4) (eq (clsql:interval-type interval) :open) (clsql:time= (clsql:interval-start interval-contained) time-2) (clsql:time= (clsql:interval-end interval-contained) time-3) (eq (clsql:interval-type interval-contained) :closed))))) t) ;; interval-edit - nonoverlapping (deftest :time/4 (let* ((interval-list nil) (time-1 (clsql:parse-timestring "2002-01-01 10:00:00")) (time-2 (clsql:parse-timestring "2002-01-01 11:00:00")) (time-3 (clsql:parse-timestring "2002-01-01 12:00:00")) (time-4 (clsql:parse-timestring "2002-01-01 13:00:00"))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-1 :end time-2 :type :open))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-3 :end time-4 :type :closed))) (setf interval-list (clsql:interval-edit interval-list time-1 time-1 time-3)) ;; should be time-3 not time-2 (clsql:time= (clsql:interval-end (car interval-list)) time-3)) t) ;; interval-edit - overlapping (deftest :time/5 (let* ((interval-list nil) (time-1 (clsql:parse-timestring "2002-01-01 10:00:00")) (time-2 (clsql:parse-timestring "2002-01-01 11:00:00")) (time-3 (clsql:parse-timestring "2002-01-01 12:00:00")) (time-4 (clsql:parse-timestring "2002-01-01 13:00:00"))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-1 :end time-2 :type :open))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-2 :end time-4 :type :closed))) (let ((pass t)) (handler-case (progn (setf interval-list (clsql:interval-edit interval-list time-1 time-1 time-3)) (setf pass nil)) (error nil)) pass)) t) ;; interval-edit - nested intervals in list (deftest :time/6 (let* ((interval-list nil) (time-1 (clsql:parse-timestring "2002-01-01 10:00:00")) (time-2 (clsql:parse-timestring "2002-01-01 11:00:00")) (time-3 (clsql:parse-timestring "2002-01-01 12:00:00")) (time-4 (clsql:parse-timestring "2002-01-01 13:00:00")) (time-5 (clsql:parse-timestring "2002-01-01 14:00:00")) (time-6 (clsql:parse-timestring "2002-01-01 15:00:00"))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-1 :end time-6 :type :open))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-2 :end time-3 :type :closed))) (setf interval-list (clsql:interval-push interval-list (clsql:make-interval :start time-4 :end time-5 :type :closed))) (setf interval-list (clsql:interval-edit interval-list time-1 time-1 time-4)) ;; should be time-4 not time-6 (clsql:time= (clsql:interval-end (car interval-list)) time-4)) t) ;; Test the boundaries of Local Time with granularity of 1 year (deftest :time/7 (let ((sec-in-year (* 60 60 24 365)) (year (clsql:time-element (clsql:make-time) :year))) (dotimes (n 50 n) (let ((date (clsql:make-time :second (* n sec-in-year)))) (unless (= (+ year n) (clsql:time-element date :year)) (return n))))) 50) ;; Test db-timestring (deftest :time/9 (flet ((grab-year (dbstring) (parse-integer (subseq dbstring 1 5)))) (let ((second-in-year (* 60 60 24 365))) (dotimes (n 2000 n) (let* ((second (* -1 n second-in-year)) (date (clsql:make-time :year 2525 :second second))) (unless (= (grab-year (clsql:db-timestring date)) (clsql:time-element date :year)) (return n)))))) 2000) ;; Conversion between MJD and Gregorian (deftest :time/10 (dotimes (base 10000 base) (unless (= (apply #'clsql:gregorian-to-mjd (clsql:mjd-to-gregorian base)) base) (return base))) 10000) ;; Clsql:Roll by minutes: +90 (deftest :time/11 (let ((now (clsql:get-time))) (clsql:time= (clsql:time+ now (clsql:make-duration :minute 90)) (clsql:roll now :minute 90))) t) ;;Clsql:Roll by minutes: +900 (deftest :time/12 (let ((now (clsql:get-time))) (clsql:time= (clsql:time+ now (clsql:make-duration :minute 900)) (clsql:roll now :minute 900))) t) ;; Clsql:Roll by minutes: +900 (deftest :time/13 (let* ((now (clsql:get-time)) (add-time (clsql:time+ now (clsql:make-duration :minute 9000))) (roll-time (clsql:roll now :minute 9000))) (clsql:time= add-time roll-time)) t) ;;; The cross platform dataset uses the 'timestamp' column type which is ;;; in sql-92, for all that means. (deftest :time/cross-platform/no-usec/no-tz (with-dataset *cross-platform-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtime]) :values (list time)) (let ((testtime (first (clsql:select [testtime] :from [datetest] :flatp t :where [= [testtime] time] )))) (format-time nil (parse-timestring testtime) :format :iso) ))) #.(format-time nil (parse-timestring "2008-09-09T14:37:29") :format :iso)) (deftest :time/cross-platform/no-usec/tz (with-dataset *cross-platform-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29-04:00"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtime]) :values (list time)) (let ((testtime (first (clsql:select [testtime] :from [datetest] :flatp t :where [= [testtime] time] )))) (format-time nil (parse-timestring testtime) :format :iso) ))) #.(format-time nil (parse-timestring "2008-09-09T14:37:29-04:00") :format :iso)) ;;;This test gets at the databases that only support miliseconds, ;;; not microseconds. (deftest :time/cross-platform/msec (with-dataset *cross-platform-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29.423"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtime]) :values (list time)) (let ((testtime (first (clsql:select [testtime] :from [datetest] :flatp t :where [= [testtime] time] )))) (format-time nil (parse-timestring testtime) :format :iso) ))) #.(format-time nil (parse-timestring "2008-09-09T14:37:29.423") :format :iso)) (deftest :time/cross-platform/usec/no-tz (with-dataset *cross-platform-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29.000213"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtime]) :values (list time)) (let ((testtime (first (clsql:select [testtime] :from [datetest] :flatp t :where [= [testtime] time] )))) (format-time nil (parse-timestring testtime) :format :iso) ))) #.(format-time nil (parse-timestring "2008-09-09T14:37:29.000213") :format :iso)) (deftest :time/cross-platform/usec/tz (with-dataset *cross-platform-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29.000213-04:00"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtime]) :values (list time)) (let ((testtime (first (clsql:select [testtime] :from [datetest] :limit 1 :flatp t :where [= [testtime] time] )))) (format-time nil (parse-timestring testtime) :format :iso) ))) #.(format-time nil (parse-timestring "2008-09-09T14:37:29.000213-04:00") :format :iso)) ;;; All odbc databases use local times exclusively (they do not send timezone info) ;;; Postgresql can use timezones, except when being used over odbc. This test when ;;; run through both postgres socket and postgres odbc should test a fairly ;;; broad swath of available problem space ;;; ;;; Things the following tests try to prove correct ;;; * Reading and writing usec and usec-less times ;;; * reading and writing timezones (Z=utc) when appropriate (eg: postgresql-socket) ;;; * reading and writing localtimes when appropriate (eg: ODBC) ;;; * reading and writing through both the oodml and fdml layers (deftest :time/pg/fdml/usec (with-dataset *ds-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29.000213-04:00"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtimetz] [testtime] [id]) :values (list time time 1)) (destructuring-bind (testtimetz testtime) (first (clsql:select [testtimetz] [testtime] :from [datetest] :limit 1 :flatp t :where [= [testtime] time] )) (values (iso-timestring (parse-timestring testtime)) (iso-timestring (parse-timestring testtimetz)))))) #.(iso-timestring (parse-timestring "2008-09-09T14:37:29.000213-04:00")) #.(iso-timestring (parse-timestring "2008-09-09T14:37:29.000213-04:00"))) (deftest :time/pg/oodml/no-usec (with-dataset *ds-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29-04:00"))) (clsql-sys:update-records-from-instance (make-instance 'datetest :testtimetz time :testtime time :id 1)) (let ((o (first (clsql:select 'datetest :limit 1 :flatp t :where [= [testtime] time] )))) (assert o (o) "o shouldnt be null here (we should have just inserted)") (update-records-from-instance o) (update-instance-from-records o) (values (iso-timestring (testtime o)) (iso-timestring (testtimetz o)))))) #.(iso-timestring (parse-timestring "2008-09-09T14:37:29-04:00")) #.(iso-timestring (parse-timestring "2008-09-09T14:37:29-04:00"))) (deftest :time/pg/oodml/usec (with-dataset *ds-datetest* (let ((time (parse-timestring "2008-09-09T14:37:29.000278-04:00"))) (clsql-sys:update-records-from-instance (make-instance 'datetest :testtimetz time :testtime time :id 1)) (let ((o (first (clsql:select 'datetest :limit 1 :flatp t :where [= [testtime] time] )))) (assert o (o) "o shouldnt be null here (we should have just inserted)") (update-records-from-instance o) (update-instance-from-records o) (values (iso-timestring (testtime o)) (iso-timestring (testtimetz o))) ))) #.(iso-timestring (parse-timestring "2008-09-09T14:37:29.000278-04:00")) #.(iso-timestring (parse-timestring "2008-09-09T14:37:29.000278-04:00"))) (deftest :time/historic-datetimes (with-dataset *cross-platform-datetest* (let ((time (parse-timestring "1800-09-09T14:37:29"))) (clsql-sys:insert-records :into [datetest] :attributes '([testtime]) :values (list time)) (let ((testtime (first (clsql:select [testtime] :from [datetest] :flatp t :where [= [testtime] time] )))) (format-time nil (parse-timestring testtime) :format :iso) ))) #.(format-time nil (parse-timestring "1800-09-09T14:37:29") :format :iso)) )) cl-sql-6.7.2/tests/test-fddl.lisp0000644000175000017500000003242112303270414015652 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-fddl.lisp ;;;; Purpose: Tests for the CLSQL Functional Data Definition Language ;;;; Authors: Marcus Pearce and Kevin M. Rosenberg ;;;; Created: March 2004 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (def-dataset *ds-fddl* (:setup (lambda () (create-table [alpha] '(([a] integer) ([c] (varchar 30)) ([d] date) ([f] float))) (create-table [bravo] '(([foo] integer) ([bar] integer))))) (:sqldata "ALPHA" "A,C,D,F" "1,'asdf','2010-01-01',3.14" "2,'blarg','2012-12-21',0.1" "3,'matey','1992-02-29',0.0") (:cleanup "DROP TABLE ALPHA" "DROP TABLE BRAVO")) (def-dataset *ds-fddl-parsing-oddities* (:setup "CREATE TABLE ATEST ( A varchar (32), B varchar(32))") (:cleanup "DROP TABLE ATEST")) (setq *rt-fddl* '( ;; list current tables (deftest :fddl/table/1 (with-dataset *ds-fddl* (let ((tables (sort (mapcar #'string-downcase (clsql:list-tables)) #'string<))) ;; sqlite has a table for autoincrement sequences that we dont care about if ;; it exists (remove "sqlite_sequence" tables :test #'string-equal))) ("alpha" "bravo")) ;; create a table, test for its existence, drop it and test again (deftest :fddl/table/2 (progn (clsql:create-table [foo] '(([id] integer) ([height] float) ([name] (string 24)) ([comments] longchar))) (values (clsql:table-exists-p [foo]) (progn (clsql:drop-table [foo] :if-does-not-exist :ignore) (clsql:table-exists-p [foo])))) t nil) ;; create a table, list its attributes and drop it (deftest :fddl/table/3 (apply #'values (progn (clsql:create-table [foo] '(([id] integer) ([height] float) ([name] (char 255)) ([comments] longchar))) (prog1 (sort (mapcar #'string-downcase (clsql:list-attributes [foo])) #'string<) (clsql:drop-table [foo] :if-does-not-exist :ignore)))) "comments" "height" "id" "name") (deftest :fddl/table/4 (values (clsql:table-exists-p "MyMixedCase") (progn (clsql:create-table "MyMixedCase" '(([a] integer))) (clsql:table-exists-p "MyMixedCase")) (progn (clsql:drop-table "MyMixedCase") (clsql:table-exists-p "MyMixedCase"))) nil t nil) (deftest :fddl/table/5 (prog1 (progn (clsql:create-table "MyMixedCase" '(([a] integer))) (clsql:execute-command "insert into \"MyMixedCase\" values (5)") (clsql:insert-records :into "MyMixedCase" :values '(6)) (clsql:select [a] :from "MyMixedCase" :order-by '((a :asc)))) (clsql:drop-table "MyMixedCase")) ((5) (6))) (deftest :fddl/table/6 (values (clsql:table-exists-p [foo]) (progn (let ((*backend-warning-behavior* (if (member *test-database-type* '(:postgresql :postgresql-socket :postgresql-socket3)) :ignore :warn))) (case *test-database-underlying-type* (:mssql (clsql:create-table [foo] '(([bar] integer :not-null :primary-key) ([baz] string :not-null :unique)))) (t (clsql:create-table [foo] '(([bar] integer :not-null :unique :primary-key) ([baz] string :not-null :unique)))))) (clsql:table-exists-p [foo])) (progn (clsql:drop-table [foo]) (clsql:table-exists-p [foo]))) nil t nil) (deftest :fddl/table/7 (values (clsql:table-exists-p [foo]) (progn (let ((*backend-warning-behavior* (if (member *test-database-type* '(:postgresql :postgresql-socket :postgresql-socket3)) :ignore :warn))) (clsql:create-table [foo] '(([bar] integer :not-null) ([baz] string :not-null)) :constraints '("UNIQUE (bar,baz)" "PRIMARY KEY (bar)"))) (clsql:table-exists-p [foo])) (progn (clsql:drop-table [foo]) (clsql:table-exists-p [foo]))) nil t nil) (deftest :fddl/attributes/1 (apply #'values (with-dataset *ds-fddl* (sort (mapcar #'string-downcase (clsql:list-attributes [alpha] )) #'string<))) "a" "c" "d" "f") (deftest :fddl/attributes/2 (with-dataset *ds-fddl* (apply #'values (sort (mapcar #'(lambda (a) (string-downcase (car a))) (clsql:list-attribute-types [alpha])) #'string<))) "a" "c" "d" "f") ;; Attribute types are vendor specific so need to test a range (deftest :fddl/attributes/3 (with-dataset *ds-fddl* (and (member (clsql:attribute-type [a] [alpha]) '(:int :integer :int4 :number)) t)) t) (deftest :fddl/attributes/4 (with-dataset *ds-fddl* (multiple-value-bind (type length scale nullable) (clsql:attribute-type [c] [alpha]) (values (clsql-sys:in type :varchar :varchar2 :nvarchar) length scale nullable))) t 30 nil 1) (deftest :fddl/attributes/5 (with-dataset *ds-fddl* (and (member (clsql:attribute-type [d] [alpha]) '(:datetime :timestamp :date :smalldatetime)) t)) t) (deftest :fddl/attributes/6 (with-dataset *ds-fddl* (and (member (clsql:attribute-type [f] [alpha]) '(:float :float8 :number)) t)) t) (deftest :fddl/attributes/7 (with-dataset *ds-bigint* (and (member (clsql:attribute-type [t_bigint] [TYPE_BIGINT]) '(:bigint :int8)) t)) t) (deftest :fddl/attributes/8 ;;this is mostly from sqlite3 sending back (with-dataset *ds-fddl-parsing-oddities* (values (clsql-sys:in (clsql:attribute-type [a] [atest]) :varchar :varchar2) (clsql-sys:in (clsql:attribute-type [b] [atest]) :varchar :varchar2))) t t) ;; create a view, test for existence, drop it and test again (deftest :fddl/view/1 (with-dataset *ds-fddl* (progn (clsql:create-view [v1] :as [select [a] [c] [d] :from [alpha] :where [= [a] 1]]) (values (clsql:view-exists-p [v1]) (progn (clsql:drop-view [v1] :if-does-not-exist :ignore) (clsql:view-exists-p [v1]))))) t nil) ;; create a view, list its attributes and drop it (deftest :fddl/view/2 (with-dataset *ds-fddl* (progn (clsql:create-view [v1] :as [select [a] [c] [d] :from [alpha] :where [= [a] 1]]) (unwind-protect (sort (mapcar #'string-downcase (clsql:list-attributes [v1])) #'string<) (clsql:drop-view [v1] :if-does-not-exist :ignore)))) ("a" "c" "d")) ;; create a view, select stuff from it and drop it (deftest :fddl/view/3 (with-dataset *ds-fddl* (progn (clsql:create-view [v1] :as [select [a] [c] [d] :from [alpha] :where [= [a] 1]]) (unwind-protect (let ((result (list ;; Shouldn't exist (clsql:select [a] [c] :from [v1] :where [= [a] -1]) ;; Should exist (car (clsql:select [a] [c] :from [v1] :where [= [a] 1]))))) (apply #'values result)) (clsql:drop-view [v1] :if-does-not-exist :ignore)))) nil (1 "asdf")) (deftest :fddl/view/4 (with-dataset *ds-fddl* (progn (clsql:create-view [v1] :column-list '([x] [y] [z]) :as [select [a] [c] [d] :from [alpha] :where [= [a] 1]]) (unwind-protect (let ((result (list (sort (mapcar #'string-downcase (clsql:list-attributes [v1])) #'string<) ;; Shouldn't exist (clsql:select [x] [y] :from [v1] :where [= [x] -1]) ;; Should exist (car (clsql:select [x] [y] :from [v1] :where [= [x] 1]))))) (apply #'values result)) (clsql:drop-view [v1] :if-does-not-exist :ignore)))) ("x" "y" "z") nil (1 "asdf")) ;; create an index, test for existence, drop it and test again (deftest :fddl/index/1 (with-dataset *ds-fddl* (progn (clsql:create-index [bar] :on [alpha] :attributes '([a] [c]) :unique t) (values (clsql:index-exists-p [bar] ) (progn (clsql:drop-index [bar] :on [alpha] :if-does-not-exist :ignore) (clsql:index-exists-p [bar]))))) t nil) ;; create indexes with names as strings, symbols and in square brackets (deftest :fddl/index/2 (with-dataset *ds-fddl* (let ((names '("foo" foo [foo])) (result '())) (dolist (name names) (clsql:create-index name :on [alpha] :attributes '([a])) (push (clsql:index-exists-p name ) result) (clsql:drop-index name :on [alpha] :if-does-not-exist :ignore)) (apply #'values result))) t t t) ;; test list-indexes with keyword :ON (deftest :fddl/index/3 (progn (clsql:create-table [i3test] '(([a] (string 10)) ([b] integer))) (clsql:create-index [foo] :on [i3test] :attributes '([b]) :unique nil) (clsql:create-index [bar] :on [i3test] :attributes '([a]) :unique t) (values (clsql:table-exists-p [i3test]) (clsql:index-exists-p [foo]) (clsql:index-exists-p [bar]) (sort (mapcar #'string-downcase (clsql:list-indexes :on [i3test])) #'string-lessp) (progn (clsql:drop-index [bar] :on [i3test]) (clsql:drop-index [foo] :on [i3test]) (clsql:drop-table [i3test]) t))) t t t ("bar" "foo") t) ;; create an sequence, test for existence, drop it and test again (deftest :fddl/sequence/1 (progn (clsql:create-sequence [foo]) (values (clsql:sequence-exists-p [foo]) (progn (clsql:drop-sequence [foo] :if-does-not-exist :ignore) (clsql:sequence-exists-p [foo])))) t nil) ;; create and increment a sequence (deftest :fddl/sequence/2 (let ((val1 nil)) (clsql:create-sequence [foo]) (setf val1 (clsql:sequence-next [foo])) (prog1 (< val1 (clsql:sequence-next [foo])) (clsql:drop-sequence [foo] :if-does-not-exist :ignore))) t) ;; explicitly set the value of a sequence (deftest :fddl/sequence/3 (progn (clsql:create-sequence [foo]) (clsql:set-sequence-position [foo] 5) (prog1 (clsql:sequence-next [foo]) (clsql:drop-sequence [foo] :if-does-not-exist :ignore))) 6) (deftest :fddl/owner/1 (with-dataset *ds-fddl* (and ;; user tables are an improper subset of all tables (= (length (intersection (clsql:list-tables :owner nil) (clsql:list-tables :owner :all) :test #'string=)) (length (clsql:list-tables :owner nil))) ;; user tables are a proper subset of all tables (> (length (clsql:list-tables :owner :all)) (length (clsql:list-tables :owner nil))))) t) (deftest :fddl/owner/table (with-dataset *ds-fddl* (values (clsql-sys:table-exists-p [alpha]) (clsql-sys:table-exists-p [alpha] :owner *test-database-user*) (clsql-sys:table-exists-p [alpha] :owner *test-false-database-user*))) t t nil) (deftest :fddl/owner/attributes (with-dataset *ds-fddl* (values (length (clsql-sys:list-attributes [alpha])) (length (clsql-sys:list-attributes [alpha] :owner *test-database-user*)) (length (clsql-sys:list-attributes [alpha] :owner *test-false-database-user*)))) 4 4 0) (deftest :fddl/owner/attribute-types (with-dataset *ds-fddl* (values (length (clsql:list-attribute-types [alpha])) (length (clsql:list-attribute-types [alpha] :owner *test-database-user*)) (length (clsql:list-attribute-types [alpha] :owner *test-false-database-user*)))) 4 4 0) (deftest :fddl/owner/index (with-dataset *ds-fddl* (progn (clsql:create-index [bar] :on [alpha] :attributes '([a] [c])) (values (clsql:index-exists-p [bar] ) (clsql:index-exists-p [bar] :owner *test-database-user*) (clsql:index-exists-p [bar] :owner *test-false-database-user*) (length (clsql-sys:list-indexes :on [alpha])) (length (clsql-sys:list-indexes :on [alpha] :owner *test-database-user*)) (length (clsql-sys:list-indexes :on [alpha] :owner *test-false-database-user*)) (progn (clsql:drop-index [bar] :on [alpha] :if-does-not-exist :ignore) (clsql:index-exists-p [bar] :owner *test-database-user*)) (clsql:index-exists-p [bar] )))) t t nil 1 1 0 nil nil) (deftest :fddl/owner/sequence (progn (clsql:create-sequence [foo]) (values (clsql:sequence-exists-p [foo]) (clsql:sequence-exists-p [foo] :owner *test-database-user*) (clsql:sequence-exists-p [foo] :owner *test-false-database-user*) (progn (clsql:drop-sequence [foo] :if-does-not-exist :ignore) (clsql:sequence-exists-p [foo] )))) t t nil nil) (deftest :fddl/cache-table-queries/1 (with-dataset *ds-fddl* (list (gethash "ALPHA" (clsql-sys::attribute-cache clsql:*default-database*)) (progn (clsql:cache-table-queries "ALPHA" :action t) (gethash "ALPHA" (clsql-sys::attribute-cache clsql:*default-database*))) (progn (clsql:list-attribute-types "ALPHA") (not (null (cadr (gethash "ALPHA" (clsql-sys::attribute-cache clsql:*default-database*)))))) (progn (clsql:cache-table-queries "ALPHA" :action :flush) (gethash "ALPHA" (clsql-sys::attribute-cache clsql:*default-database*))))) (nil (t nil) t (t nil))) )) cl-sql-6.7.2/tests/test-syntax.lisp0000644000175000017500000002761211746263021016303 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql.asd ;;;; Purpose: Tests for the CLSQL Symbolic SQL syntax. ;;;; Authors: Marcus Pearce and Kevin M. Rosenberg ;;;; Created: March 2004 ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (setq *rt-syntax* '( (deftest :syntax/generic/1 (clsql:sql "foo") "'foo'") (deftest :syntax/generic/2 (clsql:sql 23) "23") (deftest :syntax/generic/3 (clsql:sql 'bar) "BAR") (deftest :syntax/generic/4 (clsql:sql '("ten" 10 ten)) "('ten',10,TEN)") (deftest :syntax/generic/5 (clsql:sql ["SELECT FOO,BAR FROM BAZ"]) "SELECT FOO,BAR FROM BAZ") (deftest :syntax/generic/6 (clsql:sql "What's up Doc?") "'What''s up Doc?'") (deftest :syntax/ident/1 (clsql:sql [foo]) "FOO") (deftest :syntax/ident/2 (clsql:sql [foo bar]) "FOO.BAR") (deftest :syntax/ident/3 (clsql:sql [foo :integer]) "FOO") (deftest :syntax/ident/4 (clsql:sql [foo bar :integer]) "FOO.BAR") (deftest :syntax/ident/5 (clsql:sql [foo "bar"]) "FOO \"bar\"") (deftest :syntax/ident/6 (clsql:sql ["foo" bar]) "\"foo\".BAR") (deftest :syntax/ident/7 (clsql:sql ["foo" bar :integer]) "\"foo\".BAR") (deftest :syntax/attribute/1 (clsql:sql (clsql:sql-expression :table 'foo :attribute 'bar)) "FOO.BAR") (deftest :syntax/attribute/2 (clsql:sql (clsql:sql-expression :table 'foo :attribute "bar")) "FOO.\"bar\"") (deftest :syntax/attribute/3 (clsql:sql (clsql:sql-expression :table "foo" :attribute 'bar)) "\"foo\".BAR") (deftest :syntax/attribute/4 (clsql:sql (clsql:sql-expression :table "foo" :attribute "bar")) "\"foo\".\"bar\"") (deftest :syntax/subquery/1 (clsql:sql [any '(3 4)]) "ANY((3,4))") (deftest :syntax/subquery/2 (clsql:sql [in [foo] '(foo bar baz)]) "(FOO IN (FOO,BAR,BAZ))") (deftest :syntax/subquery/3 (clsql:sql [all '(foo bar baz)]) "ALL((FOO,BAR,BAZ))") (deftest :syntax/subquery/4 (clsql:sql [exists '(foo bar baz)]) "EXISTS((FOO,BAR,BAZ))") (deftest :syntax/subquery/5 (clsql:sql [some '(foo bar baz)]) "SOME((FOO,BAR,BAZ))") (deftest :syntax/aggregate/1 (clsql:sql [max [+ [foo] [* 1000 [bar]]]]) "MAX((FOO + (1000 * BAR)))") (deftest :syntax/aggregate/2 (clsql:sql [avg [+ [foo] [* 1000 [bar]]]]) "AVG((FOO + (1000 * BAR)))") (deftest :syntax/aggregate/3 (clsql:sql [min [+ [foo] [* 1000 [bar]]]]) "MIN((FOO + (1000 * BAR)))") (deftest :syntax/aggregate/4 (clsql:sql [sum [foo] [bar]]) "SUM(FOO,BAR)") (deftest :syntax/aggregate/5 (clsql:sql [count [foo]]) "COUNT(FOO)") (deftest :syntax/logical/1 (values (clsql:sql [and [foo] [bar]]) (clsql:sql [or [foo] [bar]])) "(FOO AND BAR)" "(FOO OR BAR)") (deftest :syntax/logical/2 (clsql:sql [not [foo]]) "(NOT (FOO))") ;;; Test how we apply logical operators when we have different numbers of children ;;; This is useful if we wish to (apply #'sql-and some-list) without having to do ;;; alot of length checking (deftest :syntax/logical/3 (values (clsql:sql [and ]) (clsql:sql [and [foo]]) (clsql:sql [and [not [foo]]]) (clsql:sql [and [foo] [bar] [baz]])) "" "FOO" "(NOT (FOO))" "(FOO AND BAR AND BAZ)") (deftest :syntax/logical/4 (clsql:sql [and [= [foo] [bar]]]) "(FOO = BAR)") (deftest :syntax/logical/5 (clsql:sql [and [= [foo] [bar]] [= [bar] [bast]] [= [block] [blech]]]) "((FOO = BAR) AND (BAR = BAST) AND (BLOCK = BLECH))") (deftest :syntax/logical/6 (clsql:sql (apply #'sql-and (list [= [foo] [bar]] [and ] [and [= [bar] [bast]]]))) "((FOO = BAR) AND (BAR = BAST))") (deftest :syntax/null/1 (clsql:sql [null [foo]]) "(FOO IS NULL)") (deftest :syntax/null/2 (clsql:sql [not [null [foo]]]) "(NOT ((FOO IS NULL)))") (deftest :syntax/null/3 (clsql:sql [null]) "NULL") (deftest :syntax/null/4 (clsql:sql [not [null]]) "(NOT (NULL))") (deftest :syntax/null/5 (clsql:sql [is [foo.bar] [null]]) "(FOO.BAR IS NULL)") (deftest :syntax/null/6 (clsql:sql [is [foo.bar] [not-null]]) "(FOO.BAR IS NOT NULL)") (deftest :syntax/null/7 (clsql:sql [not-null [foo.bar]]) "(FOO.BAR IS NOT NULL)") (deftest :syntax/relational/1 (clsql:sql [> [baz] [beep]]) "(BAZ > BEEP)") (deftest :syntax/relational/2 (let ((x 10)) (clsql:sql [> [foo] x])) "(FOO > 10)") (deftest :syntax/relational/3 (clsql:sql [>= [baz] [beep]]) "(BAZ >= BEEP)") (deftest :syntax/relational/4 (clsql:sql [< [baz] [beep]]) "(BAZ < BEEP)") (deftest :syntax/relational/5 (clsql:sql [= [baz] [beep]]) "(BAZ = BEEP)") (deftest :syntax/relational/6 (clsql:sql [<> [baz] [beep]]) "(BAZ <> BEEP)") (deftest :syntax/between/1 (clsql:sql [between [- [foo] 1] [* [bar] 5] [/ [baz] 9]]) "(FOO - 1) BETWEEN (BAR * 5) AND (BAZ / 9)") (deftest :syntax/between/2 (clsql:sql [not [between [- [foo] 1] [* [bar] 5] [/ [baz] 9]]]) "(NOT ((FOO - 1) BETWEEN (BAR * 5) AND (BAZ / 9)))") (deftest :syntax/arithmetic/1 (clsql:sql [+ [foo bar] [baz]]) "(FOO.BAR + BAZ)") (deftest :syntax/arithmetic/2 (clsql:sql [- [foo bar] [baz]]) "(FOO.BAR - BAZ)") (deftest :syntax/arithmetic/3 (clsql:sql [/ [foo bar] [baz]]) "(FOO.BAR / BAZ)") (deftest :syntax/arithmetic/4 (clsql:sql [* [foo bar] [baz]]) "(FOO.BAR * BAZ)") (deftest :syntax/arithmetic/5 (clsql:sql [- [foo bar]]) "(- (FOO.BAR))") (deftest :syntax/arithmetic/6 (clsql:sql [* 2 3]) "(2 * 3)") (deftest :syntax/substr/1 (clsql:sql [substr [hello] 1 4]) "SUBSTR(HELLO,1,4)") (deftest :syntax/substring/1 (clsql:sql [substring [hello] 1 4]) "SUBSTRING(HELLO,1,4)") (deftest :syntax/concat/1 (clsql:sql [|| [foo] [bar] [baz]]) "(FOO || BAR || BAZ)") (deftest :syntax/concat/2 (clsql:sql [concat [foo] [bar]]) "CONCAT(FOO,BAR)") (deftest :syntax/pattern/1 (clsql:sql [like [foo] "%v"]) "(FOO LIKE '%v')") (deftest :syntax/pattern/2 (clsql:sql [not [like [foo] "%v"]]) "(NOT ((FOO LIKE '%v')))") (deftest :syntax/distinct/1 (clsql:sql [distinct [foo bar :string]]) "DISTINCT FOO.BAR") (deftest :syntax/distinct/2 (clsql:sql [distinct [foo :string] [bar :integer]]) "DISTINCT FOO, BAR") (deftest :syntax/order-by/1 (clsql:sql [order-by [foo]]) "ORDER BY FOO") (deftest :syntax/group-by/1 (clsql:sql [group-by [foo]]) "GROUP BY FOO") (deftest :syntax/group-by/2 (clsql:sql (clsql-sys::make-query [foo] [bar] [count [foo]] :from [table] :group-by '([foo] [bar]) :order-by '([foo] [bar]))) "SELECT FOO,BAR,COUNT(FOO) FROM TABLE GROUP BY FOO,BAR ORDER BY FOO,BAR") (deftest :syntax/coalesce/1 (clsql:sql [coalesce [foo] [bar] "not specified"]) "COALESCE(FOO,BAR,'not specified')") (deftest :syntax/coalesce/2 (clsql:sql [nvl [foo] "not specified"]) "COALESCE(FOO,'not specified')") (deftest :syntax/nvl/1 (clsql:sql [nvl [foo] "not specified"]) "COALESCE(FOO,'not specified')") (deftest :syntax/sets/1 (clsql:sql [union [select [foo] :from [bar]] [select [baz] :from [bar]]]) "SELECT FOO FROM BAR UNION SELECT BAZ FROM BAR") (deftest :syntax/sets/2 (clsql:sql [intersect [select [foo] :from [bar]] [select [baz] :from [bar]]]) "SELECT FOO FROM BAR INTERSECT SELECT BAZ FROM BAR") (deftest :syntax/sets/3 (clsql:sql [except [select [foo] :from [bar]] [select [baz] :from [bar]]]) "SELECT FOO FROM BAR EXCEPT SELECT BAZ FROM BAR") (deftest :syntax/sets/4 (clsql:sql [minus [select [foo] :from [bar]] [select [baz] :from [bar]]]) "SELECT FOO FROM BAR MINUS SELECT BAZ FROM BAR") (deftest :syntax/function/1 (clsql:sql [function "COS" [age]]) "COS(AGE)") (deftest :syntax/function/2 (clsql:sql [function "TO_DATE" "02/06/99" "mm/DD/RR"]) "TO_DATE('02/06/99','mm/DD/RR')") (deftest :syntax/query/1 (clsql:sql [select [person_id] [surname] :from [person]]) "SELECT PERSON_ID,SURNAME FROM PERSON") (deftest :syntax/query/2 (clsql:sql [select [foo] [bar *] :from '([baz] [bar]) :where [or [= [foo] 3] [> [baz.quux] 10]]]) "SELECT FOO,BAR.* FROM BAZ,BAR WHERE ((FOO = 3) OR (BAZ.QUUX > 10))") (deftest :syntax/query/3 (clsql:sql [select [foo bar] [baz] :from '([foo] [quux]) :where [or [> [baz] 3] [like [foo bar] "SU%"]]]) "SELECT FOO.BAR,BAZ FROM FOO,QUUX WHERE ((BAZ > 3) OR (FOO.BAR LIKE 'SU%'))") (deftest :syntax/query/4 (clsql:sql [select [count [*]] :from [emp]]) "SELECT COUNT(*) FROM EMP") (deftest :syntax/expression/1 (clsql:sql (clsql:sql-operation 'select (clsql:sql-expression :table 'foo :attribute 'bar) (clsql:sql-expression :attribute 'baz) :from (list (clsql:sql-expression :table 'foo) (clsql:sql-expression :table 'quux)) :where (clsql:sql-operation 'or (clsql:sql-operation '> (clsql:sql-expression :attribute 'baz) 3) (clsql:sql-operation 'like (clsql:sql-expression :table 'foo :attribute 'bar) "SU%")))) "SELECT FOO.BAR,BAZ FROM FOO,QUUX WHERE ((BAZ > 3) OR (FOO.BAR LIKE 'SU%'))") (deftest :syntax/expression/2 (clsql:sql (apply (clsql:sql-operator 'and) (loop for table in '(thistime nexttime sometime never) for count from 42 collect [function "BETWEEN" (clsql:sql-expression :table table :attribute 'bar) (clsql:sql-operation '* [hip] [hop]) count] collect [like (clsql:sql-expression :table table :attribute 'baz) (clsql:sql table)]))) "(BETWEEN(THISTIME.BAR,(HIP * HOP),42) AND (THISTIME.BAZ LIKE 'THISTIME') AND BETWEEN(NEXTTIME.BAR,(HIP * HOP),43) AND (NEXTTIME.BAZ LIKE 'NEXTTIME') AND BETWEEN(SOMETIME.BAR,(HIP * HOP),44) AND (SOMETIME.BAZ LIKE 'SOMETIME') AND BETWEEN(NEVER.BAR,(HIP * HOP),45) AND (NEVER.BAZ LIKE 'NEVER'))" ) (deftest :syntax/subqueries/query (clsql:sql (clsql:sql-operation 'select [*] :from [foo] :where [in [id] [select [id] :from [bar]]])) "SELECT * FROM FOO WHERE (ID IN (SELECT ID FROM BAR))") (deftest :syntax/subqueries/delete (clsql:sql (make-instance 'clsql-sys::sql-delete :from [foo] :where [in [id] [select [id] :from [bar]]])) "DELETE FROM FOO WHERE (ID IN (SELECT ID FROM BAR))") (deftest :syntax/subqueries/update (clsql:sql (make-instance 'clsql-sys::sql-update :attributes (list [id]) :values '(0) :table [foo] :where [in [id] [select [id] :from [bar]]])) "UPDATE FOO SET ID = 0 WHERE (ID IN (SELECT ID FROM BAR))") )) (let ((tests '(((:foo) "FOO") ((:foo-bar) "FOO_BAR") (("foo") "\"foo\"") (('|foo bar|) "\"foo bar\"") ((:foo :table-alias :bar) "FOO BAR" ) ((:foo_bar :table-alias :bar-bast) "FOO_BAR BAR_BAST") (("foo" :table-alias "Bar") "\"foo\" \"Bar\"") (('|foo bar| :table-alias :bast) "\"foo bar\" BAST")))) (push `(deftest :syntax/sql-ident-table (values ,@(mapcar #'(lambda (args) `(clsql:sql (make-instance 'clsql-sys:sql-ident-table :name ,@args))) (mapcar #'first tests))) ,@(mapcar #'second tests)) *rt-syntax*)) cl-sql-6.7.2/tests/test-ooddl.lisp0000644000175000017500000001537512064366222016062 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: test-ooddl.lisp ;;;; Purpose: Tests for the CLSQL Object Oriented Data Definition Language ;;;; Authors: Marcus Pearce and Kevin M. Rosenberg ;;;; Created: March 2004 ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-tests) (clsql-sys:file-enable-sql-reader-syntax) (def-view-class big () ((i :type integer :initarg :i) (bi :type bigint :initarg :bi))) (def-dataset *ds-big* (:setup (lambda () (clsql-sys:create-view-from-class 'big) (let ((max (expt 2 60))) (dotimes (i 555) (update-records-from-instance (make-instance 'big :i (1+ i) :bi (truncate max (1+ i)))))))) (:cleanup (lambda () (clsql-sys:drop-view-from-class 'big)))) (setq *rt-ooddl* '( ;; Ensure slots inherited from standard-classes are :virtual (deftest :ooddl/metaclass/1 (values (clsql-sys::view-class-slot-db-kind (clsql-sys::slotdef-for-slot-with-class 'extraterrestrial (find-class 'person))) (clsql-sys::view-class-slot-db-kind (clsql-sys::slotdef-for-slot-with-class 'hobby (find-class 'person)))) :virtual :virtual) ;; Ensure all slots in view-class are view-class-effective-slot-definition (deftest :ooddl/metaclass/2 (values (every #'(lambda (slotd) (typep slotd 'clsql-sys::view-class-effective-slot-definition)) (clsql-sys::class-slots (find-class 'person))) (every #'(lambda (slotd) (typep slotd 'clsql-sys::view-class-effective-slot-definition)) (clsql-sys::class-slots (find-class 'employee))) (every #'(lambda (slotd) (typep slotd 'clsql-sys::view-class-effective-slot-definition)) (clsql-sys::class-slots (find-class 'setting))) (every #'(lambda (slotd) (typep slotd 'clsql-sys::view-class-effective-slot-definition)) (clsql-sys::class-slots (find-class 'theme))) (every #'(lambda (slotd) (typep slotd 'clsql-sys::view-class-effective-slot-definition)) (clsql-sys::class-slots (find-class 'node))) (every #'(lambda (slotd) (typep slotd 'clsql-sys::view-class-effective-slot-definition)) (clsql-sys::class-slots (find-class 'company)))) t t t t t t) ;; Ensure classes are correctly marked normalized or not, default not ;(deftest :ooddl/metaclass/3 ; (values ; (clsql-sys::normalizedp derivednode1) ; (clsql-sys::normalizedp basenode) ; (clsql-sys::normalizedp company1) ; (clsql-sys::normalizedp employee3) ; (clsql-sys::normalizedp derivednode-sc-2)) ; t nil nil nil t) ;(deftest :ooddl/metaclass/3 ; (values ; (normalizedp (find-class 'baseclass)) ; (normalizedp (find-class 'normderivedclass))) ; nil t) (deftest :ooddl/join/1 (with-dataset *ds-employees* (mapcar #'(lambda (e) (slot-value e 'ecompanyid)) (company-employees company1))) (1 1 1 1 1 1 1 1 1 1)) (deftest :ooddl/join/2 (with-dataset *ds-employees* (slot-value (president company1) 'last-name)) "Lenin") (deftest :ooddl/join/3 (with-dataset *ds-employees* (slot-value (employee-manager employee2) 'last-name)) "Lenin") (deftest :ooddl/join/4 (with-dataset *ds-employees* (values (length (employee-addresses employee10)) ;; add an address (let ((*db-auto-sync* T)) (make-instance 'address :addressid 50) (make-instance 'employee-address :emplid 10 :addressid 50) ;; again (length (employee-addresses employee10))) (progn (update-objects-joins (list employee10) :slots '(addresses)) (length (employee-addresses employee10))))) 0 0 1) (deftest :ooddl/big/1 ;;tests that we can create-view-from-class with a bigint slot, ;; and stick a value in there. (progn (clsql-sys:create-view-from-class 'big) (values (clsql:table-exists-p [big] ) (progn (clsql:drop-table [big] :if-does-not-exist :ignore) (clsql:table-exists-p [big] ))) ) t nil) (deftest :ooddl/big/2 (with-dataset *ds-big* (let ((rows (clsql:select [*] :from [big] :order-by [i] :field-names nil))) (values (length rows) (do ((i 0 (1+ i)) (max (expt 2 60)) (rest rows (cdr rest))) ((= i (length rows)) t) (let ((index (1+ i)) (int (first (car rest))) (bigint (second (car rest)))) (when (and (or (eq *test-database-type* :oracle) (and (eq *test-database-type* :odbc) (eq *test-database-underlying-type* :postgresql))) (stringp bigint)) (setf bigint (parse-integer bigint))) (unless (and (eql int index) (eql bigint (truncate max index))) (return nil))))))) 555 t) (deftest :ooddl/time/1 (with-dataset *ds-employees* (sleep 1) ;force birthdays into the past (let* ((now (clsql:get-time))) (when (member *test-database-underlying-type* '(:postgresql :postgresql-socket)) (clsql:execute-command "set datestyle to 'iso'")) (clsql:update-records [employee] :av-pairs `((birthday ,now)) :where [= [emplid] 1]) (let ((dbobj (car (clsql:select 'employee :where [= [birthday] now] :flatp t)))) (values (slot-value dbobj 'last-name) (clsql:time= (slot-value dbobj 'birthday) now))))) "Lenin" t) (deftest :ooddl/time/2 (with-dataset *ds-employees* (sleep 1) ;force birthdays into the past (let* ((now (clsql:get-time)) (fail-index -1)) (when (member *test-database-underlying-type* '(:postgresql :postgresql-socket)) (clsql:execute-command "set datestyle to 'iso'")) (dotimes (x 40) (clsql:update-records [employee] :av-pairs `((birthday ,now)) :where [= [emplid] 1]) (let ((dbobj (car (clsql:select 'employee :where [= [birthday] now] :flatp t)))) (unless (clsql:time= (slot-value dbobj 'birthday) now) (setf fail-index x)) (setf now (clsql:roll now :day (* 10 x))))) fail-index)) -1) (deftest :ooddl/time/3 (with-dataset *ds-employees* (progn (when (member *test-database-underlying-type* '(:postgresql :postgresql-socket)) (clsql:execute-command "set datestyle to 'iso'")) (let ((dbobj (car (clsql:select 'employee :where [= [emplid] 10] :flatp t)))) (list (eql *test-start-utime* (slot-value dbobj 'bd-utime)) (clsql:time= (slot-value dbobj 'birthday) (clsql:utime->time (slot-value dbobj 'bd-utime))))))) (t t)) )) cl-sql-6.7.2/tests/Makefile0000644000175000017500000000117711335067642014552 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL tests # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file is part of CLSQL # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/tests/README0000644000175000017500000001044212570246521013762 0ustar kevinkevin* RUNNING THE REGRESSION SUITE This test suite looks for a configuration file named ".clsql-test.config" located in the users home directory. This file contains a single assoc-list that specifies the connection specs for each database type to be tested. There is an example file in contained in CLSQL's examples directory. These tests require the downloading of the rt package from http://files.kpe.io/. Load clsql.asd or put it somewhere where ASDF can find it and call: (asdf:oos 'asdf:test-op 'clsql) The test suite will then automatically run on all of the backends that you have defined in .clsql-test.config * REGRESSION TEST SUITE GOALS The intent of this test suite is to provide sufficient coverage for the system to support the following: ** Refactoring and Redesign of particular subsystems Refactoring and redesign efforts are normally restricted to a single subsystem, or perhaps to interdependent subsystems. In such cases, a set of regression tests which excercise the existing interface of the rest of CLSQL to the changing subsystems should be in place and passing before the coding starts. ** Ensuring portability and Supporting new ports. The more coverage the test suite provides the easier portability is to maintain, particularly if we have instances of the test suite running against the head on the supporting lisp environment/OS/hardware/DBMS combinations. Since no individual within the project has the ability to run all of those combinations themselves, we are dependent upon some informal coordination between the mintainers of the various ports. ** Adding new RDBMS backends The entire CLSQL DBMS interface needs to be excercised by the test suite, such that a new RDBMS backend that passes all the tests can be reasonably assured of working with the CLSQL layers above that. These tests should also serve as impromptu documentation for the details of that interface and what it expects frothe RDBMS driver layers. ** Bug identification and QA As new bugs are identified, they should have a regression test written which excercises them. This is to ensue that we donot start backtracking. These tests by theselves are also very valuable for developers, so even if you cannot fix a bug yourself, providing a testto excercise it greatly reduces the amount of timea developer must spend finding the bug prior to fixing it. * TEST DESIGN ISSUES ** Multiple RDBMS Issues CLSQL supports several RDBMS backends, and it should be possible to run every test against all of them. However, there are some features which we want tests for but which are not implemented on several of the backends. ** Test Hygiene Tests should be able to be run multiple times against the same database. It is also important that they clean up after themselves when they create tables, sequences or other pesistent entities in the RDBMS backends, because often there are limits to the number of those thatcan exist at one time, and it also makes debuging thru the SQL monitors difficult when there aretons of unused tables lying around. If test need to load large datasets, they should have a mechanism to ensure the dataset is loaded just once, and not with every test run. Lastly, because there are various idiosyncracies with RDBMSs, please ensure that you run the entire test suite once when you write your tests, to ensure that your test does not leave some state behind which causes other tests to fail. ** Test Run Configuration The file test-init.lisp defines several variables which can be used to control the connection dictionary of the database against which tests will be run. * DATABASE CONNECTIONS/LIFECYCLE ** CreateDB *** Without existing DB *** With existing DB and use old *** With existing DB and use new *** Error if existing DB ** Data Definition *** Create Tables/Views/Sequences/Indexes -- Should cover creation of tables with all supported types of fields. *** Delete Tables/Views/Sequences/Indexes *** Inspection of Tables and attributes, including types ** Data Manipulation *** Update *** Insert *** Delete *** Query ** Functional Interface *** Creation/Modification of SQL expressions *** Querying ** Embedded SQL syntax *** Excercise all sql operators ** Object Interface *** View class definition *** Object creation/manipulation/deletion *** Inter-object Relations cl-sql-6.7.2/TODO0000644000175000017500000000177411345753563012450 0ustar kevinkevinTESTS TO ADD * Test that ":db-kind :key" adds an index for that key. This is complicated by different backends showing autogenerated primary key in different ways. * :db-constraint tests * Number and Char field types * symbol slot * generalized-boolean slot * tests for db-reader and db-writer OPTIMIZATIONS * Revisit result-type list creation, perhaps caching * Rework LIST-ATTRIBUTE-TYPES and LIST-INDEXES such that they exhibit their current behaviours using single database queries. * Possible use of cached attribute type information for operations which insert/update records as mentioned in the CommonSQL user guide. * Extend caching of generated SQL strings to more complex expressions which are likely to be repeatedly executed many times. POSSIBLE EXTENSIONS * improve large object api and extend to databases beyond postgresql * add support for prepared statements RACE CONDITIONS * sql/databases.lisp: *connected-databases* is shared globally but not modified in a threadsafe manner. cl-sql-6.7.2/clsql-aodbc.asd0000644000175000017500000000264311332141035014606 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-aodbc.asd ;;;; Purpose: ASDF definition file for CLSQL AODBC backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-aodbc-system (:use #:asdf #:cl)) (in-package #:clsql-aodbc-system) #+(and allegro (not allegro-cl-trial)) (defsystem clsql-aodbc :name "cl-sql-aodbc" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL AODBC Driver" :long-description "cl-sql-aodbc package provides a database driver to AllegroCL's AODBC database interface." :depends-on (clsql) :components ((:module :db-aodbc :components ((:file "aodbc-package") (:file "aodbc-sql" :depends-on ("aodbc-package")))))) #-(and allegro (not allegro-cl-trial)) (defsystem clsql-aodbc) cl-sql-6.7.2/clsql.asd0000644000175000017500000001057613735402537013564 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql.asd ;;;; Purpose: ASDF System definition for CLSQL ;;;; Authors: Marcus Pearce and Kevin M. Rosenberg ;;;; Created: March 2004 ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:clsql-system (:use #:asdf #:cl)) (in-package #:clsql-system) #+(and clisp (not :clsql-cffi)) (asdf:operate 'asdf:load-op 'clsql-cffi) ;; need to load uffi for below perform :after method (eval-when (:compile-toplevel :load-toplevel :execute) #+:clsql-cffi (unless (find-package 'cffi-uffi-compat) #+quicklisp (ql:quickload :cffi-uffi-compat) #-quicklisp (asdf:operate 'asdf:load-op 'cffi-uffi-compat)) #-:clsql-cffi (unless (find-package 'uffi) (asdf:operate 'asdf:load-op 'uffi))) (defsystem clsql :name "CLSQL" :author "Kevin Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL Interface library" :long-description "A Common Lisp interface to SQL RDBMS based on the Xanalys CommonSQL interface for Lispworks. It provides low-level database interfaces as well as a functional and an object oriented interface." :version "6.4" :components ((:module sql :components ((:module base :pathname "" :components ((:file "cmucl-compat") (:file "package") (:file "kmr-mop" :depends-on ("package")) (:file "base-classes" :depends-on ("package")) (:file "conditions" :depends-on ("base-classes")) (:file "db-interface" :depends-on ("conditions")) (:file "decimals" :depends-on ("package" "db-interface")) (:file "utils" :depends-on ("package" "db-interface")) (:file "time" :depends-on ("package" "conditions" "utils")) (:file "generics" :depends-on ("package")))) (:module database :pathname "" :components ((:file "initialize") (:file "database" :depends-on ("initialize")) (:file "recording" :depends-on ("database")) (:file "pool" :depends-on ("database"))) :depends-on (base)) (:module syntax :pathname "" :components ((:file "expressions") (:file "operations" :depends-on ("expressions")) (:file "syntax" :depends-on ("operations"))) :depends-on (database)) (:module functional :pathname "" :components ((:file "fdml") (:file "transaction" :depends-on ("fdml")) #+clisp (:file "ansi-loop") (:file "loop-extension" :depends-on ("fdml" #+clisp "ansi-loop")) (:file "fddl" :depends-on ("fdml"))) :depends-on (syntax)) (:module object :pathname "" :components ((:file "metaclasses") (:file "ooddl" :depends-on ("metaclasses")) (:file "oodml" :depends-on ("ooddl"))) :depends-on (functional)) (:module generic :pathname "" :components ((:file "generic-postgresql") (:file "generic-odbc") (:file "sequences") (:file "command-object")) :depends-on (functional))))) :in-order-to ((test-op (test-op "clsql-tests")))) (defmethod perform :after ((o load-op) (c (eql (find-system 'clsql)))) (let* ((init-var (uffi::getenv "CLSQLINIT")) (init-file (or (when init-var (probe-file init-var)) (probe-file (concatenate 'string (namestring (user-homedir-pathname)) ".clsql-init.lisp")) (probe-file "/etc/clsql-init.lisp") #+(or mswin windows win32 win64 mswindows) (probe-file "c:\\etc\\clsql-init.lisp")))) (when init-file (load init-file)))) cl-sql-6.7.2/sql/0000755000175000017500000000000014327126007012534 5ustar kevinkevincl-sql-6.7.2/sql/generic-odbc.lisp0000644000175000017500000002343412303270414015746 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Generic ODBC layer, used by db-odbc and db-aodbc backends ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass generic-odbc-database (database) ((dbi-package :initarg :dbi-package :reader dbi-package) (odbc-conn :initarg :odbc-conn :initform nil :accessor odbc-conn) (disconnect-fn :reader disconnect-fn) (sql-fn :reader sql-fn) (close-query-fn :reader close-query-fn) (fetch-row :reader fetch-row-fn) (list-all-database-tables-fn :reader list-all-database-tables-fn) (list-all-table-columns-fn :reader list-all-table-columns-fn) (odbc-db-type :accessor database-odbc-db-type :initarg :odbc-db-type )) (:documentation "Encapsulate same behavior across odbc and aodbc backends.")) (defmethod initialize-instance :after ((db generic-odbc-database) &rest all-keys) (declare (ignore all-keys)) (unless (slot-boundp db 'dbi-package) (error "dbi-package not specified.")) (let ((pkg (slot-value db 'dbi-package))) (unless pkg (error "dbi-package is nil.")) (setf (slot-value db 'disconnect-fn) (intern (symbol-name '#:disconnect) pkg) (slot-value db 'sql-fn) (intern (symbol-name '#:sql) pkg) (slot-value db 'close-query-fn) (intern (symbol-name '#:close-query) pkg) (slot-value db 'fetch-row) (intern (symbol-name '#:fetch-row) pkg) (slot-value db 'list-all-database-tables-fn) (intern (symbol-name '#:list-all-database-tables) pkg) (slot-value db 'list-all-table-columns-fn) (intern (symbol-name '#:list-all-table-columns) pkg)))) ;;; Type methods (defmethod database-get-type-specifier ((type symbol) args database (db-type (eql :mssql))) "Special database types for MSSQL backends" (declare (ignore database db-type args)) (case type (wall-time "DATETIME") (date "SMALLDATETIME") ((generalized-boolean boolean) "BIT") ((longchar text) "ntext") ((varchar string) (if args (format nil "NVARCHAR(~A)" (car args)) (format nil "NVARCHAR(~D)" *default-string-length*))) (t (call-next-method)))) ;;; Generation of SQL strings from lisp expressions (defmethod database-output-sql ((tee (eql t)) (database generic-odbc-database)) (case (database-underlying-type database) (:mssql "1") (t "'Y'"))) ;;; Database backend capabilities (defmethod db-type-use-fully-qualified-column-on-drop-index? ((db-type (eql :mssql))) t) (defmethod db-type-has-boolean-where? ((db-type (eql :mssql))) nil) (defmethod db-type-has-intersect? ((db-type (eql :mssql))) nil) (defmethod db-type-has-except? ((db-type (eql :mssql))) nil) ;;; Backend methods (defmethod database-disconnect ((database generic-odbc-database)) (funcall (disconnect-fn database) (odbc-conn database)) (setf (odbc-conn database) nil) t) (defmethod database-query (query-expression (database generic-odbc-database) result-types field-names) (handler-case (funcall (sql-fn database) query-expression :db (odbc-conn database) :result-types result-types :column-names field-names) #+ignore (error () (error 'sql-database-data-error :database database :expression query-expression :message "Query failed")))) (defmethod database-execute-command (sql-expression (database generic-odbc-database)) (handler-case (funcall (sql-fn database) sql-expression :db (odbc-conn database)) #+ignore (sql-error (e) (error e)) #+ignore (error () (error 'sql-database-data-error :database database :expression sql-expression :message "Execute command failed")))) (defstruct odbc-result-set (query nil) (types nil) (full-set nil :type boolean)) (defmethod database-query-result-set ((query-expression string) (database generic-odbc-database) &key full-set result-types) (handler-case (multiple-value-bind (query column-names) (funcall (sql-fn database) query-expression :db (odbc-conn database) :row-count nil :column-names t :query t :result-types result-types) (values (make-odbc-result-set :query query :full-set full-set :types result-types) (length column-names) nil ;; not able to return number of rows with odbc )) (error () (error 'sql-database-data-error :database database :expression query-expression :message "Query result set failed")))) (defmethod database-dump-result-set (result-set (database generic-odbc-database)) (funcall (close-query-fn database) (odbc-result-set-query result-set)) t) (defmethod database-store-next-row (result-set (database generic-odbc-database) list) (let ((row (funcall (fetch-row-fn database) (odbc-result-set-query result-set) nil 'eof))) (if (eq row 'eof) nil (progn (loop for elem in row for rest on list do (setf (car rest) elem)) list)))) (defun %database-list-* (database type owner) "Internal function used by database-list-tables and database-list-views" (multiple-value-bind (rows col-names) (funcall (list-all-database-tables-fn database) :db (odbc-conn database)) (declare (ignore col-names)) ;; http://msdn.microsoft.com/en-us/library/ms711831%28VS.85%29.aspx ;; TABLE_SCHEM is hard-coded in second column by ODBC Driver Manager ;; TABLE_NAME in third column, TABLE_TYPE in fourth column (loop for (category schema name ttype . rest) in rows when (and (string-equal type ttype) (or (null owner) (string-equal owner schema)) ;; unless requesting by name, skip system schema (not (and (null owner) (member schema '("information_schema" "sys") :test #'string-equal))) ;; skip system specific tables in mssql2000 (not (and (eql :mssql (database-underlying-type database)) (member name '("dtproperties" "sysconstraints" "syssegments") :test #'string-equal)))) collect name))) (defmethod database-list-tables ((database generic-odbc-database) &key (owner nil)) "Since ODBC doesn't expose the owner we use that parameter to filter on schema since that's what tends to be exposed. Some DBs like mssql 2000 conflate the two so at least there it works nicely." (%database-list-* database "TABLE" owner)) (defmethod database-list-views ((database generic-odbc-database) &key (owner nil)) "Since ODBC doesn't expose the owner we use that parameter to filter on schema since that's what tends to be exposed. Some DBs like mssql 2000 conflate the two so at least there it works nicely." (%database-list-* database "VIEW" owner)) (defmethod database-list-attributes ((table %database-identifier) (database generic-odbc-database) &key (owner nil) &aux (table (unescaped-database-identifier table))) (declare (ignore owner)) (multiple-value-bind (rows col-names) (funcall (list-all-table-columns-fn database) table :db (odbc-conn database)) (declare (ignore col-names)) ;; COLUMN_NAME is hard-coded by odbc spec as fourth position (loop for row in rows collect (fourth row)))) (defmethod database-attribute-type ((attribute %database-identifier) (table %database-identifier) (database generic-odbc-database) &key (owner nil) &aux (table (unescaped-database-identifier table)) (attribute (unescaped-database-identifier attribute))) (declare (ignore owner)) (multiple-value-bind (rows col-names) (funcall (list-all-table-columns-fn database) table :db (odbc-conn database)) (declare (ignore col-names)) ;; COLUMN_NAME is hard-coded by odbc spec as fourth position ;; TYPE_NAME is the sixth column ;; PRECISION/COLUMN_SIZE is the seventh column ;; SCALE/DECIMAL_DIGITS is the ninth column ;; NULLABLE is the eleventh column (loop for row in rows when (string-equal attribute (fourth row)) do (let ((size (seventh row)) (precision (ninth row)) (scale (nth 10 row))) (return (values (ensure-keyword (sixth row)) (when size (parse-integer size)) (when precision (parse-integer precision)) (when scale (parse-integer scale)))))))) (defmethod database-last-auto-increment-id ((database generic-odbc-database) table column) (case (database-underlying-type database) (:mssql (first (clsql:query "SELECT SCOPE_IDENTITY()" :flatp t :database database :result-types '(:int)))) (t (if (next-method-p) (call-next-method))))) (defmethod clsql-sys:db-type-has-auto-increment? ((db-underlying-type (eql :mssql))) t) cl-sql-6.7.2/sql/sequences.lisp0000644000175000017500000000717311746263021015430 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Generic sequence implementation. Backends should use native sequences if ;;;; are available. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass generic-database (database) () (:documentation "Encapsulate same behavior across backends.")) ;;; Sequence functions (defvar *old-sequence-names* nil "Should CLSQL use its old sequence naming scheme _CLSQL_SEQ_{table} instead of the current scheme {table}_CLSQL_SEQ") (defun %sequence-name-to-table (sequence-name database) (escaped (combine-database-identifiers (if *old-sequence-names* (list '_CLSQL_SEQ sequence-name) (list sequence-name 'CLSQL_SEQ)) database))) (defmethod database-create-sequence (sequence-name database) (let ((table-name (%sequence-name-to-table sequence-name database))) (database-execute-command (concatenate 'string "CREATE TABLE " table-name " (last_value int NOT NULL PRIMARY KEY, increment_by int, min_value int, is_called char(1))") database) (database-execute-command (concatenate 'string "INSERT INTO " table-name " VALUES (1,1,1,'f')") database))) (defmethod database-drop-sequence (sequence-name database) (database-execute-command (concatenate 'string "DROP TABLE " (%sequence-name-to-table sequence-name database)) database)) (defun %seq-name-key () (if *old-sequence-names* "_CLSQL_SEQ_" "_CLSQL_SEQ")) (defun %table-name-to-sequence-name (table-name) ;; if this was escaped it still should be, ;; if it wasnt it still shouldnt-be (check-type table-name string) (replace-all table-name (%seq-name-key) "")) (defmethod database-list-sequences (database &key (owner nil)) (declare (ignore owner)) (mapcan #'(lambda (s) (and (search (%seq-name-key) s :test #'string-equal) (list (%table-name-to-sequence-name s)))) (database-list-tables-and-sequences database))) (defmethod database-set-sequence-position (sequence-name position database) (database-execute-command (format nil "UPDATE ~A SET last_value=~A,is_called='t'" (%sequence-name-to-table sequence-name database) position) database) position) (defmethod database-sequence-next (sequence-name database) (without-interrupts (let* ((table-name (%sequence-name-to-table sequence-name database)) (tuple (car (database-query (concatenate 'string "SELECT last_value,is_called FROM " table-name) database :auto nil)))) (cond ((char-equal (schar (second tuple) 0) #\f) (database-execute-command (format nil "UPDATE ~A SET is_called='t'" table-name) database) (car tuple)) (t (let ((new-pos (1+ (car tuple)))) (database-execute-command (format nil "UPDATE ~A SET last_value=~D" table-name new-pos) database) new-pos)))))) (defmethod database-sequence-last (sequence-name database) (without-interrupts (caar (database-query (concatenate 'string "SELECT last_value FROM " (%sequence-name-to-table sequence-name database)) database :auto nil)))) cl-sql-6.7.2/sql/ansi-loop.lisp0000644000175000017500000031467310667176647015366 0ustar kevinkevin;;; -*- Mode: LISP; Package: ANSI-LOOP; Syntax: Common-lisp; Base: 10; Lowercase:T -*- ;;; ;;; This file is included with CLSQL to be used by CLISP which does not ;;; have an extensible LOOP macro. It was copied from the CMUCL 19c source. ;;; Minor porting changes have been made Copyright (c) 2006 Kevin M. Rosenberg ;;; ;;;> ;;;> Portions of LOOP are Copyright (c) 1986 by the Massachusetts Institute of Technology. ;;;> All Rights Reserved. ;;;> ;;;> Permission to use, copy, modify and distribute this software and its ;;;> documentation for any purpose and without fee is hereby granted, ;;;> provided that the M.I.T. copyright notice appear in all copies and that ;;;> both that copyright notice and this permission notice appear in ;;;> supporting documentation. The names "M.I.T." and "Massachusetts ;;;> Institute of Technology" may not be used in advertising or publicity ;;;> pertaining to distribution of the software without specific, written ;;;> prior permission. Notice must be given in supporting documentation that ;;;> copying distribution is by permission of M.I.T. M.I.T. makes no ;;;> representations about the suitability of this software for any purpose. ;;;> It is provided "as is" without express or implied warranty. ;;;> ;;;> Massachusetts Institute of Technology ;;;> 77 Massachusetts Avenue ;;;> Cambridge, Massachusetts 02139 ;;;> United States of America ;;;> +1-617-253-1000 ;;;> ;;;> Portions of LOOP are Copyright (c) 1989, 1990, 1991, 1992 by Symbolics, Inc. ;;;> All Rights Reserved. ;;;> ;;;> Permission to use, copy, modify and distribute this software and its ;;;> documentation for any purpose and without fee is hereby granted, ;;;> provided that the Symbolics copyright notice appear in all copies and ;;;> that both that copyright notice and this permission notice appear in ;;;> supporting documentation. The name "Symbolics" may not be used in ;;;> advertising or publicity pertaining to distribution of the software ;;;> without specific, written prior permission. Notice must be given in ;;;> supporting documentation that copying distribution is by permission of ;;;> Symbolics. Symbolics makes no representations about the suitability of ;;;> this software for any purpose. It is provided "as is" without express ;;;> or implied warranty. ;;;> ;;;> Symbolics, CLOE Runtime, and Minima are trademarks, and CLOE, Genera, ;;;> and Zetalisp are registered trademarks of Symbolics, Inc. ;;;> ;;;> Symbolics, Inc. ;;;> 8 New England Executive Park, East ;;;> Burlington, Massachusetts 01803 ;;;> United States of America ;;;> +1-617-221-1000 ;; $aclHeader: loop.cl,v 1.5 91/12/04 01:13:48 cox acl4_1 $ #+cmu (ext:file-comment "$Header: /project/cmucl/cvsroot/src/code/loop.lisp,v 1.27 2004/10/21 02:31:08 rtoy Exp $") ;;;; LOOP Iteration Macro #+clisp (eval-when (:compile-toplevel :load-toplevel :execute) (setf (ext:package-lock (find-package "COMMON-LISP")) nil)) (defpackage ansi-loop (:use :common-lisp) (:shadowing-import-from "COMMON-LISP" "LOOP" "LOOP-FINISH")) (in-package ansi-loop) ;;; Technology. ;;; ;;; The LOOP iteration macro is one of a number of pieces of code ;;; originally developed at MIT and licensed as set out above. This ;;; version of LOOP, which is almost entirely rewritten both as a ;;; clean-up and to conform with the ANSI Lisp LOOP standard, started ;;; life as MIT LOOP version 829 (which was a part of NIL, possibly ;;; never released). ;;; ;;; A "light revision" was performed by Glenn Burke while at Palladian ;;; Software in April 1986, to make the code run in Common Lisp. This ;;; revision was informally distributed to a number of people, and was ;;; sort of the "MIT" version of LOOP for running in Common Lisp. ;;; ;;; A later more drastic revision was performed at Palladian perhaps a ;;; year later. This version was more thoroughly Common Lisp in ;;; style, with a few miscellaneous internal improvements and ;;; extensions. Glenn Burke lost track of this source, apparently ;;; never having moved it to the MIT distribution point; and does not ;;; remember if it was ever distributed. ;;; ;;; This revision for the ANSI standard is based on the code of Glenn ;;; Burke's April 1986 version, with almost everything redesigned ;;; and/or rewritten. ;;; The design of this LOOP is intended to permit, using mostly the same ;;; kernel of code, up to three different "loop" macros: ;;; ;;; (1) The unextended, unextensible ANSI standard LOOP; ;;; ;;; (2) A clean "superset" extension of the ANSI LOOP which provides ;;; functionality similar to that of the old LOOP, but "in the style of" ;;; the ANSI LOOP. For instance, user-definable iteration paths, with a ;;; somewhat cleaned-up interface. ;;; ;;; (3) Extensions provided in another file which can make this LOOP ;;; kernel behave largely compatibly with the Genera-vintage LOOP macro, ;;; with only a small addition of code (instead of two whole, separate, ;;; LOOP macros). ;;; ;;; Each of the above three LOOP variations can coexist in the same LISP ;;; environment. ;;; ;;;; Miscellaneous Environment Things ;;;@@@@The LOOP-Prefer-POP feature makes LOOP generate code which "prefers" to use POP or ;;; its obvious expansion (prog1 (car x) (setq x (cdr x))). Usually this involves ;;; shifting fenceposts in an iteration or series of carcdr operations. This is ;;; primarily recognized in the list iterators (FOR .. {IN,ON}), and LOOP's ;;; destructuring setq code. (eval-when (compile load eval) #+(or Genera Minima) (pushnew :LOOP-Prefer-POP *features*) ) ;;; The uses of this macro are retained in the CL version of loop, in ;;; case they are needed in a particular implementation. Originally ;;; dating from the use of the Zetalisp COPYLIST* function, this is used ;;; in situations where, were cdr-coding in use, having cdr-NIL at the ;;; end of the list might be suboptimal because the end of the list will ;;; probably be RPLACDed and so cdr-normal should be used instead. (defmacro loop-copylist* (l) #+Genera `(lisp:copy-list ,l nil t) ; arglist = (list &optional area force-dotted) ;;@@@@Explorer?? #-Genera `(copy-list ,l) ) (defvar *loop-gentemp* t) (defun loop-gentemp (&optional (pref 'loopvar-)) (if *loop-gentemp* (gensym (string pref)) (gensym))) (eval-when (:compile-toplevel :load-toplevel :execute) (defvar *loop-real-data-type* 'real)) (defun loop-optimization-quantities (env) ;;@@@@ The ANSI conditionalization here is for those lisps that implement ;; DECLARATION-INFORMATION (from cleanup SYNTACTIC-ENVIRONMENT-ACCESS). ;; It is really commentary on how this code could be written. I don't ;; actually expect there to be an ANSI #+-conditional -- it should be ;; replaced with the appropriate conditional name for your ;; implementation/dialect. (declare #-ANSI (ignore env) #+Genera (values speed space safety compilation-speed debug)) #+ANSI (let ((stuff (declaration-information 'optimize env))) (values (or (cdr (assoc 'speed stuff)) 1) (or (cdr (assoc 'space stuff)) 1) (or (cdr (assoc 'safety stuff)) 1) (or (cdr (assoc 'compilation-speed stuff)) 1) (or (cdr (assoc 'debug stuff)) 1))) #+CLOE-Runtime (values compiler::time compiler::space compiler::safety compiler::compilation-speed 1) #-(or ANSI CLOE-Runtime) (values 1 1 1 1 1)) ;;;@@@@ The following form takes a list of variables and a form which presumably ;;; references those variables, and wraps it somehow so that the compiler does not ;;; consider those variables have been referenced. The intent of this is that ;;; iteration variables can be flagged as unused by the compiler, e.g. I in ;;; (loop for i from 1 to 10 do (print t)), since we will tell it when a usage ;;; of it is "invisible" or "not to be considered". ;;;We implicitly assume that a setq does not count as a reference. That is, the ;;; kind of form generated for the above loop construct to step I, simplified, is ;;; `(SETQ I ,(HIDE-VARIABLE-REFERENCES '(I) '(1+ I))). (defun hide-variable-references (variable-list form) (declare #-Genera (ignore variable-list)) #+Genera (if variable-list `(compiler:invisible-references ,variable-list ,form) form) #-Genera form) ;;;@@@@ The following function takes a flag, a variable, and a form which presumably ;;; references that variable, and wraps it somehow so that the compiler does not ;;; consider that variable to have been referenced. The intent of this is that ;;; iteration variables can be flagged as unused by the compiler, e.g. I in ;;; (loop for i from 1 to 10 do (print t)), since we will tell it when a usage ;;; of it is "invisible" or "not to be considered". ;;;We implicitly assume that a setq does not count as a reference. That is, the ;;; kind of form generated for the above loop construct to step I, simplified, is ;;; `(SETQ I ,(HIDE-VARIABLE-REFERENCES T 'I '(1+ I))). ;;;Certain cases require that the "invisibility" of the reference be conditional upon ;;; something. This occurs in cases of "named" variables (the USING clause). For instance, ;;; we want IDX in (LOOP FOR E BEING THE VECTOR-ELEMENTS OF V USING (INDEX IDX) ...) ;;; to be "invisible" when it is stepped, so that the user gets informed if IDX is ;;; not referenced. However, if no USING clause is present, we definitely do not ;;; want to be informed that some random gensym is not used. ;;;It is easier for the caller to do this conditionally by passing a flag (which ;;; happens to be the second value of NAMED-VARIABLE, q.v.) to this function than ;;; for all callers to contain the conditional invisibility construction. (defun hide-variable-reference (really-hide variable form) (declare #-Genera (ignore really-hide variable)) #+Genera (if (and really-hide variable (atom variable)) ;Punt on destructuring patterns `(compiler:invisible-references (,variable) ,form) form) #-Genera form) ;;;; List Collection Macrology (defmacro with-loop-list-collection-head ((head-var tail-var &optional user-head-var) &body body) ;;@@@@ TI? Exploder? #+LISPM (let ((head-place (or user-head-var head-var))) `(let* ((,head-place nil) (,tail-var ,(hide-variable-reference user-head-var user-head-var `(progn #+Genera (scl:locf ,head-place) #-Genera (system:variable-location ,head-place))))) ,@body)) #-LISPM (let ((l (and user-head-var (list (list user-head-var nil))))) #+CLOE `(sys::with-stack-list* (,head-var nil nil) (let ((,tail-var ,head-var) ,@l) ,@body)) #-CLOE `(let* ((,head-var (list nil)) (,tail-var ,head-var) ,@l) ,@body))) (defmacro loop-collect-rplacd (&environment env (head-var tail-var &optional user-head-var) form) (declare #+LISPM (ignore head-var user-head-var) ;use locatives, unconditionally update through the tail. ) (setq form (macroexpand form env)) (flet ((cdr-wrap (form n) (declare (fixnum n)) (do () ((<= n 4) (setq form `(,(case n (1 'cdr) (2 'cddr) (3 'cdddr) (4 'cddddr)) ,form))) (setq form `(cddddr ,form) n (- n 4))))) (let ((tail-form form) (ncdrs nil)) ;;Determine if the form being constructed is a list of known length. (when (consp form) (cond ((eq (car form) 'list) (setq ncdrs (1- (length (cdr form)))) ;;@@@@ Because the last element is going to be RPLACDed, ;; we don't want the cdr-coded implementations to use ;; cdr-nil at the end (which would just force copying ;; the whole list again). #+LISPM (setq tail-form `(list* ,@(cdr form) nil))) ((member (car form) '(list* cons)) (when (and (cddr form) (member (car (last form)) '(nil 'nil))) (setq ncdrs (- (length (cdr form)) 2)))))) (let ((answer (cond ((null ncdrs) `(when (setf (cdr ,tail-var) ,tail-form) (setq ,tail-var (last (cdr ,tail-var))))) ((< ncdrs 0) (return-from loop-collect-rplacd nil)) ((= ncdrs 0) ;;@@@@ Here we have a choice of two idioms: ;; (rplacd tail (setq tail tail-form)) ;; (setq tail (setf (cdr tail) tail-form)). ;;Genera and most others I have seen do better with the former. `(rplacd ,tail-var (setq ,tail-var ,tail-form))) (t `(setq ,tail-var ,(cdr-wrap `(setf (cdr ,tail-var) ,tail-form) ncdrs)))))) ;;If not using locatives or something similar to update the user's ;; head variable, we've got to set it... It's harmless to repeatedly set it ;; unconditionally, and probably faster than checking. #-LISPM (when user-head-var (setq answer `(progn ,answer (setq ,user-head-var (cdr ,head-var))))) answer)))) (defmacro loop-collect-answer (head-var &optional user-head-var) (or user-head-var (progn ;;If we use locatives to get tail-updating to update the head var, ;; then the head var itself contains the answer. Otherwise we ;; have to cdr it. #+LISPM head-var #-LISPM `(cdr ,head-var)))) ;;;; Maximization Technology #| The basic idea of all this minimax randomness here is that we have to have constructed all uses of maximize and minimize to a particular "destination" before we can decide how to code them. The goal is to not have to have any kinds of flags, by knowing both that (1) the type is something which we can provide an initial minimum or maximum value for and (2) know that a MAXIMIZE and MINIMIZE are not being combined. SO, we have a datastructure which we annotate with all sorts of things, incrementally updating it as we generate loop body code, and then use a wrapper and internal macros to do the coding when the loop has been constructed. |# (defstruct (loop-minimax (:constructor make-loop-minimax-internal) (:copier nil) (:predicate nil)) answer-variable type temp-variable flag-variable operations infinity-data) (defvar *loop-minimax-type-infinities-alist* ;;@@@@ This is the sort of value this should take on for a Lisp that has ;; "eminently usable" infinities. n.b. there are neither constants nor ;; printed representations for infinities defined by CL. ;;@@@@ This grotesque read-from-string below is to help implementations ;; which croak on the infinity character when it appears in a token, even ;; conditionalized out. #+Genera '#.(read-from-string "((fixnum most-positive-fixnum most-negative-fixnum) (short-float +1s -1s) (single-float +1f -1f) (double-float +1d -1d) (long-float +1l -1l))") ;;This is how the alist should look for a lisp that has no infinities. In ;; that case, MOST-POSITIVE-x-FLOAT really IS the most positive. #+(or CLOE-Runtime Minima) '((fixnum most-positive-fixnum most-negative-fixnum) (short-float most-positive-short-float most-negative-short-float) (single-float most-positive-single-float most-negative-single-float) (double-float most-positive-double-float most-negative-double-float) (long-float most-positive-long-float most-negative-long-float)) ;; CMUCL has infinities so let's use them. #+CMU '((fixnum most-positive-fixnum most-negative-fixnum) (short-float ext:single-float-positive-infinity ext:single-float-negative-infinity) (single-float ext:single-float-positive-infinity ext:single-float-negative-infinity) (double-float ext:double-float-positive-infinity ext:double-float-negative-infinity) (long-float ext:long-float-positive-infinity ext:long-float-negative-infinity)) ;; If we don't know, then we cannot provide "infinite" initial values for any of the ;; types but FIXNUM: #-(or Genera CLOE-Runtime Minima CMU) '((fixnum most-positive-fixnum most-negative-fixnum)) ) (defun make-loop-minimax (answer-variable type) (let ((infinity-data (cdr (assoc type *loop-minimax-type-infinities-alist* :test #'subtypep)))) (make-loop-minimax-internal :answer-variable answer-variable :type type :temp-variable (loop-gentemp 'loop-maxmin-temp-) :flag-variable (and (not infinity-data) (loop-gentemp 'loop-maxmin-flag-)) :operations nil :infinity-data infinity-data))) (defun loop-note-minimax-operation (operation minimax) (pushnew (the symbol operation) (loop-minimax-operations minimax)) (when (and (cdr (loop-minimax-operations minimax)) (not (loop-minimax-flag-variable minimax))) (setf (loop-minimax-flag-variable minimax) (loop-gentemp 'loop-maxmin-flag-))) operation) (defmacro with-minimax-value (lm &body body) (let ((init (loop-typed-init (loop-minimax-type lm))) (which (car (loop-minimax-operations lm))) (infinity-data (loop-minimax-infinity-data lm)) (answer-var (loop-minimax-answer-variable lm)) (temp-var (loop-minimax-temp-variable lm)) (flag-var (loop-minimax-flag-variable lm)) (type (loop-minimax-type lm))) (if flag-var `(let ((,answer-var ,init) (,temp-var ,init) (,flag-var nil)) (declare (type ,type ,answer-var ,temp-var)) ,@body) `(let ((,answer-var ,(if (eq which 'min) (first infinity-data) (second infinity-data))) (,temp-var ,init)) (declare (type ,type ,answer-var ,temp-var)) ,@body)))) (defmacro loop-accumulate-minimax-value (lm operation form) (let* ((answer-var (loop-minimax-answer-variable lm)) (temp-var (loop-minimax-temp-variable lm)) (flag-var (loop-minimax-flag-variable lm)) (test (hide-variable-reference t (loop-minimax-answer-variable lm) `(,(ecase operation (min '<) (max '>)) ,temp-var ,answer-var)))) `(progn (setq ,temp-var ,form) (when ,(if flag-var `(or (not ,flag-var) ,test) test) (setq ,@(and flag-var `(,flag-var t)) ,answer-var ,temp-var))))) ;;;; Loop Keyword Tables #| LOOP keyword tables are hash tables string keys and a test of EQUAL. The actual descriptive/dispatch structure used by LOOP is called a "loop universe" contains a few tables and parameterizations. The basic idea is that we can provide a non-extensible ANSI-compatible loop environment, an extensible ANSI-superset loop environment, and (for such environments as CLOE) one which is "sufficiently close" to the old Genera-vintage LOOP for use by old user programs without requiring all of the old LOOP code to be loaded. |# ;;;; Token Hackery ;;;Compare two "tokens". The first is the frob out of *LOOP-SOURCE-CODE*, ;;; the second a symbol to check against. (defun loop-tequal (x1 x2) (and (symbolp x1) (string= x1 x2))) (defun loop-tassoc (kwd alist) (and (symbolp kwd) (assoc kwd alist :test #'string=))) (defun loop-tmember (kwd list) (and (symbolp kwd) (member kwd list :test #'string=))) (defun loop-lookup-keyword (loop-token table) (and (symbolp loop-token) (values (gethash (symbol-name loop-token) table)))) (defmacro loop-store-table-data (symbol table datum) `(setf (gethash (symbol-name ,symbol) ,table) ,datum)) (defstruct (loop-universe (:print-function print-loop-universe) (:copier nil) (:predicate nil)) keywords ;hash table, value = (fn-name . extra-data). iteration-keywords ;hash table, value = (fn-name . extra-data). for-keywords ;hash table, value = (fn-name . extra-data). path-keywords ;hash table, value = (fn-name . extra-data). type-symbols ;hash table of type SYMBOLS, test EQ, value = CL type specifier. type-keywords ;hash table of type STRINGS, test EQUAL, value = CL type spec. ansi ;NIL, T, or :EXTENDED. implicit-for-required ;see loop-hack-iteration ) (eval-when (:compile-toplevel :load-toplevel :execute) (defun print-loop-universe (u stream level) (declare (ignore level)) (let ((str (case (loop-universe-ansi u) ((nil) "Non-ANSI") ((t) "ANSI") (:extended "Extended-ANSI") (t (loop-universe-ansi u))))) ;;Cloe could be done with the above except for bootstrap lossage... #+CLOE (format stream "#<~S ~A ~X>" (type-of u) str (sys::address-of u)) (print-unreadable-object (u stream :type t :identity t) (princ str stream)) ))) ;;;This is the "current" loop context in use when we are expanding a ;;;loop. It gets bound on each invocation of LOOP. (defvar *loop-universe*) (eval-when (:compile-toplevel :load-toplevel :execute) (defun make-standard-loop-universe (&key keywords for-keywords iteration-keywords path-keywords type-keywords type-symbols ansi) #-(and CLOE Source-Bootstrap) (check-type ansi (member nil t :extended)) (flet ((maketable (entries) (let* ((size (length entries)) (ht (make-hash-table :size (if (< size 10) 10 size) :test #'equal))) (dolist (x entries) (setf (gethash (symbol-name (car x)) ht) (cadr x))) ht))) (make-loop-universe :keywords (maketable keywords) :for-keywords (maketable for-keywords) :iteration-keywords (maketable iteration-keywords) :path-keywords (maketable path-keywords) :ansi ansi :implicit-for-required (not (null ansi)) :type-keywords (maketable type-keywords) :type-symbols (let* ((size (length type-symbols)) (ht (make-hash-table :size (if (< size 10) 10 size) :test #'eq))) (dolist (x type-symbols) (if (atom x) (setf (gethash x ht) x) (setf (gethash (car x) ht) (cadr x)))) ht))))) ;;;; Setq Hackery (defvar *loop-destructuring-hooks* nil "If not NIL, this must be a list of two things: a LET-like macro, and a SETQ-like macro, which perform LOOP-style destructuring.") (defun loop-make-psetq (frobs) (and frobs (loop-make-desetq (list (car frobs) (if (null (cddr frobs)) (cadr frobs) `(prog1 ,(cadr frobs) ,(loop-make-psetq (cddr frobs)))))))) (defun loop-make-desetq (var-val-pairs) (if (null var-val-pairs) nil (cons (if *loop-destructuring-hooks* (cadr *loop-destructuring-hooks*) 'loop-really-desetq) var-val-pairs))) (defvar *loop-desetq-temporary* (make-symbol "LOOP-DESETQ-TEMP")) (defmacro loop-really-desetq (&environment env &rest var-val-pairs) (labels ((find-non-null (var) ;; see if there's any non-null thing here ;; recurse if the list element is itself a list (do ((tail var)) ((not (consp tail)) tail) (when (find-non-null (pop tail)) (return t)))) (loop-desetq-internal (var val &optional temp) ;; returns a list of actions to be performed (typecase var (null (when (consp val) ;; don't lose possible side-effects (if (eq (car val) 'prog1) ;; these can come from psetq or desetq below. ;; throw away the value, keep the side-effects. ;;Special case is for handling an expanded POP. (mapcan #'(lambda (x) (and (consp x) (or (not (eq (car x) 'car)) (not (symbolp (cadr x))) (not (symbolp (setq x (macroexpand x env))))) (cons x nil))) (cdr val)) `(,val)))) (cons (let* ((car (car var)) (cdr (cdr var)) (car-non-null (find-non-null car)) (cdr-non-null (find-non-null cdr))) (when (or car-non-null cdr-non-null) (if cdr-non-null (let* ((temp-p temp) (temp (or temp *loop-desetq-temporary*)) (body #+LOOP-Prefer-POP `(,@(loop-desetq-internal car `(prog1 (car ,temp) (setq ,temp (cdr ,temp)))) ,@(loop-desetq-internal cdr temp temp)) #-LOOP-Prefer-POP `(,@(loop-desetq-internal car `(car ,temp)) (setq ,temp (cdr ,temp)) ,@(loop-desetq-internal cdr temp temp)))) (if temp-p `(,@(unless (eq temp val) `((setq ,temp ,val))) ,@body) `((let ((,temp ,val)) ,@body)))) ;; no cdring to do (loop-desetq-internal car `(car ,val) temp))))) (otherwise (unless (eq var val) `((setq ,var ,val))))))) (do ((actions)) ((null var-val-pairs) (if (null (cdr actions)) (car actions) `(progn ,@(nreverse actions)))) (setq actions (revappend (loop-desetq-internal (pop var-val-pairs) (pop var-val-pairs)) actions))))) ;;;; LOOP-local variables ;;;This is the "current" pointer into the LOOP source code. (defvar *loop-source-code*) ;;;This is the pointer to the original, for things like NAMED that ;;;insist on being in a particular position (defvar *loop-original-source-code*) ;;;This is *loop-source-code* as of the "last" clause. It is used ;;;primarily for generating error messages (see loop-error, loop-warn). (defvar *loop-source-context*) ;;;List of names for the LOOP, supplied by the NAMED clause. (defvar *loop-names*) ;;;The macroexpansion environment given to the macro. (defvar *loop-macro-environment*) ;;;This holds variable names specified with the USING clause. ;;; See LOOP-NAMED-VARIABLE. (defvar *loop-named-variables*) ;;; LETlist-like list being accumulated for one group of parallel bindings. (defvar *loop-variables*) ;;;List of declarations being accumulated in parallel with ;;;*loop-variables*. (defvar *loop-declarations*) ;;;Used by LOOP for destructuring binding, if it is doing that itself. ;;; See loop-make-variable. (defvar *loop-desetq-crocks*) ;;; List of wrapping forms, innermost first, which go immediately inside ;;; the current set of parallel bindings being accumulated in ;;; *loop-variables*. The wrappers are appended onto a body. E.g., ;;; this list could conceivably has as its value ((with-open-file (g0001 ;;; g0002 ...))), with g0002 being one of the bindings in ;;; *loop-variables* (this is why the wrappers go inside of the variable ;;; bindings). (defvar *loop-wrappers*) ;;;This accumulates lists of previous values of *loop-variables* and the ;;;other lists above, for each new nesting of bindings. See ;;;loop-bind-block. (defvar *loop-bind-stack*) ;;;This is a LOOP-global variable for the (obsolete) NODECLARE clause ;;;which inhibits LOOP from actually outputting a type declaration for ;;;an iteration (or any) variable. (defvar *loop-nodeclare*) ;;;This is simply a list of LOOP iteration variables, used for checking ;;;for duplications. (defvar *loop-iteration-variables*) ;;;List of prologue forms of the loop, accumulated in reverse order. (defvar *loop-prologue*) (defvar *loop-before-loop*) (defvar *loop-body*) (defvar *loop-after-body*) ;;;This is T if we have emitted any body code, so that iteration driving ;;;clauses can be disallowed. This is not strictly the same as ;;;checking *loop-body*, because we permit some clauses such as RETURN ;;;to not be considered "real" body (so as to permit the user to "code" ;;;an abnormal return value "in loop"). (defvar *loop-emitted-body*) ;;;List of epilogue forms (supplied by FINALLY generally), accumulated ;;; in reverse order. (defvar *loop-epilogue*) ;;;List of epilogue forms which are supplied after the above "user" ;;;epilogue. "normal" termination return values are provide by putting ;;;the return form in here. Normally this is done using ;;;loop-emit-final-value, q.v. (defvar *loop-after-epilogue*) ;;;The "culprit" responsible for supplying a final value from the loop. ;;;This is so loop-emit-final-value can moan about multiple return ;;;values being supplied. (defvar *loop-final-value-culprit*) ;;;If not NIL, we are in some branch of a conditional. Some clauses may ;;;be disallowed. (defvar *loop-inside-conditional*) ;;;If not NIL, this is a temporary bound around the loop for holding the ;;;temporary value for "it" in things like "when (f) collect it". It ;;;may be used as a supertemporary by some other things. (defvar *loop-when-it-variable*) ;;;Sometimes we decide we need to fold together parts of the loop, but ;;;some part of the generated iteration code is different for the first ;;;and remaining iterations. This variable will be the temporary which ;;;is the flag used in the loop to tell whether we are in the first or ;;;remaining iterations. (defvar *loop-never-stepped-variable*) ;;;List of all the value-accumulation descriptor structures in the loop. ;;; See loop-get-collection-info. (defvar *loop-collection-cruft*) ; for multiple COLLECTs (etc) ;;;; Code Analysis Stuff (defun loop-constant-fold-if-possible (form &optional expected-type) #+Genera (declare (values new-form constantp constant-value)) (let ((new-form form) (constantp nil) (constant-value nil)) #+Genera (setq new-form (compiler:optimize-form form *loop-macro-environment* :repeat t :do-macro-expansion t :do-named-constants t :do-inline-forms t :do-optimizers t :do-constant-folding t :do-function-args t) constantp (constantp new-form *loop-macro-environment*) constant-value (and constantp (lt:evaluate-constant new-form *loop-macro-environment*))) #-Genera (when (setq constantp (constantp new-form)) (setq constant-value (eval new-form))) (when (and constantp expected-type) (unless (typep constant-value expected-type) (loop-warn "The form ~S evaluated to ~S, which was not of the anticipated type ~S." form constant-value expected-type) (setq constantp nil constant-value nil))) (values new-form constantp constant-value))) (defun loop-constantp (form) #+Genera (constantp form *loop-macro-environment*) #-Genera (constantp form)) ;;;; LOOP Iteration Optimization (defvar *loop-duplicate-code* nil) (defvar *loop-iteration-flag-variable* (make-symbol "LOOP-NOT-FIRST-TIME")) (defun loop-code-duplication-threshold (env) (multiple-value-bind (speed space) (loop-optimization-quantities env) (+ 40 (* (- speed space) 10)))) (defmacro loop-body (&environment env prologue before-loop main-body after-loop epilogue &aux rbefore rafter flagvar) (unless (= (length before-loop) (length after-loop)) (error "LOOP-BODY called with non-synched before- and after-loop lists.")) ;;All our work is done from these copies, working backwards from the end: (setq rbefore (reverse before-loop) rafter (reverse after-loop)) (labels ((psimp (l) (let ((ans nil)) (dolist (x l) (when x (push x ans) (when (and (consp x) (member (car x) '(go return return-from))) (return nil)))) (nreverse ans))) (pify (l) (if (null (cdr l)) (car l) `(progn ,@l))) (makebody () (let ((form `(tagbody ;; ANSI CL 6.1.7.2 says that initially clauses are ;; evaluated in the loop prologue, which precedes ;; all loop code except for the initial settings ;; provided by with, for, or as. ,@(psimp (append (nreverse rbefore) prologue)) next-loop ,@(psimp (append main-body (nreconc rafter `((go next-loop))))) end-loop ,@(psimp epilogue)))) (if flagvar `(let ((,flagvar nil)) ,form) form)))) (when (or *loop-duplicate-code* (not rbefore)) (return-from loop-body (makebody))) ;; This outer loop iterates once for each not-first-time flag test generated ;; plus once more for the forms that don't need a flag test (do ((threshold (loop-code-duplication-threshold env))) (nil) (declare (fixnum threshold)) ;; Go backwards from the ends of before-loop and after-loop merging all the equivalent ;; forms into the body. (do () ((or (null rbefore) (not (equal (car rbefore) (car rafter))))) (push (pop rbefore) main-body) (pop rafter)) (unless rbefore (return (makebody))) ;; The first forms in rbefore & rafter (which are the chronologically ;; last forms in the list) differ, therefore they cannot be moved ;; into the main body. If everything that chronologically precedes ;; them either differs or is equal but is okay to duplicate, we can ;; just put all of rbefore in the prologue and all of rafter after ;; the body. Otherwise, there is something that is not okay to ;; duplicate, so it and everything chronologically after it in ;; rbefore and rafter must go into the body, with a flag test to ;; distinguish the first time around the loop from later times. ;; What chronologically precedes the non-duplicatable form will ;; be handled the next time around the outer loop. (do ((bb rbefore (cdr bb)) (aa rafter (cdr aa)) (lastdiff nil) (count 0) (inc nil)) ((null bb) (return-from loop-body (makebody))) ;Did it. (cond ((not (equal (car bb) (car aa))) (setq lastdiff bb count 0)) ((or (not (setq inc (estimate-code-size (car bb) env))) (> (incf count inc) threshold)) ;; Ok, we have found a non-duplicatable piece of code. Everything ;; chronologically after it must be in the central body. ;; Everything chronologically at and after lastdiff goes into the ;; central body under a flag test. (let ((then nil) (else nil)) (do () (nil) (push (pop rbefore) else) (push (pop rafter) then) (when (eq rbefore (cdr lastdiff)) (return))) (unless flagvar (push `(setq ,(setq flagvar *loop-iteration-flag-variable*) t) else)) (push `(if ,flagvar ,(pify (psimp then)) ,(pify (psimp else))) main-body)) ;; Everything chronologically before lastdiff until the non-duplicatable form (car bb) ;; is the same in rbefore and rafter so just copy it into the body (do () (nil) (pop rafter) (push (pop rbefore) main-body) (when (eq rbefore (cdr bb)) (return))) (return))))))) (defun duplicatable-code-p (expr env) (if (null expr) 0 (let ((ans (estimate-code-size expr env))) (declare (fixnum ans)) ;;@@@@ Use (DECLARATION-INFORMATION 'OPTIMIZE ENV) here to get an alist of ;; optimize quantities back to help quantify how much code we are willing to ;; duplicate. ans))) (defvar *special-code-sizes* '((return 0) (progn 0) (null 1) (not 1) (eq 1) (car 1) (cdr 1) (when 1) (unless 1) (if 1) (caar 2) (cadr 2) (cdar 2) (cddr 2) (caaar 3) (caadr 3) (cadar 3) (caddr 3) (cdaar 3) (cdadr 3) (cddar 3) (cdddr 3) (caaaar 4) (caaadr 4) (caadar 4) (caaddr 4) (cadaar 4) (cadadr 4) (caddar 4) (cadddr 4) (cdaaar 4) (cdaadr 4) (cdadar 4) (cdaddr 4) (cddaar 4) (cddadr 4) (cdddar 4) (cddddr 4))) (defvar *estimate-code-size-punt* '(block do do* dolist flet labels lambda let let* locally macrolet multiple-value-bind prog prog* symbol-macrolet tagbody unwind-protect with-open-file)) (defun destructuring-size (x) (do ((x x (cdr x)) (n 0 (+ (destructuring-size (car x)) n))) ((atom x) (+ n (if (null x) 0 1))))) (defun estimate-code-size (x env) (catch 'estimate-code-size (estimate-code-size-1 x env))) (defun estimate-code-size-1 (x env) (flet ((list-size (l) (let ((n 0)) (declare (fixnum n)) (dolist (x l n) (incf n (estimate-code-size-1 x env)))))) ;;@@@@ ???? (declare (function list-size (list) fixnum)) (cond ((constantp x #+Genera env) 1) ((symbolp x) (multiple-value-bind (new-form expanded-p) (macroexpand-1 x env) (if expanded-p (estimate-code-size-1 new-form env) 1))) ((atom x) 1) ;??? self-evaluating??? ((symbolp (car x)) (let ((fn (car x)) (tem nil) (n 0)) (declare (symbol fn) (fixnum n)) (macrolet ((f (overhead &optional (args nil args-p)) `(the fixnum (+ (the fixnum ,overhead) (the fixnum (list-size ,(if args-p args '(cdr x)))))))) (cond ((setq tem (get fn 'estimate-code-size)) (typecase tem (fixnum (f tem)) (t (funcall tem x env)))) ((setq tem (assoc fn *special-code-sizes*)) (f (second tem))) #+Genera ((eq fn 'compiler:invisible-references) (list-size (cddr x))) ((eq fn 'cond) (dolist (clause (cdr x) n) (incf n (list-size clause)) (incf n))) ((eq fn 'desetq) (do ((l (cdr x) (cdr l))) ((null l) n) (setq n (+ n (destructuring-size (car l)) (estimate-code-size-1 (cadr l) env))))) ((member fn '(setq psetq)) (do ((l (cdr x) (cdr l))) ((null l) n) (setq n (+ n (estimate-code-size-1 (cadr l) env) 1)))) ((eq fn 'go) 1) ((eq fn 'function) ;;This skirts the issue of implementationally-defined lambda macros ;; by recognizing CL function names and nothing else. #-cmu 1 #+cmu (if (ext:valid-function-name-p (cadr x)) 1 (throw 'duplicatable-code-p nil))) ((eq fn 'multiple-value-setq) (f (length (second x)) (cddr x))) ((eq fn 'return-from) (1+ (estimate-code-size-1 (third x) env))) ((or (special-operator-p fn) (member fn *estimate-code-size-punt*)) (throw 'estimate-code-size nil)) (t (multiple-value-bind (new-form expanded-p) (macroexpand-1 x env) (if expanded-p (estimate-code-size-1 new-form env) (f 3)))))))) (t (throw 'estimate-code-size nil))))) ;;;; Loop Errors (defun loop-context () (do ((l *loop-source-context* (cdr l)) (new nil (cons (car l) new))) ((eq l (cdr *loop-source-code*)) (nreverse new)))) (defun loop-error (format-string &rest format-args) #+(or Genera CLOE) (declare (dbg:error-reporter)) #+Genera (setq format-args (copy-list format-args)) ;Don't ask. #+cmu (kernel:simple-program-error "~?~%Current LOOP context:~{ ~S~}." format-string format-args (loop-context)) #-cmu (error "~?~%Current LOOP context:~{ ~S~}." format-string format-args (loop-context))) (defun loop-warn (format-string &rest format-args) (warn "~?~%Current LOOP context:~{ ~S~}." format-string format-args (loop-context))) (defun loop-check-data-type (specified-type required-type &optional (default-type required-type)) (if (null specified-type) default-type (multiple-value-bind (a b) (subtypep specified-type required-type) (cond ((not b) (loop-warn "LOOP couldn't verify that ~S is a subtype of the required type ~S." specified-type required-type)) ((not a) (loop-error "Specified data type ~S is not a subtype of ~S." specified-type required-type))) specified-type))) ;;;INTERFACE: Traditional, ANSI, Lucid. (defmacro loop-finish () "Causes the iteration to terminate \"normally\", the same as implicit termination by an iteration driving clause, or by use of WHILE or UNTIL -- the epilogue code (if any) will be run, and any implicitly collected result will be returned as the value of the LOOP." '(go end-loop)) (defun subst-gensyms-for-nil (tree) (declare (special *ignores*)) (cond ((null tree) (car (push (loop-gentemp) *ignores*))) ((atom tree) tree) (t (cons (subst-gensyms-for-nil (car tree)) (subst-gensyms-for-nil (cdr tree)))))) (defun loop-build-destructuring-bindings (crocks forms) (if crocks (let ((*ignores* ())) (declare (special *ignores*)) `((destructuring-bind ,(subst-gensyms-for-nil (car crocks)) ,(cadr crocks) (declare (ignore ,@*ignores*)) ,@(loop-build-destructuring-bindings (cddr crocks) forms)))) forms)) (defun loop-translate (*loop-source-code* *loop-macro-environment* *loop-universe*) (let ((*loop-original-source-code* *loop-source-code*) (*loop-source-context* nil) (*loop-iteration-variables* nil) (*loop-variables* nil) (*loop-nodeclare* nil) (*loop-named-variables* nil) (*loop-declarations* nil) (*loop-desetq-crocks* nil) (*loop-bind-stack* nil) (*loop-prologue* nil) (*loop-wrappers* nil) (*loop-before-loop* nil) (*loop-body* nil) (*loop-emitted-body* nil) (*loop-after-body* nil) (*loop-epilogue* nil) (*loop-after-epilogue* nil) (*loop-final-value-culprit* nil) (*loop-inside-conditional* nil) (*loop-when-it-variable* nil) (*loop-never-stepped-variable* nil) (*loop-names* nil) (*loop-collection-cruft* nil)) (loop-iteration-driver) (loop-bind-block) (let ((answer `(loop-body ,(nreverse *loop-prologue*) ,(nreverse *loop-before-loop*) ,(nreverse *loop-body*) ,(nreverse *loop-after-body*) ,(nreconc *loop-epilogue* (nreverse *loop-after-epilogue*))))) (dolist (entry *loop-bind-stack*) (let ((vars (first entry)) (dcls (second entry)) (crocks (third entry)) (wrappers (fourth entry))) (dolist (w wrappers) (setq answer (append w (list answer)))) (when (or vars dcls crocks) (let ((forms (list answer))) ;;(when crocks (push crocks forms)) (when dcls (push `(declare ,@dcls) forms)) (setq answer `(,(cond ((not vars) 'locally) (*loop-destructuring-hooks* (first *loop-destructuring-hooks*)) (t 'let)) ,vars ,@(loop-build-destructuring-bindings crocks forms))))))) (if *loop-names* (do () ((null (car *loop-names*)) answer) (setq answer `(block ,(pop *loop-names*) ,answer))) `(block nil ,answer))))) (defun loop-iteration-driver () (do () ((null *loop-source-code*)) (let ((keyword (car *loop-source-code*)) (tem nil)) (cond ((not (symbolp keyword)) (loop-error "~S found where LOOP keyword expected." keyword)) (t (setq *loop-source-context* *loop-source-code*) (loop-pop-source) (cond ((setq tem (loop-lookup-keyword keyword (loop-universe-keywords *loop-universe*))) ;;It's a "miscellaneous" toplevel LOOP keyword (do, collect, named, etc.) (apply (symbol-function (first tem)) (rest tem))) ((setq tem (loop-lookup-keyword keyword (loop-universe-iteration-keywords *loop-universe*))) (loop-hack-iteration tem)) ((loop-tmember keyword '(and else)) ;; Alternative is to ignore it, ie let it go around to the next keyword... (loop-error "Secondary clause misplaced at top level in LOOP macro: ~S ~S ~S ..." keyword (car *loop-source-code*) (cadr *loop-source-code*))) (t (loop-error "~S is an unknown keyword in LOOP macro." keyword)))))))) (defun loop-pop-source () (if *loop-source-code* (pop *loop-source-code*) (loop-error "LOOP source code ran out when another token was expected."))) (defun loop-get-compound-form () (let ((form (loop-get-form))) (unless (consp form) (loop-error "Compound form expected, but found ~A." form)) form)) (defun loop-get-progn () (do ((forms (list (loop-get-compound-form)) (cons (loop-get-compound-form) forms)) (nextform (car *loop-source-code*) (car *loop-source-code*))) ((atom nextform) (if (null (cdr forms)) (car forms) (cons 'progn (nreverse forms)))))) (defun loop-get-form () (if *loop-source-code* (loop-pop-source) (loop-error "LOOP code ran out where a form was expected."))) (defun loop-construct-return (form) `(return-from ,(car *loop-names*) ,form)) (defun loop-pseudo-body (form) (cond ((or *loop-emitted-body* *loop-inside-conditional*) (push form *loop-body*)) (t (push form *loop-before-loop*) (push form *loop-after-body*)))) (defun loop-emit-body (form) (setq *loop-emitted-body* t) (loop-pseudo-body form)) (defun loop-emit-final-value (&optional (form nil form-supplied-p)) (when form-supplied-p (push (loop-construct-return form) *loop-after-epilogue*)) (when *loop-final-value-culprit* (loop-warn "LOOP clause is providing a value for the iteration,~@ however one was already established by a ~S clause." *loop-final-value-culprit*)) (setq *loop-final-value-culprit* (car *loop-source-context*))) (defun loop-disallow-conditional (&optional kwd) #+(or Genera CLOE) (declare (dbg:error-reporter)) (when *loop-inside-conditional* (loop-error "~:[This LOOP~;The LOOP ~:*~S~] clause is not permitted inside a conditional." kwd))) (defun loop-disallow-anonymous-collectors () (when (find-if-not 'loop-collector-name *loop-collection-cruft*) (loop-error "This LOOP clause is not permitted with anonymous collectors."))) (defun loop-disallow-aggregate-booleans () (when (loop-tmember *loop-final-value-culprit* '(always never thereis)) (loop-error "This anonymous collection LOOP clause is not permitted with aggregate booleans."))) ;;;; Loop Types (defun loop-typed-init (data-type) (when (and data-type (subtypep data-type 'number)) (if (or (subtypep data-type 'float) (subtypep data-type '(complex float))) (coerce 0 data-type) 0))) (defun loop-optional-type (&optional variable) ;;No variable specified implies that no destructuring is permissible. (and *loop-source-code* ;Don't get confused by NILs... (let ((z (car *loop-source-code*))) (cond ((loop-tequal z 'of-type) ;;This is the syntactically unambigous form in that the form of the ;; type specifier does not matter. Also, it is assumed that the ;; type specifier is unambiguously, and without need of translation, ;; a common lisp type specifier or pattern (matching the variable) thereof. (loop-pop-source) (loop-pop-source)) ((symbolp z) ;;This is the (sort of) "old" syntax, even though we didn't used to support all of ;; these type symbols. (let ((type-spec (or (gethash z (loop-universe-type-symbols *loop-universe*)) (gethash (symbol-name z) (loop-universe-type-keywords *loop-universe*))))) (when type-spec (loop-pop-source) type-spec))) (t ;;This is our sort-of old syntax. But this is only valid for when we are destructuring, ;; so we will be compulsive (should we really be?) and require that we in fact be ;; doing variable destructuring here. We must translate the old keyword pattern typespec ;; into a fully-specified pattern of real type specifiers here. (if (consp variable) (unless (consp z) (loop-error "~S found where a LOOP keyword, LOOP type keyword, or LOOP type pattern expected." z)) (loop-error "~S found where a LOOP keyword or LOOP type keyword expected." z)) (loop-pop-source) (labels ((translate (k v) (cond ((null k) nil) ((atom k) (replicate (or (gethash k (loop-universe-type-symbols *loop-universe*)) (gethash (symbol-name k) (loop-universe-type-keywords *loop-universe*)) (loop-error "Destructuring type pattern ~S contains unrecognized type keyword ~S." z k)) v)) ((atom v) (loop-error "Destructuring type pattern ~S doesn't match variable pattern ~S." z variable)) (t (cons (translate (car k) (car v)) (translate (cdr k) (cdr v)))))) (replicate (typ v) (if (atom v) typ (cons (replicate typ (car v)) (replicate typ (cdr v)))))) (translate z variable))))))) ;;;; Loop Variables (defun loop-bind-block () (when (or *loop-variables* *loop-declarations* *loop-wrappers*) (push (list (nreverse *loop-variables*) *loop-declarations* *loop-desetq-crocks* *loop-wrappers*) *loop-bind-stack*) (setq *loop-variables* nil *loop-declarations* nil *loop-desetq-crocks* nil *loop-wrappers* nil))) (defun loop-variable-p (name) (do ((entry *loop-bind-stack* (cdr entry))) (nil) (cond ((null entry) (return nil)) ((assoc name (caar entry) :test #'eq) (return t))))) (defun loop-make-variable (name initialization dtype &optional iteration-variable-p) (cond ((null name) (cond ((not (null initialization)) (push (list (setq name (loop-gentemp 'loop-ignore-)) initialization) *loop-variables*) (push `(ignore ,name) *loop-declarations*)))) ((atom name) (cond (iteration-variable-p (if (member name *loop-iteration-variables*) (loop-error "Duplicated LOOP iteration variable ~S." name) (push name *loop-iteration-variables*))) ((assoc name *loop-variables*) (loop-error "Duplicated variable ~S in LOOP parallel binding." name))) (unless (symbolp name) (loop-error "Bad variable ~S somewhere in LOOP." name)) (loop-declare-variable name dtype) ;; We use ASSOC on this list to check for duplications (above), ;; so don't optimize out this list: (push (list name (or initialization (loop-typed-init dtype))) *loop-variables*)) (initialization (cond (*loop-destructuring-hooks* (loop-declare-variable name dtype) (push (list name initialization) *loop-variables*)) (t (let ((newvar (loop-gentemp 'loop-destructure-))) (loop-declare-variable name dtype) (push (list newvar initialization) *loop-variables*) ;; *LOOP-DESETQ-CROCKS* gathered in reverse order. (setq *loop-desetq-crocks* (list* name newvar *loop-desetq-crocks*)) #+ignore (loop-make-variable name nil dtype iteration-variable-p))))) (t (let ((tcar nil) (tcdr nil)) (if (atom dtype) (setq tcar (setq tcdr dtype)) (setq tcar (car dtype) tcdr (cdr dtype))) (loop-make-variable (car name) nil tcar iteration-variable-p) (loop-make-variable (cdr name) nil tcdr iteration-variable-p)))) name) (defun loop-make-iteration-variable (name initialization dtype) (when (and name (loop-variable-p name)) (loop-error "Variable ~S has already been used" name)) (loop-make-variable name initialization dtype t)) (defun loop-declare-variable (name dtype) (cond ((or (null name) (null dtype) (eq dtype t)) nil) ((symbolp name) (unless (or (eq dtype t) (member (the symbol name) *loop-nodeclare*)) (let ((dtype (let ((init (loop-typed-init dtype))) (if (typep init dtype) dtype `(or (member ,init) ,dtype))))) (push `(type ,dtype ,name) *loop-declarations*)))) ((consp name) (cond ((consp dtype) (loop-declare-variable (car name) (car dtype)) (loop-declare-variable (cdr name) (cdr dtype))) (t (loop-declare-variable (car name) dtype) (loop-declare-variable (cdr name) dtype)))) (t (error "Invalid LOOP variable passed in: ~S." name)))) (defun loop-maybe-bind-form (form data-type) (if (loop-constantp form) form (loop-make-variable (loop-gentemp 'loop-bind-) form data-type))) (defun loop-do-if (for negatep) (let ((form (loop-get-form)) (it-p nil) (first-clause-p t) then else) (let ((*loop-inside-conditional* t)) (flet ((get-clause (for) (do ((body nil)) (nil) (let ((key (car *loop-source-code*)) (*loop-body* nil) data) (cond ((not (symbolp key)) (loop-error "~S found where keyword expected getting LOOP clause after ~S." key for)) (t (setq *loop-source-context* *loop-source-code*) (loop-pop-source) (when (and (loop-tequal (car *loop-source-code*) 'it) first-clause-p) (setq *loop-source-code* (cons (or it-p (setq it-p (loop-when-it-variable))) (cdr *loop-source-code*)))) (cond ((or (not (setq data (loop-lookup-keyword key (loop-universe-keywords *loop-universe*)))) (progn (apply (symbol-function (car data)) (cdr data)) (null *loop-body*))) (loop-error "~S does not introduce a LOOP clause that can follow ~S." key for)) (t (setq body (nreconc *loop-body* body))))))) (setq first-clause-p nil) (if (loop-tequal (car *loop-source-code*) :and) (loop-pop-source) (return (if (cdr body) `(progn ,@(nreverse body)) (car body))))))) (setq then (get-clause for)) (setq else (when (loop-tequal (car *loop-source-code*) :else) (loop-pop-source) (list (get-clause :else))))) (when (loop-tequal (car *loop-source-code*) :end) (loop-pop-source)) (when it-p (setq form `(setq ,it-p ,form)))) (loop-pseudo-body `(if ,(if negatep `(not ,form) form) ,then ,@else)))) (defun loop-do-initially () (loop-disallow-conditional :initially) (push (loop-get-progn) *loop-prologue*)) (defun loop-do-finally () (loop-disallow-conditional :finally) (push (loop-get-progn) *loop-epilogue*)) (defun loop-do-do () (loop-emit-body (loop-get-progn))) (defun loop-do-named () (let ((name (loop-pop-source))) (unless (symbolp name) (loop-error "~S is an invalid name for your LOOP." name)) (when (or *loop-before-loop* *loop-body* *loop-after-epilogue* *loop-inside-conditional*) (loop-error "The NAMED ~S clause occurs too late." name)) (when *loop-names* (loop-error "You may only use one NAMED clause in your loop: NAMED ~S ... NAMED ~S." (car *loop-names*) name)) (setq *loop-names* (list name nil)))) (defun loop-do-return () (loop-pseudo-body (loop-construct-return (loop-get-form)))) ;;;; Value Accumulation: List (defstruct (loop-collector (:copier nil) (:predicate nil)) name class (history nil) (tempvars nil) dtype (data nil)) ;collector-specific data (defun loop-get-collection-info (collector class default-type) (let ((form (loop-get-form)) (dtype (and (not (loop-universe-ansi *loop-universe*)) (loop-optional-type))) (name (when (loop-tequal (car *loop-source-code*) 'into) (loop-pop-source) (loop-pop-source)))) (when (not (symbolp name)) (loop-error "Value accumulation recipient name, ~S, is not a symbol." name)) (unless name (loop-disallow-aggregate-booleans)) (unless dtype (setq dtype (or (loop-optional-type) default-type))) (let ((cruft (find (the symbol name) *loop-collection-cruft* :key #'loop-collector-name))) (cond ((not cruft) (when (and name (loop-variable-p name)) (loop-error "Variable ~S cannot be used in INTO clause" name)) (push (setq cruft (make-loop-collector :name name :class class :history (list collector) :dtype dtype)) *loop-collection-cruft*)) (t (unless (eq (loop-collector-class cruft) class) (loop-error "Incompatible kinds of LOOP value accumulation specified for collecting~@ ~:[as the value of the LOOP~;~:*INTO ~S~]: ~S and ~S." name (car (loop-collector-history cruft)) collector)) (unless (equal dtype (loop-collector-dtype cruft)) (loop-warn "Unequal datatypes specified in different LOOP value accumulations~@ into ~S: ~S and ~S." name dtype (loop-collector-dtype cruft)) (when (eq (loop-collector-dtype cruft) t) (setf (loop-collector-dtype cruft) dtype))) (push collector (loop-collector-history cruft)))) (values cruft form)))) (defun loop-list-collection (specifically) ;NCONC, LIST, or APPEND (multiple-value-bind (lc form) (loop-get-collection-info specifically 'list 'list) (let ((tempvars (loop-collector-tempvars lc))) (unless tempvars (setf (loop-collector-tempvars lc) (setq tempvars (list* (loop-gentemp 'loop-list-head-) (loop-gentemp 'loop-list-tail-) (and (loop-collector-name lc) (list (loop-collector-name lc)))))) (push `(with-loop-list-collection-head ,tempvars) *loop-wrappers*) (unless (loop-collector-name lc) (loop-emit-final-value `(loop-collect-answer ,(car tempvars) ,@(cddr tempvars))))) (ecase specifically (list (setq form `(list ,form))) (nconc nil) (append (unless (and (consp form) (eq (car form) 'list)) (setq form `(loop-copylist* ,form))))) (loop-emit-body `(loop-collect-rplacd ,tempvars ,form))))) ;;;; Value Accumulation: max, min, sum, count. (defun loop-sum-collection (specifically required-type default-type) ;SUM, COUNT (multiple-value-bind (lc form) (loop-get-collection-info specifically 'sum default-type) (loop-check-data-type (loop-collector-dtype lc) required-type) (let ((tempvars (loop-collector-tempvars lc))) (unless tempvars (setf (loop-collector-tempvars lc) (setq tempvars (list (loop-make-variable (or (loop-collector-name lc) (loop-gentemp 'loop-sum-)) nil (loop-collector-dtype lc))))) (unless (loop-collector-name lc) (loop-emit-final-value (car (loop-collector-tempvars lc))))) (loop-emit-body (if (eq specifically 'count) `(when ,form (setq ,(car tempvars) ,(hide-variable-reference t (car tempvars) `(1+ ,(car tempvars))))) `(setq ,(car tempvars) (+ ,(hide-variable-reference t (car tempvars) (car tempvars)) ,form))))))) (defun loop-maxmin-collection (specifically) (multiple-value-bind (lc form) (loop-get-collection-info specifically 'maxmin *loop-real-data-type*) (loop-check-data-type (loop-collector-dtype lc) *loop-real-data-type*) (let ((data (loop-collector-data lc))) (unless data (setf (loop-collector-data lc) (setq data (make-loop-minimax (or (loop-collector-name lc) (loop-gentemp 'loop-maxmin-)) (loop-collector-dtype lc)))) (unless (loop-collector-name lc) (loop-emit-final-value (loop-minimax-answer-variable data)))) (loop-note-minimax-operation specifically data) (push `(with-minimax-value ,data) *loop-wrappers*) (loop-emit-body `(loop-accumulate-minimax-value ,data ,specifically ,form)) ))) ;;;; Value Accumulation: Aggregate Booleans ;;;ALWAYS and NEVER. ;;; Under ANSI these are not permitted to appear under conditionalization. (defun loop-do-always (restrictive negate) (let ((form (loop-get-form))) (when restrictive (loop-disallow-conditional)) (loop-disallow-anonymous-collectors) (loop-emit-body `(,(if negate 'when 'unless) ,form ,(loop-construct-return nil))) (loop-emit-final-value t))) ;;;THERIS. ;;; Under ANSI this is not permitted to appear under conditionalization. (defun loop-do-thereis (restrictive) (when restrictive (loop-disallow-conditional)) (loop-disallow-anonymous-collectors) (loop-emit-final-value) (loop-emit-body `(when (setq ,(loop-when-it-variable) ,(loop-get-form)) ,(loop-construct-return *loop-when-it-variable*)))) (defun loop-do-while (negate kwd &aux (form (loop-get-form))) (loop-disallow-conditional kwd) (loop-pseudo-body `(,(if negate 'when 'unless) ,form (go end-loop)))) (defun loop-do-with () (loop-disallow-conditional :with) (do ((var) (val) (dtype)) (nil) (setq var (loop-pop-source) dtype (loop-optional-type var) val (cond ((loop-tequal (car *loop-source-code*) :=) (loop-pop-source) (loop-get-form)) (t nil))) (when (and var (loop-variable-p var)) (loop-error "Variable ~S has already been used" var)) (loop-make-variable var val dtype) (if (loop-tequal (car *loop-source-code*) :and) (loop-pop-source) (return (loop-bind-block))))) ;;;; The iteration driver (defun loop-hack-iteration (entry) (flet ((make-endtest (list-of-forms) (cond ((null list-of-forms) nil) ((member t list-of-forms) '(go end-loop)) (t `(when ,(if (null (cdr (setq list-of-forms (nreverse list-of-forms)))) (car list-of-forms) (cons 'or list-of-forms)) (go end-loop)))))) (do ((pre-step-tests nil) (steps nil) (post-step-tests nil) (pseudo-steps nil) (pre-loop-pre-step-tests nil) (pre-loop-steps nil) (pre-loop-post-step-tests nil) (pre-loop-pseudo-steps nil) (tem) (data)) (nil) ;; Note we collect endtests in reverse order, but steps in correct ;; order. MAKE-ENDTEST does the nreverse for us. (setq tem (setq data (apply (symbol-function (first entry)) (rest entry)))) (and (car tem) (push (car tem) pre-step-tests)) (setq steps (nconc steps (loop-copylist* (car (setq tem (cdr tem)))))) (and (car (setq tem (cdr tem))) (push (car tem) post-step-tests)) (setq pseudo-steps (nconc pseudo-steps (loop-copylist* (car (setq tem (cdr tem)))))) (setq tem (cdr tem)) (when *loop-emitted-body* (loop-error "Iteration in LOOP follows body code.")) (unless tem (setq tem data)) (when (car tem) (push (car tem) pre-loop-pre-step-tests)) (setq pre-loop-steps (nconc pre-loop-steps (loop-copylist* (car (setq tem (cdr tem)))))) (when (car (setq tem (cdr tem))) (push (car tem) pre-loop-post-step-tests)) (setq pre-loop-pseudo-steps (nconc pre-loop-pseudo-steps (loop-copylist* (cadr tem)))) (unless (loop-tequal (car *loop-source-code*) :and) (setq *loop-before-loop* (list* (loop-make-desetq pre-loop-pseudo-steps) (make-endtest pre-loop-post-step-tests) (loop-make-psetq pre-loop-steps) (make-endtest pre-loop-pre-step-tests) *loop-before-loop*) *loop-after-body* (list* (loop-make-desetq pseudo-steps) (make-endtest post-step-tests) (loop-make-psetq steps) (make-endtest pre-step-tests) *loop-after-body*)) (loop-bind-block) (return nil)) (loop-pop-source) ; flush the "AND" (when (and (not (loop-universe-implicit-for-required *loop-universe*)) (setq tem (loop-lookup-keyword (car *loop-source-code*) (loop-universe-iteration-keywords *loop-universe*)))) ;;Latest ANSI clarification is that the FOR/AS after the AND must NOT be supplied. (loop-pop-source) (setq entry tem))))) ;;;; Main Iteration Drivers ;FOR variable keyword ..args.. (defun loop-do-for () (let* ((var (or (loop-pop-source) (loop-gentemp 'loop-do-for-anon-))) (data-type (loop-optional-type var)) (keyword (loop-pop-source)) (first-arg nil) (tem nil)) (setq first-arg (loop-get-form)) (unless (and (symbolp keyword) (setq tem (loop-lookup-keyword keyword (loop-universe-for-keywords *loop-universe*)))) (loop-error "~S is an unknown keyword in FOR or AS clause in LOOP." keyword)) (apply (car tem) var first-arg data-type (cdr tem)))) (defun loop-do-repeat () (loop-disallow-conditional :repeat) (let ((form (loop-get-form)) (type 'real)) (let ((var (loop-make-variable (loop-gentemp) form type))) (push `(when (minusp (decf ,var)) (go end-loop)) *loop-before-loop*) (push `(when (minusp (decf ,var)) (go end-loop)) *loop-after-body*) ;; FIXME: What should ;; (loop count t into a ;; repeat 3 ;; count t into b ;; finally (return (list a b))) ;; return: (3 3) or (4 3)? PUSHes above are for the former ;; variant, L-P-B below for the latter. #+nil (loop-pseudo-body `(when (minusp (decf ,var)) (go end-loop)))))) (defun loop-when-it-variable () (or *loop-when-it-variable* (setq *loop-when-it-variable* (loop-make-variable (loop-gentemp 'loop-it-) nil nil)))) ;;;; Various FOR/AS Subdispatches ;;;ANSI "FOR x = y [THEN z]" is sort of like the old Genera one when the THEN ;;; is omitted (other than being more stringent in its placement), and like ;;; the old "FOR x FIRST y THEN z" when the THEN is present. I.e., the first ;;; initialization occurs in the loop body (first-step), not in the variable binding ;;; phase. (defun loop-ansi-for-equals (var val data-type) (loop-make-iteration-variable var nil data-type) (cond ((loop-tequal (car *loop-source-code*) :then) ;;Then we are the same as "FOR x FIRST y THEN z". (loop-pop-source) `(() (,var ,(loop-get-form)) () () () (,var ,val) () ())) (t ;;We are the same as "FOR x = y". ;; Let me document here what this is returning. Look at ;; loop-hack-iteration for more info. But anyway, we return a list of ;; 8 items, in this order: PRE-STEP-TESTS, STEPS, POST-STEP-TESTS, ;; PSEUDO-STEPS, PRE-LOOP-PRE-STEP-TESTS, PRE-LOOP-STEPS, ;; PRE-LOOP-POST-STEP-TESTS, PRE-LOOP-PSEUDO-STEPS. (We should add ;; something to make it easier to figure out what these args are!) ;; ;; For a "FOR x = y" clause without the THEN, we want the STEPS item to ;; step the variable VAR with the value VAL. This gets placed in the ;; body of the loop. The original code just did that. It seems that ;; the STEPS form is placed in *loop-before-loop* and in ;; *loop-after-loop*. Loop optimization would then see the same form ;; in both, and move them into the beginning of body. This is ok, ;; except that if there are :initially forms that were placed into the ;; loop prologue, the :initially forms might refer to incorrectly ;; initialized variables, because the optimizer moved STEPS from from ;; *loop-before-loop* into the body. ;; ;; To solve this, we add a PRE-LOOP-PSEUDO-STEP form that is identical ;; to the STEPS form. This gets placed in *loop-before-loop*. But ;; this won't match any *loop-after-loop* form, so it won't get moved, ;; and we maintain the proper sequencing such that the ;; PRE-LOOP-PSEUDO-STEP form is in *loop-before-loop*, before any ;; :initially clauses that might refer to this. So all is well. Whew. ;; ;; I hope this doesn't break anything else. `(() (,var ,val) () () () () () (,var ,val)) ))) (defun loop-for-across (var val data-type) (loop-make-iteration-variable var nil data-type) (let ((vector-var (loop-gentemp 'loop-across-vector-)) (index-var (loop-gentemp 'loop-across-index-))) (multiple-value-bind (vector-form constantp vector-value) (loop-constant-fold-if-possible val 'vector) (loop-make-variable vector-var vector-form (if (and (consp vector-form) (eq (car vector-form) 'the)) (cadr vector-form) 'vector)) #+Genera (push `(system:array-register ,vector-var) *loop-declarations*) (loop-make-variable index-var 0 'fixnum) (let* ((length 0) (length-form (cond ((not constantp) (let ((v (loop-gentemp 'loop-across-limit-))) ;; This used to just push the length ;; computation into the prologue code. I ;; (rtoy) don't think that's right, ;; especially since the prologue is supposed ;; to happen AFTER other initializations. ;; So, this puts the computation in ;; *loop-before-body*. We need a matching ;; entry for *loop-after-body*, so stuff a ;; NIL there. (push `(setq ,v (length ,vector-var)) *loop-before-loop*) (push nil *loop-after-body*) (loop-make-variable v 0 'fixnum))) (t (setq length (length vector-value))))) (first-test `(>= ,index-var ,length-form)) (other-test first-test) (step `(,var (aref ,vector-var ,index-var))) (pstep `(,index-var (1+ ,index-var)))) (declare (fixnum length)) (when constantp (setq first-test (= length 0)) (when (<= length 1) (setq other-test t))) `(,other-test ,step () ,pstep ,@(and (not (eq first-test other-test)) `(,first-test ,step () ,pstep))))))) ;;;; List Iteration (defun loop-list-step (listvar) ;;We are not equipped to analyze whether 'FOO is the same as #'FOO here in any ;; sensible fashion, so let's give an obnoxious warning whenever 'FOO is used ;; as the stepping function. ;;While a Discerning Compiler may deal intelligently with (funcall 'foo ...), not ;; recognizing FOO may defeat some LOOP optimizations. (let ((stepper (cond ((loop-tequal (car *loop-source-code*) :by) (loop-pop-source) (loop-get-form)) (t '(function cdr))))) (cond ((and (consp stepper) (eq (car stepper) 'quote)) (loop-warn "Use of QUOTE around stepping function in LOOP will be left verbatim.") (values `(funcall ,stepper ,listvar) nil)) ((and (consp stepper) (eq (car stepper) 'function)) (values (list (cadr stepper) listvar) (cadr stepper))) (t (values `(funcall ,(loop-make-variable (loop-gentemp 'loop-fn-) stepper 'function) ,listvar) nil))))) (defun loop-for-on (var val data-type) (multiple-value-bind (list constantp list-value) (loop-constant-fold-if-possible val) (let ((listvar var)) (cond ((and var (symbolp var)) (loop-make-iteration-variable var list data-type)) (t (loop-make-variable (setq listvar (loop-gentemp)) list 't) (loop-make-iteration-variable var nil data-type))) (multiple-value-bind (list-step step-function) (loop-list-step listvar) (declare #+(and (not LOOP-Prefer-POP) (not CLOE)) (ignore step-function)) ;;@@@@ The CLOE problem above has to do with bug in macroexpansion of multiple-value-bind. (let* ((first-endtest (hide-variable-reference (eq var listvar) listvar ;; the following should use `atom' instead of `endp', per ;; [bug2428] `(atom ,listvar))) (other-endtest first-endtest)) (when (and constantp (listp list-value)) (setq first-endtest (null list-value))) (cond ((eq var listvar) ;;Contour of the loop is different because we use the user's variable... `(() (,listvar ,(hide-variable-reference t listvar list-step)) ,other-endtest () () () ,first-endtest ())) #+LOOP-Prefer-POP ((and step-function (let ((n (cdr (assoc step-function '((cdr . 1) (cddr . 2) (cdddr . 3) (cddddr . 4)))))) (and n (do ((l var (cdr l)) (i 0 (1+ i))) ((atom l) (and (null l) (= i n))) (declare (fixnum i)))))) (let ((step (mapcan #'(lambda (x) (list x `(pop ,listvar))) var))) `(,other-endtest () () ,step ,first-endtest () () ,step))) (t (let ((step `(,var ,listvar)) (pseudo `(,listvar ,list-step))) `(,other-endtest ,step () ,pseudo ,@(and (not (eq first-endtest other-endtest)) `(,first-endtest ,step () ,pseudo))))))))))) (defun loop-for-in (var val data-type) (multiple-value-bind (list constantp list-value) (loop-constant-fold-if-possible val) (let ((listvar (loop-gentemp 'loop-list-))) (loop-make-iteration-variable var nil data-type) (loop-make-variable listvar list 'list) (multiple-value-bind (list-step step-function) (loop-list-step listvar) #-LOOP-Prefer-POP (declare (ignore step-function)) (let* ((first-endtest `(endp ,listvar)) (other-endtest first-endtest) (step `(,var (car ,listvar))) (pseudo-step `(,listvar ,list-step))) (when (and constantp (listp list-value)) (setq first-endtest (null list-value))) #+LOOP-Prefer-POP (when (eq step-function 'cdr) (setq step `(,var (pop ,listvar)) pseudo-step nil)) `(,other-endtest ,step () ,pseudo-step ,@(and (not (eq first-endtest other-endtest)) `(,first-endtest ,step () ,pseudo-step)))))))) ;;;; Iteration Paths (defstruct (loop-path (:copier nil) (:predicate nil)) names preposition-groups inclusive-permitted function user-data) (eval-when (:compile-toplevel :load-toplevel :execute) (defun add-loop-path (names function universe &key preposition-groups inclusive-permitted user-data) (unless (listp names) (setq names (list names))) ;; Can't do this due to CLOS bootstrapping problems. #-(or Genera (and CLOE Source-Bootstrap)) (check-type universe loop-universe) (let ((ht (loop-universe-path-keywords universe)) (lp (make-loop-path :names (mapcar #'symbol-name names) :function function :user-data user-data :preposition-groups (mapcar #'(lambda (x) (if (listp x) x (list x))) preposition-groups) :inclusive-permitted inclusive-permitted))) (dolist (name names) (setf (gethash (symbol-name name) ht) lp)) lp))) ;;; Note: path functions are allowed to use loop-make-variable, hack ;;; the prologue, etc. (defun loop-for-being (var val data-type) ;; FOR var BEING each/the pathname prep-phrases using-stuff... ;; each/the = EACH or THE. Not clear if it is optional, so I guess we'll warn. (let ((path nil) (data nil) (inclusive nil) (stuff nil) (initial-prepositions nil)) (cond ((loop-tmember val '(:each :the)) (setq path (loop-pop-source))) ((loop-tequal (car *loop-source-code*) :and) (loop-pop-source) (setq inclusive t) (unless (loop-tmember (car *loop-source-code*) '(:its :each :his :her)) (loop-error "~S found where ITS or EACH expected in LOOP iteration path syntax." (car *loop-source-code*))) (loop-pop-source) (setq path (loop-pop-source)) (setq initial-prepositions `((:in ,val)))) (t (loop-error "Unrecognizable LOOP iteration path syntax. Missing EACH or THE?"))) (cond ((not (symbolp path)) (loop-error "~S found where a LOOP iteration path name was expected." path)) ((not (setq data (loop-lookup-keyword path (loop-universe-path-keywords *loop-universe*)))) (loop-error "~S is not the name of a LOOP iteration path." path)) ((and inclusive (not (loop-path-inclusive-permitted data))) (loop-error "\"Inclusive\" iteration is not possible with the ~S LOOP iteration path." path))) (let ((fun (loop-path-function data)) (preps (nconc initial-prepositions (loop-collect-prepositional-phrases (loop-path-preposition-groups data) t))) (user-data (loop-path-user-data data))) (when (symbolp fun) (setq fun (symbol-function fun))) (setq stuff (if inclusive (apply fun var data-type preps :inclusive t user-data) (apply fun var data-type preps user-data)))) (when *loop-named-variables* (loop-error "Unused USING variables: ~S." *loop-named-variables*)) ;; STUFF is now (bindings prologue-forms . stuff-to-pass-back). Protect the system from the user ;; and the user from himself. (unless (member (length stuff) '(6 10)) (loop-error "Value passed back by LOOP iteration path function for path ~S has invalid length." path)) (do ((l (car stuff) (cdr l)) (x)) ((null l)) (if (atom (setq x (car l))) (loop-make-iteration-variable x nil nil) (loop-make-iteration-variable (car x) (cadr x) (caddr x)))) (setq *loop-prologue* (nconc (reverse (cadr stuff)) *loop-prologue*)) (cddr stuff))) ;;;INTERFACE: Lucid, exported. ;;; i.e., this is part of our extended ansi-loop interface. (defun named-variable (name) (let ((tem (loop-tassoc name *loop-named-variables*))) (declare (list tem)) (cond ((null tem) (values (loop-gentemp) nil)) (t (setq *loop-named-variables* (delete tem *loop-named-variables*)) (values (cdr tem) t))))) (defun loop-collect-prepositional-phrases (preposition-groups &optional USING-allowed initial-phrases) (flet ((in-group-p (x group) (car (loop-tmember x group)))) (do ((token nil) (prepositional-phrases initial-phrases) (this-group nil nil) (this-prep nil nil) (disallowed-prepositions (mapcan #'(lambda (x) (loop-copylist* (find (car x) preposition-groups :test #'in-group-p))) initial-phrases)) (used-prepositions (mapcar #'car initial-phrases))) ((null *loop-source-code*) (nreverse prepositional-phrases)) (declare (symbol this-prep)) (setq token (car *loop-source-code*)) (dolist (group preposition-groups) (when (setq this-prep (in-group-p token group)) (return (setq this-group group)))) (cond (this-group (when (member this-prep disallowed-prepositions) (loop-error (if (member this-prep used-prepositions) "A ~S prepositional phrase occurs multiply for some LOOP clause." "Preposition ~S used when some other preposition has subsumed it.") token)) (setq used-prepositions (if (listp this-group) (append this-group used-prepositions) (cons this-group used-prepositions))) (loop-pop-source) (push (list this-prep (loop-get-form)) prepositional-phrases)) ((and USING-allowed (loop-tequal token 'using)) (loop-pop-source) (do ((z (loop-pop-source) (loop-pop-source)) (tem)) (nil) (when (cadr z) (if (setq tem (loop-tassoc (car z) *loop-named-variables*)) (loop-error "The variable substitution for ~S occurs twice in a USING phrase,~@ with ~S and ~S." (car z) (cadr z) (cadr tem)) (push (cons (car z) (cadr z)) *loop-named-variables*))) (when (or (null *loop-source-code*) (symbolp (car *loop-source-code*))) (return nil)))) (t (return (nreverse prepositional-phrases))))))) ;;;; Master Sequencer Function (defun loop-sequencer (indexv indexv-type indexv-user-specified-p variable variable-type sequence-variable sequence-type step-hack default-top prep-phrases) (let ((endform nil) ;Form (constant or variable) with limit value. (sequencep nil) ;T if sequence arg has been provided. (testfn nil) ;endtest function (test nil) ;endtest form. (stepby (1+ (or (loop-typed-init indexv-type) 0))) ;Our increment. (stepby-constantp t) (step nil) ;step form. (dir nil) ;Direction of stepping: NIL, :UP, :DOWN. (inclusive-iteration nil) ;T if include last index. (start-given nil) ;T when prep phrase has specified start (start-value nil) (start-constantp nil) (limit-given nil) ;T when prep phrase has specified end (limit-constantp nil) (limit-value nil) ) (when variable (loop-make-iteration-variable variable nil variable-type)) (do ((l prep-phrases (cdr l)) (prep) (form) (odir)) ((null l)) (setq prep (caar l) form (cadar l)) (case prep ((:of :in) (setq sequencep t) (loop-make-variable sequence-variable form sequence-type)) ((:from :downfrom :upfrom) (setq start-given t) (cond ((eq prep :downfrom) (setq dir ':down)) ((eq prep :upfrom) (setq dir ':up))) (multiple-value-setq (form start-constantp start-value) (loop-constant-fold-if-possible form indexv-type)) (loop-make-iteration-variable indexv form indexv-type)) ((:upto :to :downto :above :below) (cond ((loop-tequal prep :upto) (setq inclusive-iteration (setq dir ':up))) ((loop-tequal prep :to) (setq inclusive-iteration t)) ((loop-tequal prep :downto) (setq inclusive-iteration (setq dir ':down))) ((loop-tequal prep :above) (setq dir ':down)) ((loop-tequal prep :below) (setq dir ':up))) (setq limit-given t) (multiple-value-setq (form limit-constantp limit-value) (loop-constant-fold-if-possible form indexv-type)) (setq endform (if limit-constantp `',limit-value (loop-make-variable (loop-gentemp 'loop-limit-) form indexv-type)))) (:by (multiple-value-setq (form stepby-constantp stepby) (loop-constant-fold-if-possible form indexv-type)) (unless stepby-constantp (loop-make-variable (setq stepby (loop-gentemp 'loop-step-by-)) form indexv-type))) (t (loop-error "~S invalid preposition in sequencing or sequence path.~@ Invalid prepositions specified in iteration path descriptor or something?" prep))) (when (and odir dir (not (eq dir odir))) (loop-error "Conflicting stepping directions in LOOP sequencing path")) (setq odir dir)) (when (and sequence-variable (not sequencep)) (loop-error "Missing OF or IN phrase in sequence path")) ;; Now fill in the defaults. (unless start-given (loop-make-iteration-variable indexv (setq start-constantp t start-value (or (loop-typed-init indexv-type) 0)) indexv-type)) (cond ((member dir '(nil :up)) (when (or limit-given default-top) (unless limit-given (loop-make-variable (setq endform (loop-gentemp 'loop-seq-limit-)) nil indexv-type) (push `(setq ,endform ,default-top) *loop-prologue*)) (setq testfn (if inclusive-iteration '> '>=))) (setq step (if (eql stepby 1) `(1+ ,indexv) `(+ ,indexv ,stepby)))) (t (unless start-given (unless default-top (loop-error "Don't know where to start stepping.")) (push `(setq ,indexv (1- ,default-top)) *loop-prologue*)) (when (and default-top (not endform)) (setq endform (loop-typed-init indexv-type) inclusive-iteration t)) (when endform (setq testfn (if inclusive-iteration '< '<=))) (setq step (if (eql stepby 1) `(1- ,indexv) `(- ,indexv ,stepby))))) (when testfn (setq test (hide-variable-reference t indexv `(,testfn ,indexv ,endform)))) (when step-hack (setq step-hack `(,variable ,(hide-variable-reference indexv-user-specified-p indexv step-hack)))) (let ((first-test test) (remaining-tests test)) (when (and stepby-constantp start-constantp limit-constantp) (when (setq first-test (funcall (symbol-function testfn) start-value limit-value)) (setq remaining-tests t))) `(() (,indexv ,(hide-variable-reference t indexv step)) ,remaining-tests ,step-hack () () ,first-test ,step-hack)))) ;;;; Interfaces to the Master Sequencer (defun loop-for-arithmetic (var val data-type kwd) (loop-sequencer var (loop-check-data-type data-type 'number) t nil nil nil nil nil nil (loop-collect-prepositional-phrases '((:from :upfrom :downfrom) (:to :upto :downto :above :below) (:by)) nil (list (list kwd val))))) (defun loop-sequence-elements-path (variable data-type prep-phrases &key fetch-function size-function sequence-type element-type) (multiple-value-bind (indexv indexv-user-specified-p) (named-variable 'index) (let ((sequencev (named-variable 'sequence))) #+Genera (when (and sequencev (symbolp sequencev) sequence-type (subtypep sequence-type 'vector) (not (member (the symbol sequencev) *loop-nodeclare*))) (push `(sys:array-register ,sequencev) *loop-declarations*)) (list* nil nil ; dummy bindings and prologue (loop-sequencer indexv 'fixnum indexv-user-specified-p variable (or data-type element-type) sequencev sequence-type `(,fetch-function ,sequencev ,indexv) `(,size-function ,sequencev) prep-phrases))))) ;;;; Builtin LOOP Iteration Paths #|| (loop for v being the hash-values of ht do (print v)) (loop for k being the hash-keys of ht do (print k)) (loop for v being the hash-values of ht using (hash-key k) do (print (list k v))) (loop for k being the hash-keys of ht using (hash-value v) do (print (list k v))) ||# (defun loop-hash-table-iteration-path (variable data-type prep-phrases &key which) (check-type which (member hash-key hash-value)) (cond ((or (cdr prep-phrases) (not (member (caar prep-phrases) '(:in :of)))) (loop-error "Too many prepositions!")) ((null prep-phrases) (loop-error "Missing OF or IN in ~S iteration path."))) (let ((ht-var (loop-gentemp 'loop-hashtab-)) (next-fn (loop-gentemp 'loop-hashtab-next-)) (dummy-predicate-var nil) (post-steps nil)) (multiple-value-bind (other-var other-p) (named-variable (if (eq which 'hash-key) 'hash-value 'hash-key)) ;;@@@@ named-variable returns a second value of T if the name was actually ;; specified, so clever code can throw away the gensym'ed up variable if ;; it isn't really needed. ;;The following is for those implementations in which we cannot put dummy NILs ;; into multiple-value-setq variable lists. #-Genera (setq other-p t dummy-predicate-var (loop-when-it-variable)) (let* ((key-var nil) (val-var nil) (temp-val-var (loop-gentemp 'loop-hash-val-temp-)) (temp-key-var (loop-gentemp 'loop-hash-key-temp-)) (temp-predicate-var (loop-gentemp 'loop-hash-predicate-var-)) (variable (or variable (loop-gentemp))) (bindings `((,variable nil ,data-type) (,ht-var ,(cadar prep-phrases)) ,@(and other-p other-var `((,other-var nil)))))) (if (eq which 'hash-key) (setq key-var variable val-var (and other-p other-var)) (setq key-var (and other-p other-var) val-var variable)) (push `(with-hash-table-iterator (,next-fn ,ht-var)) *loop-wrappers*) (when (consp key-var) (setq post-steps `(,key-var ,(setq key-var (loop-gentemp 'loop-hash-key-temp-)) ,@post-steps)) (push `(,key-var nil) bindings)) (when (consp val-var) (setq post-steps `(,val-var ,(setq val-var (loop-gentemp 'loop-hash-val-temp-)) ,@post-steps)) (push `(,val-var nil) bindings)) `(,bindings ;bindings () ;prologue () ;pre-test () ;parallel steps (not (multiple-value-bind (,temp-predicate-var ,temp-key-var ,temp-val-var) (,next-fn) ;; We use M-V-BIND instead of M-V-SETQ because we only ;; want to assign values to the key and val vars when we ;; are in the hash table. When we reach the end, ;; TEMP-PREDICATE-VAR is NIL, and so are temp-key-var and ;; temp-val-var. This might break any type declarations ;; on the key and val vars. (when ,temp-predicate-var (setq ,val-var ,temp-val-var) (setq ,key-var ,temp-key-var)) (setq ,dummy-predicate-var ,temp-predicate-var) )) ;post-test ,post-steps))))) (defun loop-package-symbols-iteration-path (variable data-type prep-phrases &key symbol-types) (cond ((and prep-phrases (cdr prep-phrases)) (loop-error "Too many prepositions!")) ((and prep-phrases (not (member (caar prep-phrases) '(:in :of)))) (loop-error "Unknow preposition ~S" (caar prep-phrases)))) (unless (symbolp variable) (loop-error "Destructuring is not valid for package symbol iteration.")) (let ((pkg-var (loop-gentemp 'loop-pkgsym-)) (next-fn (loop-gentemp 'loop-pkgsym-next-)) (variable (or variable (loop-gentemp))) (pkg (or (cadar prep-phrases) '*package*))) (push `(with-package-iterator (,next-fn ,pkg-var ,@symbol-types)) *loop-wrappers*) `(((,variable nil ,data-type) (,pkg-var ,pkg)) () () () (not (multiple-value-setq (,(progn ;;@@@@ If an implementation can get away without actually ;; using a variable here, so much the better. #+Genera NIL #-Genera (loop-when-it-variable)) ,variable) (,next-fn))) ()))) ;;;; ANSI Loop (eval-when (:compile-toplevel :load-toplevel :execute) (defun make-ansi-loop-universe (extended-p) (let ((w (make-standard-loop-universe :keywords `((named (loop-do-named)) (initially (loop-do-initially)) (finally (loop-do-finally)) (do (loop-do-do)) (doing (loop-do-do)) (return (loop-do-return)) (collect (loop-list-collection list)) (collecting (loop-list-collection list)) (append (loop-list-collection append)) (appending (loop-list-collection append)) (nconc (loop-list-collection nconc)) (nconcing (loop-list-collection nconc)) (count (loop-sum-collection count ,*loop-real-data-type* fixnum)) (counting (loop-sum-collection count ,*loop-real-data-type* fixnum)) (sum (loop-sum-collection sum number number)) (summing (loop-sum-collection sum number number)) (maximize (loop-maxmin-collection max)) (minimize (loop-maxmin-collection min)) (maximizing (loop-maxmin-collection max)) (minimizing (loop-maxmin-collection min)) (always (loop-do-always t nil)) ; Normal, do always (never (loop-do-always t t)) ; Negate the test on always. (thereis (loop-do-thereis t)) (while (loop-do-while nil :while)) ; Normal, do while (until (loop-do-while t :until)) ; Negate the test on while (when (loop-do-if when nil)) ; Normal, do when (if (loop-do-if if nil)) ; synonymous (unless (loop-do-if unless t)) ; Negate the test on when (with (loop-do-with)) (repeat (loop-do-repeat))) :for-keywords '((= (loop-ansi-for-equals)) (across (loop-for-across)) (in (loop-for-in)) (on (loop-for-on)) (from (loop-for-arithmetic :from)) (downfrom (loop-for-arithmetic :downfrom)) (upfrom (loop-for-arithmetic :upfrom)) (below (loop-for-arithmetic :below)) (above (loop-for-arithmetic :above)) (to (loop-for-arithmetic :to)) (upto (loop-for-arithmetic :upto)) (downto (loop-for-arithmetic :downto)) (by (loop-for-arithmetic :by)) (being (loop-for-being))) :iteration-keywords '((for (loop-do-for)) (as (loop-do-for))) :type-symbols '(array atom bignum bit bit-vector character compiled-function complex cons double-float fixnum float function hash-table integer keyword list long-float nil null number package pathname random-state ratio rational readtable sequence short-float simple-array simple-bit-vector simple-string simple-vector single-float standard-char stream string base-char symbol t vector) :type-keywords nil :ansi (if extended-p :extended t)))) (add-loop-path '(hash-key hash-keys) 'loop-hash-table-iteration-path w :preposition-groups '((:of :in)) :inclusive-permitted nil :user-data '(:which hash-key)) (add-loop-path '(hash-value hash-values) 'loop-hash-table-iteration-path w :preposition-groups '((:of :in)) :inclusive-permitted nil :user-data '(:which hash-value)) (add-loop-path '(symbol symbols) 'loop-package-symbols-iteration-path w :preposition-groups '((:of :in)) :inclusive-permitted nil :user-data '(:symbol-types (:internal :external :inherited))) (add-loop-path '(external-symbol external-symbols) 'loop-package-symbols-iteration-path w :preposition-groups '((:of :in)) :inclusive-permitted nil :user-data '(:symbol-types (:external))) (add-loop-path '(present-symbol present-symbols) 'loop-package-symbols-iteration-path w :preposition-groups '((:of :in)) :inclusive-permitted nil :user-data '(:symbol-types (:internal :external))) w)) (defparameter *loop-ansi-universe* (make-ansi-loop-universe nil)) (defun loop-standard-expansion (keywords-and-forms environment universe) (if (and keywords-and-forms (symbolp (car keywords-and-forms))) (loop-translate keywords-and-forms environment universe) (let ((tag (gensym))) `(block nil (tagbody ,tag (progn ,@keywords-and-forms) (go ,tag)))))) ) ;; eval-when ;;;INTERFACE: ANSI (defmacro loop (&environment env &rest keywords-and-forms) #+Genera (declare (compiler:do-not-record-macroexpansions) (zwei:indentation . zwei:indent-loop)) (loop-standard-expansion keywords-and-forms env *loop-ansi-universe*)) #+allegro (defun excl::complex-loop-expander (body env) (loop-standard-expansion body env *loop-ansi-universe*)) ;; Replace the CL::LOOP macro with this macro for use with CLSQL ;; LOOP extensions #+clisp (eval-when (:compile-toplevel :load-toplevel :execute) (shadowing-import '(loop loop-finish) (find-package "COMMON-LISP")) (setf (ext:package-lock (find-package "COMMON-LISP")) t)) cl-sql-6.7.2/sql/package.lisp0000644000175000017500000004112312651763351015030 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: package.lisp ;;;; Purpose: Package definition for SQL interface ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) ;;;; This file makes the required package definitions for CLSQL's ;;;; core packages. (eval-when (:compile-toplevel :load-toplevel :execute) #+sbcl (if (find-package 'sb-mop) (pushnew :clsql-sbcl-mop cl:*features*) (pushnew :clsql-sbcl-pcl cl:*features*)) #+cmu (if (eq (symbol-package 'pcl:find-class) (find-package 'common-lisp)) (pushnew :clsql-cmucl-mop cl:*features*) (pushnew :clsql-cmucl-pcl cl:*features*))) (eval-when (:compile-toplevel :load-toplevel :execute) (defpackage #:clsql-sys (:use #:common-lisp #+clsql-sbcl-mop #:sb-mop #+clsql-cmucl-mop #:mop #+allegro #:mop #+clisp #:clos #+ecl #:mop #+lispworks #:clos #+scl #:clos #+openmcl #:openmcl-mop) #+allegro (:shadowing-import-from #:excl) #+clisp (:shadowing-import-from #:clos) #+lispworks (:shadowing-import-from #:clos) #+clsql-sbcl-mop (:shadowing-import-from #:sb-pcl #:generic-function-lambda-list) #+clsql-sbcl-pcl (:shadowing-import-from #:sb-pcl #:name #:class-direct-slots #:class-of #:class-name #:class-slots #:find-class #:slot-boundp #:standard-class #:slot-definition-name #:finalize-inheritance #:standard-direct-slot-definition #:standard-effective-slot-definition #:validate-superclass #:direct-slot-definition-class #:compute-effective-slot-definition #:effective-slot-definition-class #:slot-value-using-class #:class-prototype #:generic-function-method-class #:intern-eql-specializer #:make-method-lambda #:generic-function-lambda-list #:class-precedence-list #:slot-definition-type #:class-direct-superclasses #:compute-class-precedence-list) #+clsql-cmucl-mop (:shadowing-import-from #:pcl #:generic-function-lambda-list) #+clsql-cmucl-pcl (:shadowing-import-from #:pcl #:class-direct-slots #:name #:class-of #:class-name #:class-slots #:find-class #:standard-class #:slot-boundp #:slot-definition-name #:finalize-inheritance #:standard-direct-slot-definition #:standard-effective-slot-definition #:validate-superclass #:direct-slot-definition-class #:effective-slot-definition-class #:compute-effective-slot-definition #:slot-value-using-class #:class-prototype #:generic-function-method-class #:intern-eql-specializer #:make-method-lambda #:generic-function-lambda-list #:class-precedence-list #:slot-definition-type #:class-direct-superclasses #:compute-class-precedence-list) #+scl (:shadowing-import-from #:clos #:class-prototype ;; note: make-method-lambda is not fbound ) (:export ;; "Private" exports for use by interface packages #:check-connection-spec #:database-initialize-database-type #:database-type-load-foreign #:database-connect #:database-disconnect #:database-reconnect #:database-query #:database-execute-command #:database-create-sequence #:database-drop-sequence #:database-sequence-next #:database-set-sequence-position #:database-query-result-set #:database-dump-result-set #:database-store-next-row #:database-list-tables #:database-list-tables-and-sequences #:database-table-exists-p #:database-list-views #:database-view-exists-p #:database-list-indexes #:database-list-table-indexes #:database-index-exists-p #:database-list-sequences #:database-sequence-last #:database-sequence-exists-p #:database-last-auto-increment-id #:database-list-attributes #:database-attribute-type #:database-type-library-loaded #:database-create #:database-destroy #:database-probe #:database-list #:database-acquire-from-conn-pool #:database-release-to-conn-pool #:db-backend-has-create/destroy-db? #:db-type-has-views? #:db-type-has-bigint? #:db-type-has-union? #:db-type-has-prepared-stmt? #:db-type-has-subqueries? #:db-type-has-boolean-where? #:db-type-transaction-capable? #:db-type-has-fancy-math? #:db-type-default-case #:db-type-use-column-on-drop-index? #:db-type-use-fully-qualified-column-on-drop-index? #:db-type-has-intersect? #:db-type-has-except? #:db-type-has-auto-increment? #:database-underlying-type #:database-get-type-specifier #:read-sql-value #:database-output-sql-as-type #:*loaded-database-types* #:reload-database-types #:is-database-open #:*db-pool-max-free-connections* ;; Large objects #:database-create-large-object #:database-write-large-object #:database-read-large-object #:database-delete-large-object #:create-large-object #:write-large-object #:read-large-object #:delete-large-object ;; Prepared statments #:database-prepare #:database-run-prepared #:database-bind-parameter #:database-free-prepared ;; accessors for database class #:name #:connection-spec #:transaction #:transaction-level #:conn-pool #:command-recording-stream #:result-recording-stream #:record-caches #:view-classes #:database-state #:attribute-cache #:database-autocommit #:encoding ;; utils.lisp #:without-interrupts #:make-process-lock #:with-process-lock #:command-output #:symbol-name-default-case #:convert-to-db-default-case #:ensure-keyword #:getenv #:number-to-sql-string #:float-to-sql-string #:sql-escape-quotes #:sql-escape #:in ;; Command-object.lisp #:expression #:parameters #:prepare-sql-parameter #:prepared-name #:has-been-prepared #:command-object #:reset-command-object ;; Generic backends #:generic-postgresql-database #:generic-odbc-database ;; Subclasses of sql-expresssion (expressions.lisp) #:sql-function-exp #:sql-value-exp #:sql-set-exp #:sql-query-modifier-exp #:sql-relational-exp #:sql-upcase-like #:sql-assignment-exp #:sql-typecast-exp #:sql-between-exp #:sql-ident #:sql-ident-attribute #:sql-ident-table . ;; Shared exports for re-export by CLSQL package. #1=( ;; foreign library loading #:*foreign-library-search-paths* #:push-library-path ;; Condition system (conditions.lisp) #:sql-user-error #:sql-database-error #:sql-database-data-error #:sql-connection-error #:sql-temporary-error #:sql-timeout-error #:sql-fatal-error #:sql-error-error-id #:sql-error-secondary-error-id #:sql-error-database-message ;; CLSQL Extensions #:sql-condition #:sql-error #:sql-warning #:sql-database-warning #:sql-error-database #:sql-error-database-type #:sql-error-connection-spec #:sql-error-expression #:sql-warning-database #:sql-user-error-message #:*backend-warning-behavior* ;; Connection/initialisation (base-classes.lisp, database.lisp, ;; initialize.lisp) #:*default-database-type* #:*default-database* #:*initialized-database-types* #:initialize-database-type #:connect #:disconnect #:*connect-if-exists* #:connected-databases #:database #:database-name #:reconnect #:find-database #:status ;; CLSQL Extensions #:database-name-from-spec #:database-type #:with-database #:with-default-database #:disconnect-pooled #:list-databases #:create-database #:destroy-database #:probe-database ;; I/O Recording (recording.lisp) #:add-sql-stream #:delete-sql-stream #:list-sql-streams #:sql-recording-p #:sql-stream #:start-sql-recording #:stop-sql-recording ;; FDDL (fddl.lisp) #:create-table #:drop-table #:list-tables #:table-exists-p #:list-attributes #:attribute-type #:list-attribute-types #:create-view #:drop-view #:create-index #:drop-index ;; CLSQL Extensions #:truncate-database #:list-views #:view-exists-p #:list-indexes #:index-exists-p #:create-sequence #:drop-sequence #:list-sequences #:sequence-exists-p #:sequence-next #:sequence-last #:set-sequence-position #:*old-sequence-names* ;; FDML (fdml.lisp) #:select #:cache-table-queries #:*cache-table-queries-default* #:delete-records #:insert-records #:update-records #:execute-command #:query #:print-query #:do-query #:map-query #:loop ;; CLSQL Extensions #:prepare-sql #:bind-parameter #:run-prepared-sql #:free-prepared-sql ;; Transaction handling (transaction.lisp) #:with-transaction #:commit #:rollback ;; CLSQL Extensions #:add-transaction-commit-hook #:add-transaction-rollback-hook #:start-transaction #:in-transaction-p #:set-autocommit ;; OODDL (ooddl.lisp) #:standard-db-object #:def-view-class #:create-view-from-class #:drop-view-from-class #:list-classes #:universal-time ;; CLSQL Extensions #:view-table #:bigint #:varchar #:longchar #:text #:generalized-boolean #:mediumint #:smallint #:tinyint #:*default-string-length* ;; OODML (oodml.lisp) #:select-list #:filter-select-list #:slot-list #:joins #:join-slots #:instance-refreshed #:update-objects-joins #:*default-update-objects-max-len* #:*default-caching* #:update-slot-from-record #:update-instance-from-records #:update-records-from-instance #:update-record-from-slot #:update-record-from-slots #:delete-instance-records ;; CLSQL Extensions #:*db-auto-sync* #:write-instance-to-stream #:read-instance-from-stream ;; Symbolic SQL Syntax (syntax.lisp) #:sql #:sql-expression #:sql-operation #:sql-operator #:disable-sql-reader-syntax #:enable-sql-reader-syntax #:locally-disable-sql-reader-syntax #:locally-enable-sql-reader-syntax #:restore-sql-reader-syntax-state #:file-enable-sql-reader-syntax ;; SQL operations (operations.lisp) #:sql-query #:sql-object-query #:sql-any #:sql-some #:sql-all #:sql-not #:sql-union #:sql-intersect #:sql-minus #:sql-except #:sql-order-by #:sql-null #:sql-* #:sql-+ #:sql-/ #:sql-- #:sql-like #:sql-and #:sql-or #:sql-in #:sql-substr #:sql-concat-op #:sql-= #:sql-< #:sql-> #:sql->= #:sql-<= #:sql-<> #:sql-count #:sql-max #:sql-min #:sql-avg #:sql-sum #:sql-function #:sql-between #:sql-distinct #:sql-nvl #:sql-slot-value #:sql-userenv ;; CLSQL Extensions #:sql-concat #:sql-substring #:sql-limit #:sql-group-by #:sql-having #:sql-not-null #:sql-exists #:sql-uplike #:sql-is #:sql-== #:sql-the #:sql-coalesce #:sql-view-class ;; Time handling (time.lisp) #:bad-component #:current-day #:current-month #:current-year #:day-duration #:db-timestring #:db-datestring #:decode-duration #:decode-time #:decode-date #:duration #:duration+ #:duration< #:duration<= #:duration= #:duration> #:duration>= #:duration-day #:duration-hour #:duration-minute #:duration-month #:duration-second #:duration-year #:duration-reduce #:duration-timestring #:extract-roman #:format-duration #:format-time #:format-date #:get-time #:get-date #:utime->time #:interval-clear #:interval-contained #:interval-data #:interval-edit #:interval-end #:interval-match #:interval-push #:interval-relation #:interval-start #:interval-type #:make-duration #:make-interval #:make-time #:make-date #:merged-time #:midnight #:month-name #:parse-date-time #:parse-timestring #:parse-datestring #:parse-yearstring #:print-date #:roll #:roll-to #:time #:time+ #:time- #:time-by-adding-duration #:time-compare #:time-difference #:time-dow #:time-element #:time-max #:time-min #:time-mjd #:time-msec #:time-p #:time-sec #:time-well-formed #:time-ymd #:time< #:time<= #:time= #:time> #:time>= #:date #:date+ #:date- #:date-difference #:date-compare #:date-dow #:date-element #:date-max #:date-min #:date-mjd #:date-p #:date-ymd #:date< #:date<= #:date= #:date> #:date>= #:timezone #:universal-time #:wall-time #:wall-timestring #:week-containing #:gregorian-to-mjd #:mjd-to-gregorian #:iso-timestring )) (:documentation "This is the INTERNAL SQL-Interface package of CLSQL.")) (defpackage #:clsql (:use #:common-lisp) (:import-from #:clsql-sys . #1#) (:export . #1#) (:documentation "This is the user package with CLSQL symbols.")) (defpackage #:clsql-user (:use #:common-lisp) (:import-from #:clsql-sys . #1#) (:export . #1#) (:documentation "This is the user package with CLSQL symbols.")) ;; This is from USQL's pcl-patch #+(or clsql-sbcl-pcl clsql-cmucl-pcl) (progn ;; Note that this will no longer required for cmucl as of version 19a. (in-package #+cmu :pcl #+sbcl :sb-pcl) (defmacro pv-binding1 ((pv calls pv-table-symbol pv-parameters slot-vars) &body body) `(pv-env (,pv ,calls ,pv-table-symbol ,pv-parameters) (let (,@(mapcar #'(lambda (slot-var p) `(,slot-var (get-slots-or-nil ,p))) slot-vars pv-parameters)) ,@(mapcar #'(lambda (slot-var) `(declare (ignorable ,slot-var))) slot-vars) ,@body)))) ;; see http://thread.gmane.org/gmane.lisp.lispworks.general/681 #+lispworks (setf *packages-for-warn-on-redefinition* (delete "SQL" *packages-for-warn-on-redefinition* :test 'string=)) #+sbcl (if (find-package 'sb-mop) (setq cl:*features* (delete :clsql-sbcl-mop cl:*features*)) (setq cl:*features* (delete :clsql-sbcl-pcl cl:*features*))) #+cmu (if (find-package 'mop) (setq cl:*features* (delete :clsql-cmucl-mop cl:*features*)) (setq cl:*features* (delete :clsql-cmucl-pcl cl:*features*))) ) ;eval-when cl-sql-6.7.2/sql/command-object.lisp0000644000175000017500000000601612064366222016313 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-sql.sql ;;;; Purpose: High-level PostgreSQL interface using socket ;;;; Authors: Russ Tyndall (at Acceleration.net) based on original code by ;;;; Kevin M. Rosenberg based on original code by Pierre R. Mai ;;;; Created: Sep 2009 ;;;; ;;;; ;;;; $Id$ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2007 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass command-object () ((expression :accessor expression :initarg :expression :initform nil :documentation "query that refers to parameters using \"$1\", \"$2\", \"$n\". These match positions in the parameters list.") (parameters :accessor parameters :initarg :parameters :initform nil :documentation "list of parameters") (prepared-name :accessor prepared-name :initarg :prepared-name :initform "" :documentation "If we want this to be a prepared statement, give it a name to identify it to this session") (has-been-prepared :accessor has-been-prepared :initarg :has-been-prepared :initform nil :documentation "Have we already prepared this command object?") )) (defgeneric prepare-sql-parameter (sql-parameter) (:documentation "This method is responsible for formatting parameters as the database expects them (eg: :false is nil, nil is :null, dates are iso8601 strings)") (:method (sql-parameter) (typecase sql-parameter (null :null) (symbol (if (member sql-parameter (list :false :F)) nil (princ-to-string sql-parameter))) (clsql-sys:date (format-date nil sql-parameter :format :iso8601)) (clsql-sys:wall-time (format-time nil sql-parameter :format :iso8601)) (t sql-parameter)))) (defmethod initialize-instance :after ((o command-object) &key &allow-other-keys ) ;; Inits parameter value coersion (setf (parameters o) (parameters o))) (defmethod (setf parameters) (new (o command-object)) " This causes the semantics to match cl-sql instead of cl-postgresql " (setf (slot-value o 'parameters) (loop for p in new collecting (prepare-sql-parameter p)))) (defun reset-command-object (co) "Resets the command object to have no name and to be unprepared (This is useful if you want to run a command against a second database)" (setf (prepared-name co) "" (has-been-prepared co) nil)) (defun command-object (expression &optional parameters (prepared-name "")) (make-instance 'command-object :expression expression :parameters parameters :prepared-name prepared-name)) cl-sql-6.7.2/sql/database.lisp0000644000175000017500000003714112473715066015210 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Base database functions ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defvar *default-encoding* (or #+sbcl sb-impl::*default-external-format* :utf-8)) (defvar *connect-if-exists* :error "Default value for the if-exists keyword argument in calls to CONNECT. Meaningful values are :new, :warn-new, :error, :warn-old and :old.") ;;TODO: this variable appears to be global, not thread specific and is ;; not protected when modifying the list. (defvar *connected-databases* nil "List of active database objects.") (defun connected-databases () "Returns the list of active database objects." *connected-databases*) (defvar *default-database* nil "Specifies the default database to be used.") (defun is-database-open (database) (eql (database-state database) :open)) (defun find-database (database &key (errorp t) (db-type nil)) "Returns the connected databases of type DB-TYPE whose names match the string DATABASE. If DATABASE is a database object, it is returned. If DB-TYPE is nil all databases matching the string DATABASE are considered. If no matching databases are found and ERRORP is nil then nil is returned. If ERRORP is nil and one or more matching databases are found, then the most recently connected database is returned as a first value and the number of matching databases is returned as a second value. If no, or more than one, matching databases are found and ERRORP is true, an error is signalled." (etypecase database (database (values database 1)) (string (let* ((matches (remove-if #'(lambda (db) (not (and (string= (database-name db) database) (if db-type (equal (database-type db) db-type) t)))) (connected-databases))) (count (length matches))) (if (or (not errorp) (= count 1)) (values (car matches) count) (cerror "Return nil." 'sql-database-error :message (format nil "There exists ~A database called ~A." (if (zerop count) "no" "more than one") database))))) (null (error "A database must be specified rather than NIL.")))) (defun connect (connection-spec &key (if-exists *connect-if-exists*) (make-default t) (pool nil) (database-type *default-database-type*) (encoding *default-encoding*)) "Connects to a database of the supplied DATABASE-TYPE which defaults to *DEFAULT-DATABASE-TYPE*, using the type-specific connection specification CONNECTION-SPEC. The value of IF-EXISTS, which defaults to *CONNECT-IF-EXISTS*, determines what happens if a connection to the database specified by CONNECTION-SPEC is already established. A value of :new means create a new connection. A value of :warn-new means warn the user and create a new connect. A value of :warn-old means warn the user and use the old connection. A value of :error means fail, notifying the user. A value of :old means return the old connection. MAKE-DEFAULT is t by default which means that *DEFAULT-DATABASE* is set to the new connection, otherwise *DEFAULT-DATABASE* is not changed. If POOL is t the connection will be taken from the general pool, if POOL is a CONN-POOL object the connection will be taken from this pool." (unless database-type (error 'sql-database-error :message "Must specify a database-type.")) (when (stringp connection-spec) (setq connection-spec (string-to-list-connection-spec connection-spec))) (unless (member database-type *loaded-database-types*) (asdf:operate 'asdf:load-op (ensure-keyword (concatenate 'string (symbol-name '#:clsql-) (symbol-name database-type))) :verbose nil)) (if pool (let ((conn (acquire-from-pool connection-spec database-type pool encoding))) (when make-default (setq *default-database* conn)) conn) (let* ((db-name (database-name-from-spec connection-spec database-type)) (old-db (unless (eq if-exists :new) (find-database db-name :db-type database-type :errorp nil))) (result nil)) (if old-db (ecase if-exists (:warn-new (setq result (database-connect connection-spec database-type)) (warn 'sql-warning :message (format nil "Created new connection ~A to database ~A~%, although there is an existing connection (~A)." result (database-name result) old-db))) (:error (restart-case (error 'sql-connection-error :message (format nil "There is an existing connection ~A to database ~A." old-db (database-name old-db))) (create-new () :report "Create a new connection." (setq result (database-connect connection-spec database-type))) (use-old () :report "Use the existing connection." (setq result old-db)))) (:warn-old (setq result old-db) (warn 'sql-warning :message (format nil "Using existing connection ~A to database ~A." old-db (database-name old-db)))) (:old (setq result old-db))) (setq result (database-connect connection-spec database-type))) (when result (setf (slot-value result 'state) :open) (pushnew result *connected-databases*) (when make-default (setq *default-database* result)) (setf (encoding result) encoding) result)))) (defun disconnect (&key (database *default-database*) (error nil)) "Closes the connection to DATABASE and resets *DEFAULT-DATABASE* if that database was disconnected. If DATABASE is a database instance, this object is closed. If DATABASE is a string, then a connected database whose name matches DATABASE is sought in the list of connected databases. If no matching database is found and ERROR and DATABASE are both non-nil an error is signaled, otherwise nil is returned. If the database is from a pool it will be released to this pool." (let ((database (find-database database :errorp (and database error)))) (when database (if (conn-pool database) (with-process-lock ((conn-pool-lock (conn-pool database)) "Delete from pool") (when (release-to-pool database) (setf *connected-databases* (delete database *connected-databases*)) (when (eq database *default-database*) (setf *default-database* (car *connected-databases*))) t)) (when (database-disconnect database) ;;TODO: RACE COND: 2 threads disconnecting could stomp on *connected-databases* (setf *connected-databases* (delete database *connected-databases*)) (when (eq database *default-database*) (setf *default-database* (car *connected-databases*))) (setf (slot-value database 'state) :closed) t))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmacro check-connection-spec (connection-spec database-type template) "Check the connection specification against the provided template, and signal an sql-user-error if they don't match. This function is called by database backends." `(handler-case (destructuring-bind ,template ,connection-spec (declare (ignore ,@(remove-if (lambda (x) (member x '(&key &rest &optional))) template))) t) (error () (error 'sql-user-error :message (format nil "The connection specification ~A~%is invalid for database type ~A.~%The connection specification must conform to ~A" ,connection-spec ,database-type (quote ,template)))))) (defun reconnect (&key (database *default-database*) (error nil) (force t)) "Reconnects DATABASE which defaults to *DEFAULT-DATABASE* to the underlying database management system. On success, t is returned and the variable *DEFAULT-DATABASE* is set to the newly reconnected database. If DATABASE is a database instance, this object is closed. If DATABASE is a string, then a connected database whose name matches DATABASE is sought in the list of connected databases. If no matching database is found and ERROR and DATABASE are both non-nil an error is signaled, otherwise nil is returned. When the current database connection cannot be closed, if FORCE is non-nil, as it is by default, the connection is closed and errors are suppressed. If force is nil and the database connection cannot be closed, an error is signalled." (let ((db (etypecase database (database database) ((or string list) (let ((db (find-database database :errorp nil))) (when (null db) (if (and database error) (error 'sql-connection-error :message (format nil "Unable to find database with connection-spec ~A." database)) (return-from reconnect nil))) db))))) (when (is-database-open db) (if force (ignore-errors (disconnect :database db)) (disconnect :database db :error nil))) (connect (connection-spec db) :encoding (encoding db)))) (defun status (&optional full) "Prints information about the currently connected databases to *STANDARD-OUTPUT*. The argument FULL is nil by default and a value of t means that more detailed information about each database is printed." (flet ((get-data () (let ((data '())) (dolist (db (connected-databases) data) (push (append (list (if (equal db *default-database*) "*" "") (database-name db) (string-downcase (string (database-type db))) (cond ((and (command-recording-stream db) (result-recording-stream db)) "Both") ((command-recording-stream db) "Commands") ((result-recording-stream db) "Results") (t "nil"))) (when full (list (if (conn-pool db) "t" "nil") (format nil "~A" (length (database-list-tables db))) (format nil "~A" (length (database-list-views db)))))) data)))) (compute-sizes (data) (mapcar #'(lambda (x) (apply #'max (mapcar #'length x))) (apply #'mapcar (cons #'list data)))) (print-separator (size) (format t "~&~A" (make-string size :initial-element #\-)))) (format t "~&CLSQL STATUS: ~A~%" (iso-timestring (get-time))) (let ((data (get-data))) (when data (let* ((titles (if full (list "" "DATABASE" "TYPE" "RECORDING" "POOLED" "TABLES" "VIEWS") (list "" "DATABASE" "TYPE" "RECORDING"))) (sizes (compute-sizes (cons titles data))) (total-size (+ (apply #'+ sizes) (* 2 (1- (length titles))))) (control-string (format nil "~~&~~{~{~~~AA ~}~~}" sizes))) (print-separator total-size) (format t control-string titles) (print-separator total-size) (dolist (d data) (format t control-string d)) (print-separator total-size)))) (values))) (defun create-database (connection-spec &key (database-type *default-database-type*)) "This function creates a database in the database system specified by DATABASE-TYPE." (when (stringp connection-spec) (setq connection-spec (string-to-list-connection-spec connection-spec))) (database-create connection-spec database-type)) (defun probe-database (connection-spec &key (database-type *default-database-type*)) "This function tests for the existence of a database in the database system specified by DATABASE-TYPE." (when (stringp connection-spec) (setq connection-spec (string-to-list-connection-spec connection-spec))) (database-probe connection-spec database-type)) (defun destroy-database (connection-spec &key (database-type *default-database-type*)) "This function destroys a database in the database system specified by DATABASE-TYPE." (when (stringp connection-spec) (setq connection-spec (string-to-list-connection-spec connection-spec))) (database-destroy connection-spec database-type)) (defun list-databases (connection-spec &key (database-type *default-database-type*)) "This function returns a list of databases existing in the database system specified by DATABASE-TYPE." (when (stringp connection-spec) (setq connection-spec (string-to-list-connection-spec connection-spec))) (database-list connection-spec database-type)) (defun encoding (db) (or (when (typep db 'database) (slot-value db 'encoding)) *default-encoding*)) (defun (setf encoding) (encoding db) (when (typep db 'database) (setf (slot-value db 'encoding) encoding) (when (eql (slot-value db 'state) :open) (case (database-type db) ;; FIXME: If database object is open then ;; send command to SQL engine specifying the character ;; encoding for the database (:mysql ) ((:postgresql :postgresql-socket) ))))) (defmacro with-database ((db-var connection-spec &key make-default pool (if-exists *connect-if-exists*) (database-type *default-database-type*) (encoding nil)) &body body) "Evaluate the body in an environment, where DB-VAR is bound to the database connection given by CONNECTION-SPEC and CONNECT-ARGS. The connection is automatically closed or released to the pool on exit from the body. MAKE-DEFAULT has a default value of NIL." `(let ((,db-var (connect ,connection-spec :database-type ,database-type :if-exists ,if-exists :pool ,pool :make-default ,make-default :encoding ,encoding))) (unwind-protect (let ((,db-var ,db-var)) (progn ,@body)) (disconnect :database ,db-var)))) (defmacro with-default-database ((database) &rest body) "Perform BODY with DATABASE bound as *default-database*." `(progv '(*default-database*) (list ,database) ,@body)) cl-sql-6.7.2/sql/time.lisp0000644000175000017500000013601111577737507014406 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; A variety of structures and function for creating and ;;;; manipulating dates, times, durations and intervals for ;;;; CLSQL. ;;;; ;;;; This file was originally part of ODCL and is Copyright (c) 2002 - ;;;; 2003 onShore Development, Inc. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) ;; ------------------------------------------------------------ ;; Months (defvar *month-keywords* '(:january :february :march :april :may :june :july :august :september :october :november :december)) (defvar *month-names* '("" "January" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December")) (defun month-name (month-index) (nth month-index *month-names*)) (defun ordinal-month (month-keyword) "Return the zero-based month number for the given MONTH keyword." (position month-keyword *month-keywords*)) ;; ------------------------------------------------------------ ;; Days (defvar *day-keywords* '(:sunday :monday :tuesday :wednesday :thursday :friday :saturday)) (defvar *day-names* '("Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday")) (defun day-name (day-index) (nth day-index *day-names*)) (defun ordinal-day (day-keyword) "Return the zero-based day number for the given DAY keyword." (position day-keyword *day-keywords*)) ;; ------------------------------------------------------------ ;; time classes: wall-time, duration (eval-when (:compile-toplevel :load-toplevel) (defstruct (wall-time (:conc-name time-) (:constructor %make-wall-time) (:print-function %print-wall-time)) (mjd 0 :type fixnum) (second 0 :type fixnum) (usec 0 :type fixnum)) (defun %print-wall-time (time stream depth) (declare (ignore depth)) (if *print-escape* (format stream "#" (format-time nil time)) (format-time stream time :format :pretty))) (defstruct (duration (:constructor %make-duration) (:print-function %print-duration)) (year 0 :type fixnum) (month 0 :type fixnum) (day 0 :type fixnum) (hour 0 :type fixnum) (second 0 :type fixnum) (minute 0 :type fixnum) (usec 0 :type fixnum)) (defun %print-duration (duration stream depth) (declare (ignore depth)) (if *print-escape* (format stream "#" (format-duration nil duration :precision :second)) (format-duration stream duration :precision :second))) (defstruct (date (:constructor %make-date) (:print-function %print-date)) (mjd 0 :type fixnum)) (defun %print-date (date stream depth) (declare (ignore depth)) (if *print-escape* (format stream "#" (format-date nil date)) (format-date stream date :format :pretty))) );eval-when (defun duration-timestring (duration) (let ((second (duration-second duration)) (minute (duration-minute duration)) (hour (duration-hour duration)) (day (duration-day duration)) (month (duration-month duration)) (year (duration-year duration))) (format nil "P~dY~dM~dD~dH~dM~dS" year month day hour minute second))) ;; ------------------------------------------------------------ ;; Constructors (defun make-time (&key (year 0) (month 1) (day 1) (hour 0) (minute 0) (second 0) (usec 0) (offset 0)) (let ((mjd (gregorian-to-mjd month day year)) (sec (+ (* hour 60 60) (* minute 60) second (- offset)))) (multiple-value-bind (day-add raw-sec) (floor sec (* 60 60 24)) (%make-wall-time :mjd (+ mjd day-add) :second raw-sec :usec usec)))) (defun make-date (&key (year 0) (month 1) (day 1) (hour 0) (minute 0) (second 0) (usec 0) (offset 0)) (time->date (make-time :year year :month month :day day :hour hour :minute minute :second second :usec usec :offset offset))) (defun copy-time (time) (%make-wall-time :mjd (time-mjd time) :second (time-second time))) (defun utime->time (utime) "Return a pair: (GREGORIAN DAY . TIME-OF-DAY)" (multiple-value-bind (second minute hour day mon year) (decode-universal-time utime) (make-time :year year :month mon :day day :hour hour :minute minute :second second))) (defun date->time (date) "Returns a walltime for the given date" (%make-wall-time :mjd (date-mjd date))) (defun time->date (time) "Returns a date for the given wall time (obvious loss in resolution)" (%make-date :mjd (time-mjd time))) (defun get-time () "Return a pair: (GREGORIAN DAY . TIME-OF-DAY)" (utime->time (get-universal-time))) (defun get-date () "Returns a date for today" (time->date (get-time))) (defun make-duration (&key (year 0) (month 0) (day 0) (hour 0) (minute 0) (second 0) (usec 0)) (multiple-value-bind (second-add usec-1000000) (floor usec 1000000) (multiple-value-bind (minute-add second-60) (floor (+ second second-add) 60) (multiple-value-bind (hour-add minute-60) (floor (+ minute minute-add) 60) (multiple-value-bind (day-add hour-24) (floor (+ hour hour-add) 24) (%make-duration :year year :month month :day (+ day day-add) :hour hour-24 :minute minute-60 :second second-60 :usec usec-1000000)))))) ;; ------------------------------------------------------------ ;; Accessors (defun time-hms (time) (multiple-value-bind (hourminute second) (floor (time-second time) 60) (multiple-value-bind (hour minute) (floor hourminute 60) (values hour minute second)))) (defun time-ymd (time) (destructuring-bind (month day year) (mjd-to-gregorian (time-mjd time)) (values year month day))) (defun time-dow (time) "Return the 0 indexed Day of the week starting with Sunday" (mod (+ 3 (time-mjd time)) 7)) (defun decode-time (time) "returns the decoded time as multiple values: usec, second, minute, hour, day, month, year, integer day-of-week" (multiple-value-bind (year month day) (time-ymd time) (multiple-value-bind (hour minute second) (time-hms time) (values (time-usec time) second minute hour day month year (mod (+ (time-mjd time) 3) 7))))) (defun date-ymd (date) (time-ymd (date->time date))) (defun date-dow (date) (time-dow (date->time date))) (defun decode-date (date) "returns the decoded date as multiple values: day month year integer day-of-week" (multiple-value-bind (year month day) (time-ymd (date->time date)) (values day month year (date-dow date)))) ;; duration specific (defun duration-reduce (duration precision &optional round) (ecase precision (:usec (+ (duration-usec duration) (* (duration-reduce duration :second) 1000000))) (:second (+ (if round (floor (duration-usec duration) 500000) 0) (duration-second duration) (* (duration-reduce duration :minute) 60))) (:minute (+ (if round (floor (duration-second duration) 30) 0) (duration-minute duration) (* (duration-reduce duration :hour) 60))) (:hour (+ (if round (floor (duration-minute duration) 30) 0) (duration-hour duration) (* (duration-reduce duration :day) 24))) (:day (+ (if round (floor (duration-hour duration) 12) 0) (duration-day duration))))) ;; ------------------------------------------------------------ ;; Arithemetic and comparators (defun duration= (duration-a duration-b) (= (duration-reduce duration-a :usec) (duration-reduce duration-b :usec))) (defun duration< (duration-a duration-b) (< (duration-reduce duration-a :usec) (duration-reduce duration-b :usec))) (defun duration<= (duration-a duration-b) (<= (duration-reduce duration-a :usec) (duration-reduce duration-b :usec))) (defun duration>= (x y) (duration<= y x)) (defun duration> (x y) (duration< y x)) (defun %time< (x y) (let ((mjd-x (time-mjd x)) (mjd-y (time-mjd y))) (if (/= mjd-x mjd-y) (< mjd-x mjd-y) (if (/= (time-second x) (time-second y)) (< (time-second x) (time-second y)) (< (time-usec x) (time-usec y)))))) (defun %time>= (x y) (if (/= (time-mjd x) (time-mjd y)) (>= (time-mjd x) (time-mjd y)) (if (/= (time-second x) (time-second y)) (>= (time-second x) (time-second y)) (>= (time-usec x) (time-usec y))))) (defun %time<= (x y) (if (/= (time-mjd x) (time-mjd y)) (<= (time-mjd x) (time-mjd y)) (if (/= (time-second x) (time-second y)) (<= (time-second x) (time-second y)) (<= (time-usec x) (time-usec y))))) (defun %time> (x y) (if (/= (time-mjd x) (time-mjd y)) (> (time-mjd x) (time-mjd y)) (if (/= (time-second x) (time-second y)) (> (time-second x) (time-second y)) (> (time-usec x) (time-usec y))))) (defun %time= (x y) (and (= (time-mjd x) (time-mjd y)) (= (time-second x) (time-second y)) (= (time-usec x) (time-usec y)))) (defun time= (number &rest more-numbers) "Returns T if all of its arguments are numerically equal, NIL otherwise." (do ((nlist more-numbers (cdr nlist))) ((atom nlist) t) (declare (list nlist)) (if (not (%time= (car nlist) number)) (return nil)))) (defun time/= (number &rest more-numbers) "Returns T if no two of its arguments are numerically equal, NIL otherwise." (do* ((head number (car nlist)) (nlist more-numbers (cdr nlist))) ((atom nlist) t) (declare (list nlist)) (unless (do* ((nl nlist (cdr nl))) ((atom nl) t) (declare (list nl)) (if (%time= head (car nl)) (return nil))) (return nil)))) (defun time< (number &rest more-numbers) "Returns T if its arguments are in strictly increasing order, NIL otherwise." (do* ((n number (car nlist)) (nlist more-numbers (cdr nlist))) ((atom nlist) t) (declare (list nlist)) (if (not (%time< n (car nlist))) (return nil)))) (defun time> (number &rest more-numbers) "Returns T if its arguments are in strictly decreasing order, NIL otherwise." (do* ((n number (car nlist)) (nlist more-numbers (cdr nlist))) ((atom nlist) t) (declare (list nlist)) (if (not (%time> n (car nlist))) (return nil)))) (defun time<= (number &rest more-numbers) "Returns T if arguments are in strictly non-decreasing order, NIL otherwise." (do* ((n number (car nlist)) (nlist more-numbers (cdr nlist))) ((atom nlist) t) (declare (list nlist)) (if (not (%time<= n (car nlist))) (return nil)))) (defun time>= (number &rest more-numbers) "Returns T if arguments are in strictly non-increasing order, NIL otherwise." (do* ((n number (car nlist)) (nlist more-numbers (cdr nlist))) ((atom nlist) t) (declare (list nlist)) (if (not (%time>= n (car nlist))) (return nil)))) (defun time-max (number &rest more-numbers) "Returns the greatest of its arguments." (do ((nlist more-numbers (cdr nlist)) (result number)) ((null nlist) (return result)) (declare (list nlist)) (if (%time> (car nlist) result) (setf result (car nlist))))) (defun time-min (number &rest more-numbers) "Returns the least of its arguments." (do ((nlist more-numbers (cdr nlist)) (result number)) ((null nlist) (return result)) (declare (list nlist)) (if (%time< (car nlist) result) (setf result (car nlist))))) (defun time-compare (time-a time-b) (let ((mjd-a (time-mjd time-a)) (mjd-b (time-mjd time-b)) (sec-a (time-second time-a)) (sec-b (time-second time-b)) (usec-a (time-usec time-a)) (usec-b (time-usec time-b))) (if (= mjd-a mjd-b) (if (= sec-a sec-b) (if (= usec-a usec-b) :equal (if (< usec-a usec-b) :less-than :greater-than)) (if (< sec-a sec-b) :less-than :greater-than)) (if (< mjd-a mjd-b) :less-than :greater-than)))) ; now the same for dates (eval-when (:compile-toplevel :load-toplevel) (defun replace-string (string1 search-string replace-string &key (test #'string=)) "Search within string1 for search-string, replace with replace-string, non-destructively." (let ((replace-string-length (length replace-string)) (search-string-length (length search-string))) (labels ((sub-replace-string (current-string position) (let ((found-position (search search-string current-string :test test :start2 position))) (if (null found-position) current-string (sub-replace-string (concatenate 'string (subseq current-string 0 found-position) replace-string (subseq current-string (+ found-position search-string-length))) (+ position replace-string-length)))))) (sub-replace-string string1 0)))) );eval-when (defmacro wrap-time-for-date (time-func &key (result-func)) (let ((date-func (intern (replace-string (symbol-name time-func) (symbol-name-default-case "TIME") (symbol-name-default-case "DATE"))))) `(defun ,date-func (number &rest more-numbers) (let ((result (apply #',time-func (mapcar #'date->time (cons number more-numbers))))) ,(if result-func `(funcall #',result-func result) 'result))))) (wrap-time-for-date time=) (wrap-time-for-date time/=) (wrap-time-for-date time<) (wrap-time-for-date time>) (wrap-time-for-date time<=) (wrap-time-for-date time>=) (wrap-time-for-date time-max :result-func time->date) (wrap-time-for-date time-min :result-func time->date) (defun date-compare (date-a date-b) (time-compare (date->time date-a) (date->time date-b))) ;; ------------------------------------------------------------ ;; Formatting and output (defun db-timestring (time &key stream) "return the string to store the given time in the database" (if stream (progn (write-char #\' stream) (iso-timestring time :stream stream) (write-char #\' stream)) (concatenate 'string "'" (iso-timestring time) "'"))) (defun iso-timestring (time &key stream) (multiple-value-bind (usec sec min hour day month year dow) (decode-time time) (declare (ignore dow)) (flet ((fmt (stream) (when (< year 1000) (princ #\0 stream)) (when (< year 100) (princ #\0 stream)) (when (< year 10) (princ #\0 stream)) (princ year stream) (princ #\- stream) (when (< month 10) (princ #\0 stream)) (princ month stream) (princ #\- stream) (when (< day 10) (princ #\0 stream)) (princ day stream) (princ #\T stream) ;strict ISO says T here isn't optional. (when (< hour 10) (princ #\0 stream)) (princ hour stream) (princ #\: stream) (when (< min 10) (princ #\0 stream)) (princ min stream) (princ #\: stream) (when (< sec 10) (princ #\0 stream)) (princ sec stream) (when (and usec (plusp usec)) ;; we dont do this because different dbs support differnt precision levels (princ #\. stream) (loop for i from 5 downto 0 for x10 = (expt 10 i) do (multiple-value-bind (quo rem) (floor (/ usec x10)) (setf usec (- usec (* quo x10))) (princ quo stream) (when (= rem 0) (return))))) nil)) (if stream (fmt stream) (with-output-to-string (stream) (fmt stream)))))) (defun db-datestring (date) (db-timestring (date->time date))) (defun iso-datestring (date) (iso-timestring (date->time date))) ;; ------------------------------------------------------------ ;; Intervals (defstruct interval (start nil) (end nil) (name nil) (contained nil) (type nil) (data nil)) ;; fix : should also return :contains / :contained (defun interval-relation (x y) "Compare the relationship of node x to node y. Returns either :contained :contains :follows :overlaps or :precedes." (let ((xst (interval-start x)) (xend (interval-end x)) (yst (interval-start y)) (yend (interval-end y))) (case (time-compare xst yst) (:equal (case (time-compare xend yend) (:less-than :contained) ((:equal :greater-than) :contains))) (:greater-than (case (time-compare xst yend) ((:equal :greater-than) :follows) (:less-than (case (time-compare xend yend) ((:less-than :equal) :contained) ((:greater-than) :overlaps))))) (:less-than (case (time-compare xend yst) ((:equal :less-than) :precedes) (:greater-than (case (time-compare xend yend) (:less-than :overlaps) ((:equal :greater-than) :contains)))))))) ;; ------------------------------------------------------------ ;; interval lists (defun sort-interval-list (list) (sort list (lambda (x y) (case (interval-relation x y) ((:precedes :contains) t) ((:follows :overlaps :contained) nil))))) ;; interval push will return its list of intervals in strict order. (defun interval-push (interval-list interval &optional container-rule) (declare (ignore container-rule)) (let ((sorted-list (sort-interval-list interval-list))) (dotimes (x (length sorted-list)) (let ((elt (nth x sorted-list))) (case (interval-relation elt interval) (:follows (return-from interval-push (insert-at-index x sorted-list interval))) (:contains (return-from interval-push (replace-at-index x sorted-list (make-interval :start (interval-start elt) :end (interval-end elt) :type (interval-type elt) :contained (interval-push (interval-contained elt) interval) :data (interval-data elt))))) ((:overlaps :contained) (error "Overlap"))))) (append sorted-list (list interval)))) ;; interval lists (defun interval-match (list time) "Return the index of the first interval in list containing time" ;; this depends on ordering of intervals! (let ((list (sort-interval-list list))) (dotimes (x (length list)) (let ((elt (nth x list))) (when (and (time<= (interval-start elt) time) (time< time (interval-end elt))) (return-from interval-match x)))))) (defun interval-clear (list time) (dotimes (x (length list)) (let ((elt (nth x list))) (when (and (time<= (interval-start elt) time) (time< time (interval-end elt))) (if (interval-match (interval-contained elt) time) (return-from interval-clear (replace-at-index x list (make-interval :start (interval-start elt) :end (interval-end elt) :type (interval-type elt) :contained (interval-clear (interval-contained elt) time) :data (interval-data elt)))) (return-from interval-clear (delete-at-index x list))))))) (defun interval-edit (list time start end &optional tag) "Attempts to modify the most deeply nested interval in list which begins at time. If no changes are made, returns nil." ;; function required sorted interval list (let ((list (sort-interval-list list))) (if (null list) nil (dotimes (x (length list)) (let ((elt (nth x list))) (when (and (time<= (interval-start elt) time) (time< time (interval-end elt))) (or (interval-edit (interval-contained elt) time start end tag) (cond ((and (< 0 x) (time< start (interval-end (nth (1- x) list)))) (error "Overlap of previous interval")) ((and (< x (1- (length list))) (time< (interval-start (nth (1+ x) list)) end)) (error "~S ~S ~S ~S Overlap of next interval" x (length list) (interval-start (nth (1+ x) list)) end )) ((time= (interval-start elt) time) (return-from interval-edit (replace-at-index x list (make-interval :start start :end end :type (interval-type elt) :contained (restrict-intervals (interval-contained elt) start end) :data (or tag (interval-data elt)))))))))))))) (defun restrict-intervals (list start end &aux newlist) (let ((test-interval (make-interval :start start :end end))) (dolist (elt list) (when (equal :contained (interval-relation elt test-interval)) (push elt newlist))) (nreverse newlist))) ;;; utils from odcl/list.lisp (defun replace-at-index (idx list elt) (cond ((= idx 0) (cons elt (cdr list))) ((= idx (1- (length list))) (append (butlast list) (list elt))) (t (append (subseq list 0 idx) (list elt) (subseq list (1+ idx)))))) (defun insert-at-index (idx list elt) (cond ((= idx 0) (cons elt list)) ((= idx (1- (length list))) (append list (list elt))) (t (append (subseq list 0 idx) (list elt) (subseq list idx))))) (defun delete-at-index (idx list) (cond ((= idx 0) (cdr list)) ((= idx (1- (length list))) (butlast list)) (t (append (subseq list 0 idx) (subseq list (1+ idx)))))) ;; ------------------------------------------------------------ ;; return MJD for Gregorian date (defun gregorian-to-mjd (month day year) (let ((b 0) (month-adj month) (year-adj (if (< year 0) (+ year 1) year)) d c) (when (< month 3) (incf month-adj 12) (decf year-adj)) (unless (or (< year 1582) (and (= year 1582) (or (< month 10) (and (= month 10) (< day 15))))) (let ((a (floor (/ year-adj 100)))) (setf b (+ (- 2 a) (floor (/ a 4)))))) (if (< year-adj 0) (setf c (floor (- (* 365.25d0 year-adj) 679006.75d0))) (setf c (floor (- (* 365.25d0 year-adj) 679006d0)))) (setf d (floor (* 30.6001 (+ 1 month-adj)))) ;; (cmsg "b ~s c ~s d ~s day ~s" b c d day) (+ b c d day))) ;; convert MJD to Gregorian date (defun mjd-to-gregorian (mjd) (let (z r g a b c year month day) (setf z (floor (+ mjd 678882))) (setf r (- (+ mjd 678882) z)) (setf g (- z .25)) (setf a (floor (/ g 36524.25))) (setf b (- a (floor (/ a 4)))) (setf year (floor (/ (+ b g) 365.25))) (setf c (- (+ b z) (floor (* 365.25 year)))) (setf month (truncate (/ (+ (* 5 c) 456) 153))) (setf day (+ (- c (truncate (/ (- (* 153 month) 457) 5))) r)) (when (> month 12) (incf year) (decf month 12)) (list month day year))) (defun duration+ (time &rest durations) "Add each DURATION to TIME, returning a new wall-time value." (let ((year (duration-year time)) (month (duration-month time)) (day (duration-day time)) (hour (duration-hour time)) (minute (duration-minute time)) (second (duration-second time)) (usec (duration-usec time))) (dolist (duration durations) (incf year (duration-year duration)) (incf month (duration-month duration)) (incf day (duration-day duration)) (incf hour (duration-hour duration)) (incf minute (duration-minute duration)) (incf second (duration-second duration)) (incf usec (duration-usec duration))) (make-duration :year year :month month :day day :hour hour :minute minute :second second :usec usec))) (defun duration- (duration &rest durations) "Subtract each DURATION from TIME, returning a new duration value." (let ((year (duration-year duration)) (month (duration-month duration)) (day (duration-day duration)) (hour (duration-hour duration)) (minute (duration-minute duration)) (second (duration-second duration)) (usec (duration-usec duration))) (dolist (duration durations) (decf year (duration-year duration)) (decf month (duration-month duration)) (decf day (duration-day duration)) (decf hour (duration-hour duration)) (decf minute (duration-minute duration)) (decf second (duration-second duration)) (decf usec (duration-usec duration))) (make-duration :year year :month month :day day :hour hour :minute minute :second second :usec usec))) ;; Date + Duration (defun time+ (time &rest durations) "Add each DURATION to TIME, returning a new wall-time value." (let ((new-time (copy-time time))) (dolist (duration durations) (roll new-time :year (duration-year duration) :month (duration-month duration) :day (duration-day duration) :hour (duration-hour duration) :minute (duration-minute duration) :second (duration-second duration) :usec (duration-usec duration) :destructive t)) new-time)) (defun date+ (date &rest durations) "Add each DURATION to DATE, returning a new date value. Note that (barring daylight saving time) 12h + 12h will result in a new day, but doing it as separate calculations will not, as the time is chopped to a date before being returned." (time->date (apply #'time+ (cons (date->time date) durations)))) (defun time- (time &rest durations) "Subtract each DURATION from TIME, returning a new wall-time value." (let ((new-time (copy-time time))) (dolist (duration durations) (roll new-time :year (- (duration-year duration)) :month (- (duration-month duration)) :day (- (duration-day duration)) :hour (- (duration-hour duration)) :minute (- (duration-minute duration)) :second (- (duration-second duration)) :usec (- (duration-usec duration)) :destructive t)) new-time)) (defun date- (date &rest durations) "Subtract each DURATION to DATE, returning a new date value. Note that (barring daylight saving time) 12h + 12h will result in a new day, but doing it as separate calculations will not, as the time is chopped to a date before being returned." (time->date (apply #'time- (cons (date->time date) durations)))) (defun time-difference (time1 time2) "Returns a DURATION representing the difference between TIME1 and TIME2." (flet ((do-diff (time1 time2) (let (day-diff sec-diff) (setf day-diff (- (time-mjd time2) (time-mjd time1))) (if (> day-diff 0) (progn (decf day-diff) (setf sec-diff (+ (time-second time2) (- (* 60 60 24) (time-second time1))))) (setf sec-diff (- (time-second time2) (time-second time1)))) (make-duration :day day-diff :second sec-diff)))) (if (time< time1 time2) (do-diff time1 time2) (do-diff time2 time1)))) (defun date-difference (date1 date2) "Returns a DURATION representing the difference between TIME1 and TIME2." (time-difference (date->time date1) (date->time date2))) (defun format-date (stream date &key format (date-separator "-") (internal-separator " ")) "produces on stream the datestring corresponding to the date with the given options" (format-time stream (date->time date) :format format :date-separator date-separator :internal-separator internal-separator)) (defun format-time (stream time &key format (date-separator "-") (time-separator ":") (internal-separator " ")) "produces on stream the timestring corresponding to the wall-time with the given options" (let ((*print-circle* nil)) (multiple-value-bind (usec second minute hour day month year dow) (decode-time time) (case format (:pretty (format stream "~A ~A, ~A ~D, ~D" (pretty-time hour minute) (day-name dow) (month-name month) day year)) (:short-pretty (format stream "~A, ~D/~D/~D" (pretty-time hour minute) month day year)) ((:iso :iso8601) (iso-timestring time :stream stream)) (t (format stream "~2,'0D~A~2,'0D~A~2,'0D~A~2,'0D~A~2,'0D~A~2,'0D.~6,'0D" year date-separator month date-separator day internal-separator hour time-separator minute time-separator second usec) ))))) (defun pretty-time (hour minute) (cond ((eq hour 0) (format nil "12:~2,'0D AM" minute)) ((eq hour 12) (format nil "12:~2,'0D PM" minute)) ((< hour 12) (format nil "~D:~2,'0D AM" hour minute)) ((and (> hour 12) (< hour 24)) (format nil "~D:~2,'0D PM" (- hour 12) minute)) (t (error "pretty-time got bad hour")))) (defun leap-days-in-days (days) ;; return the number of leap days between Mar 1 2000 and ;; (Mar 1 2000) + days, where days can be negative (if (< days 0) (ceiling (/ (- days) (* 365 4))) (floor (/ days (* 365 4))))) (defun current-year () (third (mjd-to-gregorian (time-mjd (get-time))))) (defun current-month () (first (mjd-to-gregorian (time-mjd (get-time))))) (defun current-day () (second (mjd-to-gregorian (time-mjd (get-time))))) (defun parse-date-time (string) "parses date like 08/08/01, 8.8.2001, eg" (when (> (length string) 1) (let ((m (current-month)) (d (current-day)) (y (current-year))) (let ((integers (mapcar #'parse-integer (hork-integers string)))) (case (length integers) (1 (setf y (car integers))) (2 (setf m (car integers)) (setf y (cadr integers))) (3 (setf m (car integers)) (setf d (cadr integers)) (setf y (caddr integers))) (t (return-from parse-date-time)))) (when (< y 100) (incf y 2000)) (make-time :year y :month m :day d)))) (defun hork-integers (input) (let ((output '()) (start 0)) (dotimes (x (length input)) (unless (<= 48 (char-code (aref input x)) 57) (push (subseq input start x) output) (setf start (1+ x)))) (nreverse (push (subseq input start) output)))) (defun merged-time (day time-of-day) (%make-wall-time :mjd (time-mjd day) :second (time-second time-of-day))) (defun time-meridian (hours) (cond ((= hours 0) (values 12 "AM")) ((= hours 12) (values 12 "PM")) ((< 12 hours) (values (- hours 12) "PM")) (t (values hours "AM")))) (defgeneric to-string (val &rest keys) ) (defmethod to-string ((time wall-time) &rest keys) (destructuring-bind (&key (style :daytime) &allow-other-keys) keys (print-date time style))) (defun print-date (time &optional (style :daytime)) (multiple-value-bind (usec second minute hour day month year dow) (decode-time time) (declare (ignore usec second)) (multiple-value-bind (hours meridian) (time-meridian hour) (ecase style (:time-of-day ;; 2:00 PM (format nil "~d:~2,'0d ~a" hours minute meridian)) (:long-day ;; October 11th, 2000 (format nil "~a ~d, ~d" (month-name month) day year)) (:month ;; October (month-name month)) (:month-year ;; October 2000 (format nil "~a ~d" (month-name month) year)) (:full ;; 11:08 AM, November 22, 2002 (format nil "~d:~2,'0d ~a, ~a ~d, ~d" hours minute meridian (month-name month) day year)) (:full+weekday ;; 11:09 AM Friday, November 22, 2002 (format nil "~d:~2,'0d ~a ~a, ~a ~d, ~d" hours minute meridian (nth dow *day-names*) (month-name month) day year)) (:daytime ;; 11:09 AM, 11/22/2002 (format-time nil time :format :short-pretty)) (:day ;; 11/22/2002 (format nil "~d/~d/~d" month day year)))))) (defun time-element (time element) (multiple-value-bind (usec second minute hour day month year dow) (decode-time time) (declare (ignore usec)) (ecase element (:seconds second) (:minutes minute) (:hours hour) (:day-of-month day) (:integer-day-of-week dow) (:day-of-week (nth dow *day-keywords*)) (:month month) (:year year)))) (defun date-element (date element) (time-element (date->time date) element)) (defun format-duration (stream duration &key (precision :minute)) (let ((second (duration-second duration)) (minute (duration-minute duration)) (hour (duration-hour duration)) (day (duration-day duration)) (month (duration-month duration)) (year (duration-year duration)) (return (null stream)) (stream (or stream (make-string-output-stream)))) (ecase precision (:day (setf hour 0 second 0 minute 0)) (:hour (setf second 0 minute 0)) (:minute (setf second 0)) (:second t)) (if (= 0 year month day hour minute) (format stream "0 minutes") (let ((sent? nil)) (when (< 0 year) (format stream "~d year~p" year year) (setf sent? t)) (when (< 0 month) (when sent? (write-char #\Space stream)) (format stream "~d month~p" month month) (setf sent? t)) (when (< 0 day) (when sent? (write-char #\Space stream)) (format stream "~d day~p" day day) (setf sent? t)) (when (< 0 hour) (when sent? (write-char #\Space stream)) (format stream "~d hour~p" hour hour) (setf sent? t)) (when (< 0 minute) (when sent? (write-char #\Space stream)) (format stream "~d min~p" minute minute) (setf sent? t)) (when (< 0 second) (when sent? (write-char #\Space stream)) (format stream "~d sec~p" second second)))) (when return (get-output-stream-string stream)))) (defgeneric midnight (self)) (defmethod midnight ((self wall-time)) "truncate hours, minutes and seconds" (%make-wall-time :mjd (time-mjd self))) (defun roll (date &key (year 0) (month 0) (day 0) (second 0) (hour 0) (minute 0) (usec 0) (destructive nil)) (unless (= 0 year month) (multiple-value-bind (year-orig month-orig day-orig) (time-ymd date) (multiple-value-bind (new-year new-month) (floor (+ month month-orig (* 12 (+ year year-orig))) 12) (let ((new-date (make-time :year new-year :month new-month :day day-orig :second (time-second date) :usec usec))) (if destructive (setf (time-mjd date) (time-mjd new-date)) (setq date new-date)))))) (let ((mjd (time-mjd date)) (sec (time-second date))) (multiple-value-bind (sec-new usec-new) (floor (+ usec (time-usec date) (* 1000000 (+ sec second (* 60 minute) (* 60 60 hour)))) 1000000) (multiple-value-bind (mjd-new sec-new) (floor sec-new (* 60 60 24)) (if destructive (progn (setf (time-mjd date) (+ mjd mjd-new day) (time-second date) sec-new (time-usec date) usec-new) date) (%make-wall-time :mjd (+ mjd mjd-new day) :second sec-new :usec usec-new)))))) (defun roll-to (date size position) (ecase size (:month (ecase position (:beginning (roll date :day (+ 1 (- (time-element date :day-of-month))))) (:end (roll date :day (+ (days-in-month (time-element date :month) (time-element date :year)) (- (time-element date :day-of-month))))))))) (defun week-containing (time) (let* ((midn (midnight time)) (dow (time-element midn :integer-day-of-week))) (list (roll midn :day (- dow)) (roll midn :day (- 7 dow))))) (defun leap-year? (year) "t if YEAR is a leap yeap in the Gregorian calendar" (and (= 0 (mod year 4)) (or (not (= 0 (mod year 100))) (= 0 (mod year 400))))) (defun valid-month-p (month) "t if MONTH exists in the Gregorian calendar" (<= 1 month 12)) (defun valid-gregorian-date-p (date) "t if DATE (year month day) exists in the Gregorian calendar" (let ((max-day (days-in-month (nth 1 date) (nth 0 date)))) (<= 1 (nth 2 date) max-day))) (defun days-in-month (month year &key (careful t)) "the number of days in MONTH of YEAR, observing Gregorian leap year rules" (declare (type fixnum month year)) (when careful (check-type month (satisfies valid-month-p) "between 1 (January) and 12 (December)")) (if (eql month 2) ; feb (if (leap-year? year) 29 28) (let ((even (mod (1- month) 2))) (if (< month 8) ; aug (- 31 even) (+ 30 even))))) (defun day-of-year (year month day &key (careful t)) "the day number within the year of the date DATE. For example, 1987 1 1 returns 1" (declare (type fixnum year month day)) (when careful (let ((date (list year month day))) (check-type date (satisfies valid-gregorian-date-p) "a valid Gregorian date"))) (let ((doy (+ day (* 31 (1- month))))) (declare (type fixnum doy)) (when (< 2 month) (setf doy (- doy (floor (+ 23 (* 4 month)) 10))) (when (leap-year? year) (incf doy))) doy)) (defun parse-yearstring (string) (let ((year (or (parse-integer-insensitively string) (extract-roman string)))) (when (and year (< 1500 year 2500)) (make-time :year year)))) (defun parse-integer-insensitively (string) (let ((start (position-if #'digit-char-p string)) (end (position-if #'digit-char-p string :from-end t))) (when (and start end) (parse-integer (subseq string start (1+ end)) :junk-allowed t)))) (defvar *roman-digits* '((#\M . 1000) (#\D . 500) (#\C . 100) (#\L . 50) (#\X . 10) (#\V . 5) (#\I . 1))) (defun extract-roman (string &aux parse) (dotimes (x (length string)) (let ((val (cdr (assoc (aref string x) *roman-digits*)))) (when (and val parse (< (car parse) val)) (push (- (pop parse)) parse)) (push val parse))) (apply #'+ parse)) ;; ------------------------------------------------------------ ;; Parsing iso-8601 timestrings (define-condition iso-8601-syntax-error (sql-user-error) ((bad-component;; year, month whatever :initarg :bad-component :reader bad-component)) (:report (lambda (c stream) (format stream "Bad component: ~A " (bad-component c))))) (defun parse-timestring (timestring &key (start 0) end junk-allowed) "parse a timestring and return the corresponding wall-time. If the timestring starts with P, read a duration; otherwise read an ISO 8601 formatted date string." (declare (ignore junk-allowed)) (etypecase timestring (wall-time timestring) (date (date->time timestring)) (string (let ((string (subseq timestring start end))) (if (char= (aref string 0) #\P) (parse-iso-8601-duration string) (parse-iso-8601-time string)))))) (defun parse-datestring (datestring &key (start 0) end junk-allowed) "parse a ISO 8601 timestring and return the corresponding date. Will throw a hissy fit if the date string is a duration. Will ignore any precision beyond day (hour/min/sec/usec)." (etypecase datestring (date datestring) (wall-time (time->date datestring)) (string (let ((parsed-value (parse-timestring datestring :start start :end end :junk-allowed junk-allowed))) (etypecase parsed-value (date parsed-value) (wall-time (time->date parsed-value))))))) (defvar *iso-8601-duration-delimiters* '((#\Y . :years) (#\D . :days) (#\H . :hours) (#\M . :months/minutes) (#\S . :seconds))) (defun iso-8601-delimiter (elt) (cdr (assoc elt *iso-8601-duration-delimiters*))) (defun iso-8601-duration-subseq (string end) (let* ((pos (position-if #'iso-8601-delimiter string :end end :from-end t)) (pos2 (when pos (position-if-not #'digit-char-p string :end pos :from-end t))) (number (when pos2 (parse-integer (subseq string (1+ pos2) pos) :junk-allowed t)))) (when number (values number (1+ pos) (1+ pos2) (iso-8601-delimiter (aref string pos)))))) (defun parse-iso-8601-duration (string) "return a wall-time from a duration string" (block parse (let ((years 0) (months 0) (days 0) (secs 0) (hours 0) (minutes 0) (index (length string)) (months/minutes nil)) (loop (multiple-value-bind (duration end next-index duration-type) (iso-8601-duration-subseq string index) (declare (ignore end)) (case duration-type (:years (incf years duration)) (:months/minutes (if months/minutes (incf months duration) (progn (setq months/minutes t) (incf minutes duration)))) (:days (setq months/minutes t) (incf days duration)) (:hours (setq months/minutes t) (incf hours duration)) (:seconds (incf secs duration)) (t (return-from parse (make-duration :year years :month months :day days :hour hours :minute minutes :second secs)))) (setf index next-index)))))) ;; e.g. 2000-11-11 00:00:00-06 (defun parse-iso-8601-time (string) "return the wall-time corresponding to the given ISO 8601 datestring" (multiple-value-bind (year month day hour minute second usec offset) (syntax-parse-iso-8601 string) (make-time :year year :month month :day day :hour hour :minute minute :second second :usec usec :offset offset))) (defun syntax-parse-iso-8601 (string) ;; use strlen to determine if fractional seconds are present in timestamp (let ((strlen (length string)) year month day hour minute second usec gmt-sec-offset) (handler-case (progn (setf year (parse-integer string :start 0 :end 4) month (parse-integer string :start 5 :end 7) day (parse-integer string :start 8 :end 10) hour (if (<= 13 strlen) (parse-integer string :start 11 :end 13) 0) minute (if (<= 16 strlen) (parse-integer string :start 14 :end 16) 0) second (if (<= 19 strlen) (parse-integer string :start 17 :end 19) 0)) (cond ((and (> strlen 19) (or (char= #\, (char string 19)) (char= #\. (char string 19)))) (multiple-value-bind (parsed-usec usec-end) (parse-integer string :start 20 :junk-allowed t) (let ((parsed-usec (and parsed-usec (floor (* parsed-usec (expt 10 (+ 6 (- usec-end) 20))))))) (setf usec (or parsed-usec 0) gmt-sec-offset (if (<= (+ 3 usec-end) strlen) (let ((skip-to (or (position #\+ string :start 19) (position #\- string :start 19)))) (if skip-to (* 60 60 (parse-integer string :start skip-to :end (+ skip-to 3))) 0)) 0))))) (t (setf usec 0 gmt-sec-offset (if (<= 22 strlen) (let ((skip-to (or (position #\+ string :start 19) (position #\- string :start 19)))) (if skip-to (* 60 60 (parse-integer string :start skip-to :end (+ skip-to 3))) 0)) 0)))) (unless (< 0 year) (error 'iso-8601-syntax-error :bad-component '(year . 0))) (unless (< 0 month) (error 'iso-8601-syntax-error :bad-component '(month . 0))) (unless (< 0 day) (error 'iso-8601-syntax-error :bad-component '(month . 0))) (values year month day hour minute second usec gmt-sec-offset)) (simple-error () (error 'iso-8601-syntax-error :bad-component (car (find-if (lambda (pair) (null (cdr pair))) `((year . ,year) (month . ,month) (day . ,day) (hour . ,hour) (minute . ,minute) (second . ,second) (usec . ,usec) (timezone . ,gmt-sec-offset))))))))) cl-sql-6.7.2/sql/metaclasses.lisp0000644000175000017500000006052512473715066015752 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; CLSQL metaclass for standard-db-objects created in the OODDL. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (eval-when (:compile-toplevel :load-toplevel :execute) (when (>= (length (generic-function-lambda-list (ensure-generic-function 'compute-effective-slot-definition))) 3) (pushnew :kmr-normal-cesd cl:*features*)) (when (>= (length (generic-function-lambda-list (ensure-generic-function 'direct-slot-definition-class))) 3) (pushnew :kmr-normal-dsdc cl:*features*)) (when (>= (length (generic-function-lambda-list (ensure-generic-function 'effective-slot-definition-class))) 3) (pushnew :kmr-normal-esdc cl:*features*))) ;; ------------------------------------------------------------ ;; metaclass: view-class (defclass standard-db-class (standard-class) ((view-table :accessor view-table :initarg :view-table) (definition :accessor object-definition :initarg :definition :initform nil) (key-slots :accessor key-slots :initform nil) (normalizedp :accessor normalizedp :initform nil) (class-qualifier :accessor view-class-qualifier :initarg :qualifier :initform nil)) (:documentation "Metaclass for all CLSQL View Classes.")) ;;; Lispworks 4.2 and before requires special processing of extra slot and class options (defvar +extra-slot-options+ '(:column :db-kind :db-type :db-reader :void-value :db-constraints :db-writer :db-info)) (defvar +extra-class-options+ '(:base-table)) #+lispworks (dolist (slot-option +extra-slot-options+) (eval `(process-slot-option standard-db-class ,slot-option))) #+lispworks (dolist (class-option +extra-class-options+) (eval `(process-class-option standard-db-class ,class-option))) (defmethod validate-superclass ((class standard-db-class) (superclass standard-class)) t) (defun table-name-from-arg (arg) (cond ((symbolp arg) (intern (sql-escape arg))) ((typep arg 'sql-ident) (if (symbolp (slot-value arg 'name)) (intern (sql-escape (slot-value arg 'name))) (sql-escape (slot-value arg 'name)))) ((stringp arg) (sql-escape arg)))) (defun remove-keyword-arg (arglist akey) (let ((mylist arglist) (newlist ())) (labels ((pop-arg (alist) (let ((arg (pop alist)) (val (pop alist))) (unless (equal arg akey) (setf newlist (append (list arg val) newlist))) (when alist (pop-arg alist))))) (pop-arg mylist)) newlist)) (defun set-view-table-slot (class base-table) (setf (view-table class) (table-name-from-arg (or (and base-table (if (listp base-table) (car base-table) base-table)) (class-name class))))) (defmethod initialize-instance :around ((class standard-db-class) &rest all-keys &key direct-superclasses base-table qualifier normalizedp &allow-other-keys) (let ((root-class (find-class 'standard-db-object nil)) (vmc 'standard-db-class)) (setf (view-class-qualifier class) (car qualifier)) (if root-class (if (some #'(lambda (super) (typep super vmc)) direct-superclasses) (call-next-method) (apply #'call-next-method class :direct-superclasses (append (list root-class) direct-superclasses) (remove-keyword-arg all-keys :direct-superclasses))) (call-next-method)) (set-view-table-slot class base-table) (setf (normalizedp class) (car normalizedp)) (register-metaclass class (nth (1+ (position :direct-slots all-keys)) all-keys)))) (defmethod reinitialize-instance :around ((class standard-db-class) &rest all-keys &key base-table normalizedp direct-superclasses qualifier &allow-other-keys) (let ((root-class (find-class 'standard-db-object nil)) (vmc 'standard-db-class)) (set-view-table-slot class base-table) (setf (normalizedp class) (car normalizedp)) (setf (view-class-qualifier class) (car qualifier)) (if (and root-class (not (equal class root-class))) (if (some #'(lambda (super) (typep super vmc)) direct-superclasses) (call-next-method) (apply #'call-next-method class :direct-superclasses (append (list root-class) direct-superclasses) (remove-keyword-arg all-keys :direct-superclasses))) (call-next-method))) (register-metaclass class (nth (1+ (position :direct-slots all-keys)) all-keys)) class) (defun get-keywords (keys list) (flet ((extract (key) (let ((pos (position key list))) (when pos (nth (1+ pos) list))))) (mapcar #'extract keys))) (defun describe-db-layout (class) (flet ((not-db-col (col) (not (member (nth 2 col) '(nil :base :key)))) (frob-slot (slot) (let ((type (slot-definition-type slot))) (if (eq type t) (setq type nil)) (list (slot-value slot 'name) type (slot-value slot 'db-kind) (and (slot-boundp slot 'column) (slot-value slot 'column)))))) (let ((all-slots (mapcar #'frob-slot (ordered-class-slots class)))) (setq all-slots (remove-if #'not-db-col all-slots)) (setq all-slots (stable-sort all-slots #'string< :key #'car)) ;;(mapcar #'dink-type all-slots) all-slots))) (defun register-metaclass (class slots) (labels ((not-db-col (col) (not (member (nth 2 col) '(nil :base :key)))) (frob-slot (slot) (get-keywords '(:name :type :db-kind :column) slot))) (let ((all-slots (mapcar #'frob-slot slots))) (setq all-slots (remove-if #'not-db-col all-slots)) (setq all-slots (stable-sort all-slots #'string< :key #'car)) (setf (object-definition class) all-slots)) #-(or sbcl allegro) (setf (key-slots class) (remove-if-not (lambda (slot) (eql (slot-value slot 'db-kind) :key)) (slots-for-possibly-normalized-class class))))) #+(or sbcl allegro) (defmethod finalize-inheritance :after ((class standard-db-class)) (setf (key-slots class) (remove-if-not (lambda (slot) (eql (slot-value slot 'db-kind) :key)) (slots-for-possibly-normalized-class class)))) ;; return the deepest view-class ancestor for a given view class (defun base-db-class (classname) (let* ((class (find-class classname)) (db-class (find-class 'standard-db-object))) (loop (let ((cds (class-direct-superclasses class))) (cond ((null cds) (error "not a db class")) ((member db-class cds) (return (class-name class)))) (setq class (car cds)))))) (defun db-ancestors (classname) (let ((class (find-class classname)) (db-class (find-class 'standard-db-object))) (labels ((ancestors (class) (let ((scs (class-direct-superclasses class))) (if (member db-class scs) (list class) (append (list class) (mapcar #'ancestors scs)))))) (ancestors class)))) (defclass view-class-slot-definition-mixin () ((column :accessor view-class-slot-column :initarg :column :documentation "The name of the SQL column this slot is stored in. Defaults to the slot name.") (db-kind :accessor view-class-slot-db-kind :initarg :db-kind :initform :base ;; openmcl 0.14.2 stores the value as list in the DSD ;; :type (or list keyword) #-openmcl :type #-openmcl keyword :documentation "The kind of DB mapping which is performed for this slot. :base indicates the slot maps to an ordinary column of the DB view. :key indicates that this slot corresponds to part of the unique keys for this view, :join indicates ... and :virtual indicates that this slot is an ordinary CLOS slot. Defaults to :base.") (db-reader :accessor view-class-slot-db-reader :initarg :db-reader :initform nil :documentation "If a string, then when reading values from the DB, the string will be used for a format string, with the only value being the value from the database. The resulting string will be used as the slot value. If a function then it will take one argument, the value from the database, and return the value that should be put into the slot.") (db-writer :accessor view-class-slot-db-writer :initarg :db-writer :initform nil :documentation "If a string, then when reading values from the slot for the DB, the string will be used for a format string, with the only value being the value of the slot. The resulting string will be used as the column value in the DB. If a function then it will take one argument, the value of the slot, and return the value that should be put into the database.") (db-type :accessor view-class-slot-db-type :initarg :db-type :initform nil :documentation "A string which will be used as the type specifier for this slots column definition in the database.") (db-constraints :accessor view-class-slot-db-constraints :initarg :db-constraints :initform nil :documentation "A keyword symbol representing a single SQL column constraint or list of such symbols.") (void-value :accessor view-class-slot-void-value :initarg :void-value :initform nil :documentation "Value to store if the SQL value is NULL. Default is NIL.") (db-info :accessor view-class-slot-db-info :initarg :db-info :documentation "Description of the join.") (specified-type :accessor specified-type :initarg specified-type :initform nil :documentation "Internal slot storing the :type specified by user.") (autoincrement-sequence :accessor view-class-slot-autoincrement-sequence :initarg :autoincrement-sequence :initform nil :documentation "A string naming the (possibly automatically generated) sequence for a slot with an :auto-increment constraint."))) (defparameter *db-info-lambda-list* '(&key join-class home-key foreign-key (key-join nil) (target-slot nil) (retrieval :immmediate) (set nil))) (defun parse-db-info (db-info-list) (destructuring-bind (&key join-class home-key key-join foreign-key (delete-rule nil) (target-slot nil) (retrieval :deferred) (set t)) db-info-list (let ((ih (make-hash-table :size 6))) (if join-class (setf (gethash :join-class ih) join-class) (error "Must specify :join-class in :db-info")) (if home-key (setf (gethash :home-key ih) home-key) (error "Must specify :home-key in :db-info")) (when delete-rule (setf (gethash :delete-rule ih) delete-rule)) (if foreign-key (setf (gethash :foreign-key ih) foreign-key) (error "Must specify :foreign-key in :db-info")) (when key-join (setf (gethash :key-join ih) t)) (when target-slot (setf (gethash :target-slot ih) target-slot)) (when set (setf (gethash :set ih) set)) (when retrieval (progn (setf (gethash :retrieval ih) retrieval) (if (eql retrieval :immediate) (setf (gethash :set ih) nil)))) ih))) (defclass view-class-direct-slot-definition (view-class-slot-definition-mixin standard-direct-slot-definition) ()) (defclass view-class-effective-slot-definition (view-class-slot-definition-mixin standard-effective-slot-definition) ()) (defmethod direct-slot-definition-class ((class standard-db-class) #+kmr-normal-dsdc &rest initargs) (declare (ignore initargs)) (find-class 'view-class-direct-slot-definition)) (defmethod effective-slot-definition-class ((class standard-db-class) #+kmr-normal-esdc &rest initargs) (declare (ignore initargs)) (find-class 'view-class-effective-slot-definition)) #+openmcl (when (not (symbol-function 'compute-class-precedence-list)) (eval (defun compute-class-precedence-list (class) (class-precedence-list class)))) #-mop-slot-order-reversed (defmethod compute-slots ((class standard-db-class)) "Need to sort order of class slots so they are the same across implementations." (let ((slots (call-next-method)) desired-sequence output-slots) (dolist (c (compute-class-precedence-list class)) (dolist (s (class-direct-slots c)) (let ((name (slot-definition-name s))) (unless (find name desired-sequence) (push name desired-sequence))))) (dolist (desired desired-sequence) (let ((slot (find desired slots :key #'slot-definition-name))) (assert slot) (push slot output-slots))) output-slots)) (defun compute-lisp-type-from-specified-type (specified-type db-constraints) "Computes the Lisp type for a user-specified type." (let ((type (cond ((consp specified-type) (let* ((first (first specified-type)) (name (etypecase first (symbol (symbol-name first)) (string first)))) (cond ((or (string-equal name "string") (string-equal name "varchar") (string-equal name "char")) 'string) (t specified-type)))) ((eq (ensure-keyword specified-type) :bigint) 'integer) ((eq (ensure-keyword specified-type) :char) 'character) ((eq (ensure-keyword specified-type) :varchar) 'string) (t specified-type)))) (if (and type (not (member :not-null (listify db-constraints)))) `(or null ,type) (or type t)))) ;; Compute the slot definition for slots in a view-class. Figures out ;; what kind of database value (if any) is stored there, generates and ;; verifies the column name. (declaim (inline delistify)) (defun delistify (list) "Some MOPs, like openmcl 0.14.2, cons attribute values in a list." (if (listp list) (car list) list)) (declaim (inline delistify-dsd)) ;; there is an :after method below too (defmethod initialize-instance :around ((obj view-class-direct-slot-definition) &rest initargs &key db-constraints db-kind type &allow-other-keys) (when (and (not db-kind) (member :primary-key (listify db-constraints))) (warn "Slot ~S constrained to be :primary-key, but not marked as :db-kind :key" (slot-definition-name obj))) (apply #'call-next-method obj 'specified-type type :type (if (and (eql db-kind :virtual) (null type)) t (compute-lisp-type-from-specified-type type db-constraints)) initargs)) (defun compute-column-name (arg) (database-identifier arg nil)) (defun %convert-db-info-to-hash (slot-def) ;; I wonder if this slot option and the previous could be merged, ;; so that :base and :key remain keyword options, but :db-kind ;; :join becomes :db-kind (:join )? (setf (slot-value slot-def 'db-info) (when (slot-boundp slot-def 'db-info) (let ((info (view-class-slot-db-info slot-def))) (etypecase info (hash-table info) (atom info) (list (cond ((and (> (length info) 1) (atom (car info))) (parse-db-info info)) ((and (= 1 (length info)) (listp (car info))) (parse-db-info (car info))) (t info)))))))) (defmethod initialize-instance :after ((obj view-class-direct-slot-definition) &key &allow-other-keys) (setf (view-class-slot-column obj) (compute-column-name obj) (view-class-slot-autoincrement-sequence obj) (dequote (view-class-slot-autoincrement-sequence obj))) (%convert-db-info-to-hash obj)) (defmethod compute-effective-slot-definition ((class standard-db-class) #+kmr-normal-cesd slot-name direct-slots) #+kmr-normal-cesd (declare (ignore slot-name)) ;; KMR: store the user-specified type and then compute ;; real Lisp type and store it (let ((dsd (car direct-slots))) (let ((esd (call-next-method))) (typecase dsd (view-class-slot-definition-mixin (setf (slot-value esd 'column) (compute-column-name dsd)) (macrolet ((safe-copy-value (name &optional default) (let ((fn (intern (format nil "~A~A" 'view-class-slot- name )))) `(setf (slot-value esd ',name) (or (when (slot-boundp dsd ',name) (delistify-dsd (,fn dsd))) ,default))))) (safe-copy-value autoincrement-sequence) (safe-copy-value db-type) (safe-copy-value void-value) (safe-copy-value db-reader) (safe-copy-value db-writer) ;; :db-kind slot value defaults to :base (store slot value in ;; database) (safe-copy-value db-kind :base) (safe-copy-value db-constraints) (safe-copy-value db-info) (%convert-db-info-to-hash esd)) (setf (specified-type esd) (delistify-dsd (specified-type dsd))) ;; In older SBCL's the type-check-function is computed at ;; defclass expansion, which is too early for the CLSQL type ;; conversion to take place. This gets rid of it. It's ugly ;; but it's better than nothing -wcp10/4/10. #+(and sbcl #.(cl:if (cl:and (cl:find-package :sb-pcl) (cl:find-symbol "%TYPE-CHECK-FUNCTION" :sb-pcl)) '(cl:and) '(cl:or))) (setf (slot-value esd 'sb-pcl::%type-check-function) nil) ) ;; all other slots (t (unless (typep esd 'view-class-effective-slot-definition) (warn "Non view-class-direct-slot object with non-view-class-effective-slot-definition in compute-effective-slot-definition") (let ((type-predicate #+openmcl (slot-value esd 'ccl::type-predicate))) #-openmcl (declare (ignore type-predicate)) #-(or clisp sbcl) (change-class esd 'view-class-effective-slot-definition #+allegro :name #+allegro (slot-definition-name dsd)) #+openmcl (setf (slot-value esd 'ccl::type-predicate) type-predicate))) ;; has no column name if it is not a database column (setf (slot-value esd 'column) nil) (setf (slot-value esd 'db-info) nil) (setf (slot-value esd 'db-kind) :virtual) (setf (specified-type esd) (slot-definition-type dsd))) ) esd))) (defun slotdefs-for-slots-with-class (slots class) (let ((result nil)) (dolist (s slots) (let ((c (slotdef-for-slot-with-class s class))) (if c (setf result (cons c result))))) result)) (defun slotdef-for-slot-with-class (slot class) (typecase slot (standard-slot-definition slot) (symbol (find-slot-by-name class slot)))) #+ignore (eval-when (:compile-toplevel :load-toplevel :execute) #+kmr-normal-cesd (setq cl:*features* (delete :kmr-normal-cesd cl:*features*)) #+kmr-normal-dsdc (setq cl:*features* (delete :kmr-normal-dsdc cl:*features*)) #+kmr-normal-esdc (setq cl:*features* (delete :kmr-normal-esdc cl:*features*)) ) (defmethod database-identifier ( (name standard-db-class) &optional database find-class-p) "the majority of this function is in expressions.lisp this is here to make loading be less painful (try-recompiles) in SBCL" (declare (ignore find-class-p)) (database-identifier (view-table name) database)) (defmethod database-identifier ((name view-class-slot-definition-mixin) &optional database find-class-p) (declare (ignore find-class-p)) (database-identifier (if (slot-boundp name 'column) (delistify-dsd (view-class-slot-column name)) (slot-definition-name name)) database)) (defun find-standard-db-class (name &aux cls) (and (setf cls (ignore-errors (find-class name))) (typep cls 'standard-db-class) cls)) (defun slots-for-possibly-normalized-class (class) "Get the slots for this class, if normalized this is only the direct slots otherwiese its all the slots" (if (normalizedp class) (ordered-class-direct-slots class) (ordered-class-slots class))) (defun key-slot-p (slot-def) "takes a slot def and returns whether or not it is a key" (eql :key (view-class-slot-db-kind slot-def))) (defun join-slot-p (slot-def) "takes a slot def and returns whether or not it is a join slot" (eql :join (view-class-slot-db-kind slot-def))) (defun join-slot-info-value (slot-def key) "Get the join-slot db-info value associated with a key" (when (join-slot-p slot-def) (let ((dbi (view-class-slot-db-info slot-def))) (when dbi (gethash key dbi))))) (defun join-slot-retrieval-method (slot-def) "if this is a join slot return the retrieval param in the db-info" (join-slot-info-value slot-def :retrieval)) (defun join-slot-class-name (slot-def) "get the join class name for a given join slot" (join-slot-info-value slot-def :join-class)) (defun join-slot-class (slot-def) "Get the join class for a given join slot" (let ((c (join-slot-class-name slot-def))) (when c (find-class c)))) (defun key-or-base-slot-p (slot-def) "takes a slot def and returns whether or not it is a key" (member (view-class-slot-db-kind slot-def) '(:key :base))) (defun direct-normalized-slot-p (class slot-name) "Is this a normalized class and if so is the slot one of our direct slots?" (setf slot-name (to-slot-name slot-name)) (and (typep class 'standard-db-class) (normalizedp class) (member slot-name (ordered-class-direct-slots class) :key #'slot-definition-name))) (defun not-direct-normalized-slot-p (class slot-name) "Is this a normalized class and if so is the slot not one of our direct slots?" (setf slot-name (to-slot-name slot-name)) (and (typep class 'standard-db-class) (normalizedp class) (not (member slot-name (ordered-class-direct-slots class) :key #'slot-definition-name)))) (defun slot-has-default-p (slot) "returns nil if the slot does not have a default constraint" (let* ((constraints (when (typep slot '(or view-class-direct-slot-definition view-class-effective-slot-definition)) (listify (view-class-slot-db-constraints slot))))) (member :default constraints))) cl-sql-6.7.2/sql/generics.lisp0000644000175000017500000002222012303270414015214 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: generics.lisp ;;;; Purpose: Generic function definitions for DB interfaces ;;;; Author: Kevin M. Rosenberg ;;;; Created: Apr 2004 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2004-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) ;; FDML (defgeneric choose-database-for-instance (object &optional database) (:documentation "Used by the oodml functions to select which database object to use. Chooses the database associated with the object primarily, falls back to the database provided as an argument or the *DEFAULT-DATABASE*.")) (defgeneric execute-command (expression &key database) (:documentation "Executes the SQL command EXPRESSION, which may be an SQL expression or a string representing any SQL statement apart from a query, on the supplied DATABASE which defaults to *DEFAULT-DATABASE*.")) (defgeneric query (query-expression &key database result-types flatp field-names) (:documentation "Executes the SQL query expression QUERY-EXPRESSION, which may be an SQL expression or a string, on the supplied DATABASE which defaults to *DEFAULT-DATABASE*. RESULT-TYPES is a list of symbols which specifies the lisp type for each field returned by QUERY-EXPRESSION. If RESULT-TYPES is nil all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field. FIELD-NAMES is t by default which means that the second value returned is a list of strings representing the columns selected by QUERY-EXPRESSION. If FIELD-NAMES is nil, the list of column names is not returned as a second value. FLATP has a default value of nil which means that the results are returned as a list of lists. If FLATP is t and only one result is returned for each record selected by QUERY-EXPRESSION, the results are returned as elements of a list.")) ;; OODML (defgeneric update-record-from-slot (object slot &key database) (:documentation "Updates the value stored in the column represented by the slot, specified by the CLOS slot name SLOT, of View Class instance OBJECT. DATABASE defaults to *DEFAULT-DATABASE* and specifies the database in which the update is made only if OBJECT is not associated with a database. In this case, a record is created in DATABASE and the attribute represented by SLOT is initialised from the value of the supplied slots with other attributes having default values. Furthermore, OBJECT becomes associated with DATABASE.")) (defgeneric update-record-from-slots (object slots &key database) (:documentation "Updates the values stored in the columns represented by the slots, specified by the CLOS slot names SLOTS, of View Class instance OBJECT. DATABASE defaults to *DEFAULT-DATABASE* and specifies the database in which the update is made only if OBJECT is not associated with a database. In this case, a record is created in the appropriate table of DATABASE and the attributes represented by SLOTS are initialised from the values of the supplied slots with other attributes having default values. Furthermore, OBJECT becomes associated with DATABASE.")) (defgeneric update-records-from-instance (object &key database) (:documentation "Using an instance of a View Class, OBJECT, update the table that stores its instance data. DATABASE defaults to *DEFAULT-DATABASE* and specifies the database in which the update is made only if OBJECT is not associated with a database. In this case, a record is created in the appropriate table of DATABASE using values from the slot values of OBJECT, and OBJECT becomes associated with DATABASE.")) (defgeneric delete-instance-records (object &key database) (:documentation "Deletes the records represented by OBJECT in the appropriate table of the database associated with OBJECT. If OBJECT is not yet associated with a database, an error is signalled.")) (defgeneric update-instance-from-records (object &key database) (:documentation "Updates the slot values of the View Class instance OBJECT using the attribute values of the appropriate table of DATABASE which defaults to the database associated with OBJECT or, if OBJECT is not associated with a database, *DEFAULT-DATABASE*. Join slots are updated but instances of the class on which the join is made are not updated.")) (defgeneric update-slot-from-record (object slot &key database) (:documentation "Updates the slot value, specified by the CLOS slot name SLOT, of the View Class instance OBJECT using the attribute values of the appropriate table of DATABASE which defaults to the database associated with OBJECT or, if OBJECT is not associated with a database, *DEFAULT-DATABASE*. Join slots are updated but instances of the class on which the join is made are not updated.")) (defgeneric instance-refreshed (object) (:documentation "Provides a hook which is called within an object oriented call to SELECT with a non-nil value of REFRESH when the View Class instance OBJECT has been updated from the database. A method specialised on STANDARD-DB-OBJECT is provided which has no effects. Methods specialised on particular View Classes can be used to specify any operations that need to be made on View Classes instances which have been updated in calls to SELECT.")) (defgeneric update-slot-with-null (instance slotdef) (:documentation "Called to update a slot when its column has a NULL value. If nulls are allowed for the column, the slot's value will be nil, otherwise its value will be set to the result of calling DATABASE-NULL-VALUE on the type of the slot.")) (defgeneric database-pkey-constraint (class database) ) (defgeneric %install-class (class database &key transactions) ) (defgeneric database-generate-column-definition (class slotdef database) ) (defgeneric update-slot-from-db (instance slotdef val) ) (defgeneric key-value-from-db (slotdef value database) ) (defgeneric get-slot-values-from-view (obj slotdeflist values) ) (defgeneric database-output-sql-as-type (type val database db-type) ) (defgeneric read-sql-value (val type database db-type) ) (defgeneric database-add-autoincrement-sequence (class database) (:method (class database) nil) (:documentation "If a database needs to add a sequence for its autoincrement to work, this is where it should go. Default is that it doesnt so just return nil")) (defgeneric database-remove-autoincrement-sequence (class database) (:method (class database) nil) (:documentation "If a database needs to add a sequence for its autoincrement to work, this is where it should go. Default is that it doesnt so just return nil")) (defgeneric auto-increment-sequence-name (class slotdef database) (:documentation "The sequence name to create for this autoincremnt column on this class if returns nil, there is no associated sequence ")) (defmethod auto-increment-sequence-name :around (class slot database) (when (auto-increment-column-p slot database) (call-next-method))) (defgeneric database-last-auto-increment-id (database table column) ) ;; Generation of SQL strings from lisp expressions (defgeneric output-sql (expr database) (:documentation "Writes an SQL string appropriate for DATABASE and corresponding to the lisp expression EXPR to *SQL-STREAM*. The function SQL-OUTPUT is a top-level call for generating SQL strings which initialises *SQL-STREAM*, calls OUTPUT-SQL and reads the generated SQL string from *SQL-STREAM*.")) (defgeneric database-output-sql (expr database) (:documentation "Returns an SQL string appropriate for DATABASE and corresponding to the lisp expression EXPR. DATABASE-OUTPUT-SQL is called by OUTPUT-SQL when no more specific method exists for EXPR.")) (defgeneric output-sql-hash-key (expr database) (:documentation "Returns a list (or other object suitable for use as the key of an EQUAL hash table) which uniquely identifies the arguments EXPR and DATABASE.")) (defgeneric collect-table-refs (sql) ) (defgeneric database-constraint-statement (constraints database) ) (defgeneric database-translate-constraint (constraint database) (:documentation "Given a column constraint returns its database-specific name. For example, auto-increment constraints can have different names in different database engines.")) (defgeneric filter-select-list ( view-class clsql-sys::select-list database) (:documentation "Gives fine grained control over sql to be executed and mapped to slots called with a dummy instance (so that class precedence can be used)") ) (defgeneric view-classes-and-storable-slots (view-class &key to-database-p) (:documentation "A method that collects all the classes and storable slots that need to be read from or written to the database. to-database-p should be T if we are writing this object to the database and nil when we are reading this object from the database")) cl-sql-6.7.2/sql/oodml.lisp0000644000175000017500000016505512651763351014562 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; The CLSQL Object Oriented Data Manipulation Language (OODML). ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defun find-normalized-key (obj) "Find the first / primary key of a normalized object" (find-slot-if obj #'key-slot-p T T)) (defun normalized-key-value (obj) "Normalized classes share a single key for all their key slots" (when (normalizedp (class-of obj)) (easy-slot-value obj (find-normalized-key obj)))) (defun key-qualifier-for-instance (obj &key (database *default-database*) this-class) "Generate a boolean sql-expression that identifies an object by its keys" (let* ((obj-class (or this-class (class-of obj))) (keys (keyslots-for-class obj-class)) (normal-db-value (normalized-key-value obj))) (when keys (labels ((db-value (k) (or normal-db-value (db-value-from-slot k (easy-slot-value obj k) database))) (key-equal-exp (k) (sql-operation '== (generate-attribute-reference obj-class k database) (db-value k)))) (clsql-ands (mapcar #'key-equal-exp keys)))))) (defun generate-attribute-reference (vclass slotdef &optional (database *default-database*)) "Turns key class and slot-def into a sql-expression representing the table and column it comes from used by things like make-select-list, update-slot-from-record" (when (key-or-base-slot-p slotdef) (sql-expression :attribute (database-identifier slotdef database) :table (database-identifier vclass database)))) (defun get-join-slots (class &optional retrieval-method) "Returns list of join slots for a class. if a retrieval method is specified only return slots of that type if the retrieval method is T, nil or :all return all join slots" (assert (member retrieval-method '(nil t :all :immediate :deferred))) (setf class (to-class class)) (let ((all? (member retrieval-method '(nil t :all)))) (loop for slot in (ordered-class-slots class) when (and (join-slot-p slot) (or all? (eql (join-slot-retrieval-method slot) retrieval-method))) collect slot))) (defun immediate-join-slots (class) (get-join-slots class :immediate)) (defmethod choose-database-for-instance ((obj standard-db-object) &optional database) "Determine which database connection to use for a standard-db-object. Errs if none is available." (or (find-if #'(lambda (db) (and db (is-database-open db))) (list (view-database obj) database *default-database*)) (signal-no-database-error nil))) (defmethod update-slot-with-null ((object standard-db-object) slotdef) "sets a slot to the void value of the slot-def (usually nil)" (setf (easy-slot-value object slotdef) (slot-value slotdef 'void-value))) (defmethod update-slot-from-db-value ((instance standard-db-object) slotdef value) "This gets a value from the database and turns it itno a lisp value based on the slot's slot-db-reader or baring that read-sql-value" (declare (optimize (speed 3) #+cmu (extensions:inhibit-warnings 3))) (let* ((slot-reader (view-class-slot-db-reader slotdef)) (slot-type (specified-type slotdef))) (cond ((null value) (update-slot-with-null instance slotdef)) ((null slot-reader) (setf (easy-slot-value instance slotdef) (read-sql-value value (delistify slot-type) (choose-database-for-instance instance) (database-underlying-type (choose-database-for-instance instance))))) (t (etypecase slot-reader ((or symbol function) (setf (easy-slot-value instance slotdef) (apply slot-reader (list value)))) (string (setf (easy-slot-value instance slotdef) (format nil slot-reader value)))))))) (defmethod key-value-from-db (slotdef value database) "TODO: is this deprecated? there are no uses anywhere in clsql" (declare (optimize (speed 3) #+cmu (extensions:inhibit-warnings 3))) (let ((slot-reader (view-class-slot-db-reader slotdef)) (slot-type (specified-type slotdef))) (cond ((and value (null slot-reader)) (read-sql-value value (delistify slot-type) database (database-underlying-type database))) ((null value) nil) ((typep slot-reader 'string) (format nil slot-reader value)) ((typep slot-reader '(or symbol function)) (apply slot-reader (list value))) (t (error "Slot reader is of an unusual type."))))) (defun db-value-from-slot (slotdef val database) (let ((dbwriter (view-class-slot-db-writer slotdef)) (dbtype (specified-type slotdef))) (typecase dbwriter (string (format nil dbwriter val)) ((and (or symbol function) (not null)) (apply dbwriter (list val))) (t (database-output-sql-as-type (typecase dbtype (cons (car dbtype)) (t dbtype)) val database (database-underlying-type database)))))) (defun check-slot-type (slotdef val) (let* ((slot-type (specified-type slotdef)) (basetype (if (listp slot-type) (car slot-type) slot-type))) (when (and slot-type val) (unless (typep val basetype) (error 'sql-user-error :message (format nil "Invalid value ~A in slot ~A, not of type ~A." val (slot-definition-name slotdef) slot-type)))))) (defmethod get-slot-values-from-view (obj slotdeflist values) "Used to copy values from the database into the object used by things like find-all and select" (loop for slot in slotdeflist for value in values do (update-slot-from-db-value obj slot value)) obj) (defclass class-and-slots () ((view-class :accessor view-class :initarg :view-class :initform nil) (slot-defs :accessor slot-defs :initarg :slot-defs :initform nil)) (:documentation "A helper class to keep track of which slot-defs from a table need to be updated, a normalized class might have many of these because each of its parent classes might represent some other table and we need to match which slots came from which parent class/table")) (defun make-class-and-slots (c &optional s) "Create a new class-and-slots object" (make-instance 'class-and-slots :view-class c :slot-defs (listify s) )) (defmethod view-table ((o class-and-slots)) "get the view-table of the view-class of o" (view-table (view-class o))) (defmethod view-table-exp ((o class-and-slots)) (sql-expression :table (view-table o))) (defmethod view-table-exp ((o standard-db-class)) (sql-expression :table (view-table o))) (defmethod attribute-references ((o class-and-slots)) "build sql-ident-attributes for a given class-and-slots" (loop with class = (view-class o) for sd in (slot-defs o) collect (generate-attribute-reference class sd))) (defmethod attribute-value-pairs ((def class-and-slots) (o standard-db-object) database) "for a given class-and-slots and object, create the sql-expression & value pairs that need to be sent to the database" (loop for s in (slot-defs def) for n = (to-slot-name s) when (slot-boundp o n) collect (make-attribute-value-pair s (slot-value o n) database))) (defmethod view-classes-and-slots-by-name ((obj standard-db-object) slots-to-match) "If it's normalized, find the class that actually contains the slot that's tied to the db, otherwise just search the current class " (let* ((view-class (class-of obj)) (normalizedp (normalizedp view-class)) rtns) (labels ((get-c&s-obj (class) (or (find class rtns :key #'view-class) (first (push (make-class-and-slots class) rtns)))) (associate-slot-with-class (class slot) "Find the best class to associate with the slot. If it is normalized then it needs to be a direct slot otherwise it just needs to be on the class." (let ((sd (find-slot-by-name class slot normalizedp nil))) (if sd ;;we found it directly or it's (not normalized) (pushnew sd (slot-defs (get-c&s-obj class))) (when normalizedp (loop for parent in (class-direct-superclasses class) until (associate-slot-with-class parent slot)))) sd))) (loop for in-slot in (listify slots-to-match) do (associate-slot-with-class view-class in-slot))) rtns)) (defun update-auto-increments-keys (class obj database) " handle pulling any autoincrement values into the object Also handles normalized key chaining" (let ((pk-slots (keyslots-for-class class)) (table (view-table class)) new-pk-value) (labels ((do-update (slot &aux (val (easy-slot-value obj slot))) (if val (setf new-pk-value val) (update-slot-from-db-value obj slot (or new-pk-value (setf new-pk-value (database-last-auto-increment-id database table slot)))))) ;; NB: This interacts very strangely with autoincrement keys ;; (see changelog 2014-01-30) (chain-primary-keys (in-class) "This seems kindof wrong, but this is mostly how it was working, so its here to keep the normalized code path working" (when (typep in-class 'standard-db-class) (loop for slot in (ordered-class-slots in-class) when (key-slot-p slot) do (do-update slot))))) (loop for slot in pk-slots do (do-update slot)) (let ((direct-class (to-class obj))) (when (and new-pk-value (normalizedp direct-class)) (chain-primary-keys direct-class))) new-pk-value))) (defmethod %update-instance-helper (class-and-slots obj database &aux (avps (attribute-value-pairs class-and-slots obj database))) "A function to help us update a given table (based on class-and-slots) with values from an object" ;; we dont actually need to update anything on this particular ;; class / parent class (unless avps (return-from %update-instance-helper)) (let* ((view-class (view-class class-and-slots)) (table (view-table view-class)) (table-sql (sql-expression :table table))) ;; view database is the flag we use to tell it was pulled from a database ;; and thus probably needs an update instead of an insert (cond ((view-database obj) (let ((where (key-qualifier-for-instance obj :database database :this-class view-class))) (unless where (error "update-record-from-*: could not generate a where clause for ~a using ~A" obj view-class)) (update-records table-sql :av-pairs avps :where where :database database))) (T ;; was not pulled from the db so insert it ;; avps MUST contain any primary key slots set ;; by previous inserts of the same object into different ;; tables (ie: normalized stuff) (insert-records :into table-sql :av-pairs avps :database database) ;; also handles normalized-class key chaining (update-auto-increments-keys view-class obj database) ;; we dont set view database here, because there could be ;; N of these for each call to update-record-from-* because ;; of normalized classes )) (update-slot-default-values obj class-and-slots))) (defmethod update-record-from-slots ((obj standard-db-object) slots &key (database *default-database*)) "For a given list of slots, update all records associated with those slots and classes. Generally this will update the single record associated with this object, but for normalized classes might update as many records as there are inheritances " (setf slots (listify slots)) (let* ((classes-and-slots (view-classes-and-slots-by-name obj slots)) (database (choose-database-for-instance obj database))) (loop for class-and-slots in classes-and-slots do (%update-instance-helper class-and-slots obj database)) (setf (slot-value obj 'view-database) database)) (values)) (defmethod update-record-from-slot ((obj standard-db-object) slot &key (database *default-database*)) "just call update-records-from-slots which now handles this. This function is only here to maintain backwards compatibility in the public api" (update-record-from-slots obj slot :database database)) (defmethod view-classes-and-storable-slots (class &key to-database-p) "Get a list of all the tables we need to update and the slots on them for non normalized classes we return the class and all its storable slots for normalized classes we return a list of direct slots and the class they came from for each normalized view class to-database-p is provided so that we can read / write different data to the database in different circumstances (specifically clsql-helper:dirty-db-slots-mixin which only updates slots that have changed ) " (setf class (to-class class)) (let* (rtns) (labels ((storable-slots (class) (loop for sd in (slots-for-possibly-normalized-class class) when (and (key-or-base-slot-p sd) ;; we dont want to insert/update auto-increments ;; but we do read them (not (and to-database-p (auto-increment-column-p sd)))) collect sd)) (get-classes-and-slots (class &aux (normalizedp (normalizedp class))) (let ((slots (storable-slots class))) (when slots (push (make-class-and-slots class slots) rtns))) (when normalizedp (loop for new-class in (class-direct-superclasses class) do (when (typep new-class 'standard-db-class) (get-classes-and-slots new-class)))))) (get-classes-and-slots class)) rtns)) (defmethod primary-key-slot-values ((obj standard-db-object) &key class slots ) "Returns the values of all key-slots for a given class" (defaulting class (class-of obj) slots (keyslots-for-class class)) (loop for slot in slots collect (easy-slot-value obj slot))) (defmethod update-slot-default-values ((obj standard-db-object) classes-and-slots) "Makes sure that if a class has unfilled slots that claim to have a default, that we retrieve those defaults from the database TODO: use update-slots-from-record (doesnt exist) instead to batch this!" (loop for class-and-slots in (listify classes-and-slots) do (loop for slot in (slot-defs class-and-slots) do (when (and (slot-has-default-p slot) (not (easy-slot-value obj slot))) (update-slot-from-record obj (to-slot-name slot)))))) (defmethod update-records-from-instance ((obj standard-db-object) &key (database *default-database*)) "Updates the records in the database associated with this object if view-database slot on the object is nil then the object is assumed to be new and is inserted" (let ((database (choose-database-for-instance obj database)) (classes-and-slots (view-classes-and-storable-slots obj :to-database-p t))) (loop for class-and-slots in classes-and-slots do (%update-instance-helper class-and-slots obj database)) (setf (slot-value obj 'view-database) database) (primary-key-slot-values obj))) (defmethod delete-instance-records ((instance standard-db-object) &key database) "Removes the records associated with a given instance (as determined by key-qualifier-for-instance) TODO: Doesnt handle normalized classes at all afaict" (let ((database (choose-database-for-instance instance database)) (vt (sql-expression :table (view-table (class-of instance))))) (if database (let ((qualifier (key-qualifier-for-instance instance :database database))) (delete-records :from vt :where qualifier :database database) (setf (record-caches database) nil) (setf (slot-value instance 'view-database) nil) (values)) (signal-no-database-error database)))) (defmethod update-instance-from-records ((instance standard-db-object) &key (database *default-database*)) "Updates a database object with the current values stored in the database TODO: Should this update immediate join slots similar to build-objects? Can we just call build-objects?, update-objects-joins? " (let* ((classes-and-slots (view-classes-and-storable-slots instance :to-database-p nil)) (vd (choose-database-for-instance instance database))) (labels ((do-update (class-and-slots) (let* ((select-list (make-select-list class-and-slots :do-joins-p nil :database database)) (view-table (sql-table select-list)) (view-qual (key-qualifier-for-instance instance :database vd :this-class (view-class select-list))) (res (when view-qual (first (apply #'select (append (full-select-list select-list) (list :from view-table :where view-qual :result-types nil :database vd))))))) (when res (setf (slot-value instance 'view-database) vd) (get-slot-values-from-view instance (slot-list select-list) res)) ))) (loop for class-and-slots in classes-and-slots do (do-update class-and-slots))))) (defmethod get-slot-value-from-record ((instance standard-db-object) slot &key (database *default-database*)) (let* ((class-and-slot (first (view-classes-and-slots-by-name instance slot))) (view-class (view-class class-and-slot)) (slot-def (first (slot-defs class-and-slot))) (vd (choose-database-for-instance instance database)) (att-ref (first (attribute-references class-and-slot))) (res (first (select att-ref :from (view-table-exp class-and-slot) :where (key-qualifier-for-instance instance :database vd :this-class view-class) :result-types nil :flatp T)))) (values res slot-def))) (defmethod update-slot-from-record ((instance standard-db-object) slot &key (database *default-database*)) "Pulls the value of a given slot form the database and stores that in the appropriate slot on instance" (multiple-value-bind (res slot-def) (get-slot-value-from-record instance slot :database database) (let ((vd (choose-database-for-instance instance database))) (setf (slot-value instance 'view-database) vd) (update-slot-from-db-value instance slot-def res)))) (defvar +no-slot-value+ '+no-slot-value+) (defsql sql-slot-value (:symbol "slot-value") (classname slot &optional (value +no-slot-value+) (database *default-database*)) (let* ((class (find-class classname)) (sld (slotdef-for-slot-with-class slot class))) (if sld (if (eq value +no-slot-value+) (sql-expression :attribute (database-identifier sld database) :table (view-table class)) (db-value-from-slot sld value database)) (error "Unknown slot ~A for class ~A" slot classname)))) (defsql sql-view-class (:symbol "view-class") (classname &optional (database *default-database*)) (declare (ignore database)) (let* ((class (find-class classname))) (unless (view-table class) (error "No view-table for class ~A" classname)) (sql-expression :table (view-table class)))) (deftype tinyint () "An 8-bit integer, this width may vary by SQL implementation." 'integer) (deftype smallint () "An integer smaller than a 32-bit integer. this width may vary by SQL implementation." 'integer) (deftype mediumint () "An integer smaller than a 32-bit integer, but may be larger than a smallint. This width may vary by SQL implementation." 'integer) (deftype bigint () "An integer larger than a 32-bit integer, this width may vary by SQL implementation." 'integer) (deftype varchar (&optional size) "A variable length string for the SQL varchar type." (declare (ignore size)) 'string) (deftype universal-time () "A positive integer as returned by GET-UNIVERSAL-TIME." '(integer 1 *)) (deftype generalized-boolean () "A type which outputs a SQL boolean value, though any lisp type can be stored in the slot." t) #+ignore (deftype char (&optional len) "A lisp type for the SQL CHAR type." `(string ,len)) (defmethod database-get-type-specifier ((type string) args database (db-type t)) "Pass through the literal type as defined in the type string" (declare (ignore args database db-type)) type) (defmethod database-get-type-specifier ((type symbol) args database db-type) (case type (char (if args (format nil "CHAR(~D)" (first args)) "CHAR(1)")) ((varchar string symbol keyword) (if args (format nil "VARCHAR(~A)" (car args)) (format nil "VARCHAR(~D)" *default-string-length*))) ((longchar text) "text") (integer (if args (format nil "INT(~A)" (car args)) "INT")) ((tinyint smallint mediumint) "INT") ((long-float float) (if args (format nil "FLOAT(~A)" (car args)) "FLOAT")) ((bigint universal-time) "BIGINT") (number (cond ((and (consp args) (= (length args) 2)) (format nil "NUMBER(~D,~D)" (first args) (second args))) ((and (consp args) (= (length args) 1)) (format nil "NUMBER(~D)" (first args))) (t "NUMBER"))) (wall-time "TIMESTAMP") (date "DATE") (duration "VARCHAR") (money "INT8") ((boolean generalized-boolean) "BOOL") (t (warn "Could not determine a valid ~A type specifier for ~A ~A ~A, defaulting to VARCHAR " db-type type args database) (format nil "VARCHAR(~D)" *default-string-length*)))) (defun print-readable-symbol (in &aux (*package* (find-package :keyword)) (*print-readably* t)) (prin1-to-string in)) (defmethod database-output-sql-as-type (type val database db-type &aux (*print-circle* t) (*print-array* t) (*print-length* nil) (*print-base* #10r10)) (declare (ignore database)) (cond ((null type) val) ((member type '(boolean generalized-boolean)) ;; booleans handle null differently (case db-type ;; done here so it can be done once ((:mssql :mysql) (if val 1 0)) (otherwise (if val "t" "f")))) ((null val) (when (next-method-p) (call-next-method))) (t (case type ((or symbol keyword) (print-readable-symbol val)) (string val) (char (etypecase val (character (write-to-string val)) (string val))) (float (format nil "~F" val)) ((list vector array) (prin1-to-string val)) (otherwise (if (next-method-p) (call-next-method) val)))))) (defmethod read-sql-value :around (val type database db-type ;; never eval while reading values, always read base 10 &aux *read-eval* (*read-base* #10r10)) (declare (ignore db-type)) (cond ;; null value or type ((or (null val) (equalp "nil" val) (eql 'null val) (eql 'null type)) nil) ;; no specified type or already the right type ((or (null type) (ignore-errors (typep val type))) val) ;; actually convert (t (let ((res (handler-bind ;; all errors should be converted to sql-value-conversion-error ((error (lambda (c) (unless (typep c 'sql-value-conversion-error) ;; this was blowing up the tests till I ;; unbound *debugger-hook* not sure the answer, ;; as this is also imensely useful in actually ;; finding bugs below this point (when *debugger-hook* (invoke-debugger c)) (error-converting-value val type database))))) (call-next-method)))) ;; if we didnt get the right type after converting, we should probably ;; error right away (maybe-error-converting-value res val type database))))) (defmethod read-sql-value (val type database db-type) "read a sql value, from :around read-eval is disabled read numbers in base 10" ;; errors, nulls and preconverted types are already handled in around (typecase type (symbol (case type ((string varchar) val) (char (string (schar val 0))) ((or keyword symbol) (read-from-string val)) ((smallint mediumint bigint integer universal-time) (parse-integer val)) ((double-float float) ;; ensure that whatever we got is coerced to a float of the correct ;; type (eg: 1=>1.0d0) (float (etypecase val (string (let ((*read-default-float-format* (ecase type (float 'single-float) (double-float 'double-float)))) (read-from-string val))) ;; maybe wrong type of float (float val)) (if (eql type 'double-float) 1.0d0 1.0s0))) (number (read-decimal-value val)) ((boolean generalized-boolean) (if (member val '(nil t)) val (etypecase val (string (when (member val '("1" "t" "true" "y") :test #'string-equal) t)) (number (not (zerop val)))))) ((wall-time duration) (parse-timestring val)) (date (parse-datestring val)) (list (read-from-string val)) (t (error-converting-value val type database)))) (t (typecase val (string (read-from-string val)) (t (error-converting-value val type database)))))) ;; ------------------------------------------------------------ ;; Logic for 'faulting in' :join slots ;; this works, but is inefficient requiring (+ 1 n-rows) ;; SQL queries #+ignore (defun fault-join-target-slot (class object slot-def) (let* ((res (fault-join-slot-raw class object slot-def)) (dbi (view-class-slot-db-info slot-def)) (target-name (gethash :target-slot dbi)) (target-class (find-class target-name))) (when res (mapcar (lambda (obj) (list (car (fault-join-slot-raw target-class obj (find target-name (class-slots (class-of obj)) :key #'slot-definition-name))) obj)) res) #+ignore ;; this doesn't work when attempting to call slot-value (mapcar (lambda (obj) (cons obj (slot-value obj ts))) res)))) (defun fault-join-target-slot (class object slot-def) (let* ((dbi (view-class-slot-db-info slot-def)) (ts (gethash :target-slot dbi)) (jc (gethash :join-class dbi)) (jc-view-table (view-table (find-class jc))) (tdbi (view-class-slot-db-info (find ts (class-slots (find-class jc)) :key #'slot-definition-name))) (retrieval (gethash :retrieval tdbi)) (tsc (gethash :join-class tdbi)) (ts-view-table (view-table (find-class tsc))) (jq (join-qualifier class object slot-def)) (key (slot-value object (gethash :home-key dbi)))) (when jq (ecase retrieval (:immediate (let ((res (find-all (list tsc) :inner-join (sql-expression :table jc-view-table) :on (sql-operation '== (sql-expression :attribute (gethash :foreign-key tdbi) :table ts-view-table) (sql-expression :attribute (gethash :home-key tdbi) :table jc-view-table)) :where jq :result-types :auto :database (choose-database-for-instance object)))) (mapcar #'(lambda (i) (let* ((instance (car i)) (jcc (make-instance jc :view-database (choose-database-for-instance instance)))) (setf (slot-value jcc (gethash :foreign-key dbi)) key) (setf (slot-value jcc (gethash :home-key tdbi)) (slot-value instance (gethash :foreign-key tdbi))) (list instance jcc))) res))) (:deferred ;; just fill in minimal slots (mapcar #'(lambda (k) (let ((instance (make-instance tsc :view-database (choose-database-for-instance object))) (jcc (make-instance jc :view-database (choose-database-for-instance object))) (fk (car k))) (setf (slot-value instance (gethash :home-key tdbi)) fk) (setf (slot-value jcc (gethash :foreign-key dbi)) key) (setf (slot-value jcc (gethash :home-key tdbi)) fk) (list instance jcc))) (select (sql-expression :attribute (gethash :foreign-key tdbi) :table jc-view-table) :from (sql-expression :table jc-view-table) :where jq :database (choose-database-for-instance object)))))))) ;;; Remote Joins (defvar *default-update-objects-max-len* nil "The default value to use for the MAX-LEN keyword argument to UPDATE-OBJECT-JOINS.") (defun %update-objects-joins-slot-defs (class slot-names) "Get the slot definitions for the joins slots specified as slot-names if slot-names is :immediate, :deferred or (or :all t) return all of that type of slot definitions" (setf class (to-class class)) (when (eq t slot-names) (setf slot-names :all)) (etypecase slot-names (null nil) (keyword ;; slot-names is the retrieval type of the join-slot or :all (get-join-slots class slot-names)) ((or symbol list) (loop for slot in (listify slot-names) for def = (find-slot-by-name class slot) when (and def (join-slot-p def)) collecting def unless (and def (join-slot-p def)) do (warn "Unable to find join slot named ~S in class ~S." slot class))))) (defun get-joined-objects (objects slotdef &key force-p (batch-size *default-update-objects-max-len*)) "Given a list of objects and a join slot-def get the objects that need to be joined to the input objects we will query in batches as large as batch-size" (when (join-slot-p slotdef) (let* ((slot-name (to-slot-name slotdef)) (join-class (join-slot-class-name slotdef)) (home-key (join-slot-info-value slotdef :home-key)) (foreign-key (join-slot-info-value slotdef :foreign-key)) (foreign-key-values (remove-duplicates (loop for object in (listify objects) for hk = (slot-value object home-key) when (or force-p (not (slot-boundp object slot-name))) collect hk) :test #'equal))) ;; we want to retrieve at most batch-size objects per query (flet ((fetch (keys) (find-all (list join-class) :where (make-instance 'sql-relational-exp :operator 'in :sub-expressions (list (sql-expression :attribute foreign-key) keys)) :result-types :auto :flatp t))) (if (null batch-size) (fetch foreign-key-values) (loop for keys = (pop-n foreign-key-values batch-size) while keys nconcing (fetch keys))))))) (defun %object-joins-from-list (object slot joins force-p ) "Given a list of objects that we are trying to join to, pull the correct ones for this object" (when (or force-p (not (slot-boundp object (to-slot-name slot)))) (let ((home-key (join-slot-info-value slot :home-key)) (foreign-key (join-slot-info-value slot :foreign-key))) (loop for join in joins when (equal (slot-value join foreign-key) (slot-value object home-key)) collect join)))) (defun update-objects-joins (objects &key (slots :immediate) (force-p t) class-name (max-len *default-update-objects-max-len*)) "Updates from the records of the appropriate database tables the join slots specified by SLOTS in the supplied list of View Class instances OBJECTS. A simpler method of causing a join-slot to be requeried is to set it to unbound, then request it again. This function has efficiency gains where join-objects are shared among the `objects` (querying all join-objects, then attaching them appropriately to each of the `objects`) SLOTS can be one of: * :immediate (DEFAULT) - refresh join slots created with :retrieval :immediate * :deferred - refresh join slots created with :retrieval :deferred * :all,t - refresh all join slots regardless of :retrieval * list of symbols - which explicit slots to refresh * a single symobl - what slot to refresh CLASS-NAME is used to specify the View Class of all instance in OBJECTS and default to nil which means that the class of the first instance in OBJECTS is used. FORCE-P is t by default which means that all join slots are updated whereas a value of nil means that only unbound join slots are updated. MAX-LEN defaults to *DEFAULT-UPDATE-OBJECTS-MAX-LEN* When non-nil this is essentially a batch size for the max number of objects to query from the database at a time. If we need more than max-len we loop till we have all the objects" (assert (or (null max-len) (plusp max-len))) (when objects (defaulting class-name (class-name (class-of (first objects)))) (let* ((class (find-class class-name)) (slotdefs (%update-objects-joins-slot-defs class slots))) (loop for slotdef in slotdefs ;; all the joins we will need for *all* the objects ;; which then get filtered below for each object for joins = (unless (join-slot-info-value slotdef :target-slot) (get-joined-objects objects slotdef :force-p force-p :batch-size max-len)) do (loop for object in objects for these-joins = ;; the joins just for this object (filtered from above) ;; or retrieved via fault-join-target-slot (or (%object-joins-from-list object slotdef joins force-p) (when (join-slot-info-value slotdef :target-slot) (fault-join-target-slot class object slotdef))) ;; when this object has joined-objects copy them in to the correct slot do (when these-joins (setf (easy-slot-value object slotdef) (if (join-slot-info-value slotdef :set) these-joins (first these-joins)))))))) (values)) (defun fault-join-slot-raw (class object slot-def) (let* ((dbi (view-class-slot-db-info slot-def)) (jc (gethash :join-class dbi))) (let ((jq (join-qualifier class object slot-def))) (when jq (select jc :where jq :flatp t :result-types nil :database (choose-database-for-instance object)))))) (defun fault-join-slot (class object slot-def) (let* ((dbi (view-class-slot-db-info slot-def)) (ts (gethash :target-slot dbi)) (dbi-set (gethash :set dbi))) (if (and ts dbi-set) (fault-join-target-slot class object slot-def) (let ((res (fault-join-slot-raw class object slot-def))) (when res (cond ((and ts (not dbi-set)) (mapcar (lambda (obj) (slot-value obj ts)) res)) ((and (not ts) (not dbi-set)) (car res)) ((and (not ts) dbi-set) res))))))) (defun update-fault-join-normalized-slot (class object slot-def) (if (and (normalizedp class) (key-slot-p slot-def)) (setf (easy-slot-value object slot-def) (normalized-key-value object)) (update-slot-from-record object slot-def))) (defun all-home-keys-have-values-p (object slot-def) "Do all of the home-keys have values ?" (let ((home-keys (join-slot-info-value slot-def :home-key))) (loop for key in (listify home-keys) always (easy-slot-value object key)))) (defun join-qualifier (class object slot-def) "Builds the join where clause based on the keys of the join slot and values of the object" (declare (ignore class)) (let* ((jc (join-slot-class slot-def)) ;;(ts (gethash :target-slot dbi)) ;;(tsdef (if ts (slotdef-for-slot-with-class ts jc))) (foreign-keys (listify (join-slot-info-value slot-def :foreign-key))) (home-keys (listify (join-slot-info-value slot-def :home-key)))) (when (all-home-keys-have-values-p object slot-def) (clsql-ands (loop for hk in home-keys for fk in foreign-keys for fksd = (slotdef-for-slot-with-class fk jc) for fk-sql = (typecase fk (symbol (sql-expression :attribute (database-identifier fksd nil) :table (database-identifier jc nil))) (t fk)) for hk-val = (typecase hk ((or symbol view-class-effective-slot-definition view-class-direct-slot-definition) (easy-slot-value object hk)) (t hk)) collect (sql-operation '== fk-sql hk-val)))))) (defmethod select-table-sql-expr ((table T)) "Turns an object representing a table into the :from part of the sql expression that will be executed " (sql-expression :table (view-table table))) (defun select-reference-equal (r1 r2) "determines if two sql select references are equal using database identifier equal" (flet ((id-of (r) (etypecase r (cons (cdr r)) (sql-ident-attribute r)))) (database-identifier-equal (id-of r1) (id-of r2)))) (defun join-slot-qualifier (class join-slot) "Creates a sql-expression expressing the join between the home-key on the table and its respective key on the joined-to-table" (sql-operation '== (sql-expression :attribute (join-slot-info-value join-slot :foreign-key) :table (view-table (join-slot-class join-slot))) (sql-expression :attribute (join-slot-info-value join-slot :home-key) :table (view-table class)))) (defun all-immediate-join-classes-for (classes) "returns a list of all join-classes needed for a list of classes" (loop for class in (listify classes) appending (loop for slot in (immediate-join-slots class) collect (join-slot-class slot)))) (defun %tables-for-query (classes from where inner-joins) "Given lists of classes froms wheres and inner-join compile a list of tables that should appear in the FROM section of the query. This includes any immediate join classes from each of the classes" (let ((inner-join-tables (collect-table-refs (listify inner-joins)))) (loop for tbl in (append (mapcar #'select-table-sql-expr classes) (mapcar #'select-table-sql-expr (all-immediate-join-classes-for classes)) (collect-table-refs (listify where)) (collect-table-refs (listify from))) when (and tbl (not (find tbl rtn :test #'database-identifier-equal)) ;; TODO: inner-join is currently hacky as can be (not (find tbl inner-join-tables :test #'database-identifier-equal))) collect tbl into rtn finally (return rtn)))) (defclass select-list () ((view-class :accessor view-class :initarg :view-class :initform nil) (select-list :accessor select-list :initarg :select-list :initform nil) (slot-list :accessor slot-list :initarg :slot-list :initform nil) (joins :accessor joins :initarg :joins :initform nil) (join-slots :accessor join-slots :initarg :join-slots :initform nil)) (:documentation "Collects the classes, slots and their respective sql representations so that update-instance-from-recors, find-all, build-objects can share this info and calculate it once. Joins are select-lists for each immediate join-slot but only if make-select-list is called with do-joins-p")) (defmethod view-table ((o select-list)) (view-table (view-class o))) (defmethod sql-table ((o select-list)) (sql-expression :table (view-table o))) (defmethod filter-select-list ((c clsql-sys::standard-db-object) (sl clsql-sys::select-list) database) sl) (defun make-select-list (class-and-slots &key (do-joins-p nil) (database *default-database*)) "Make a select-list for the current class (or class-and-slots) object." (let* ((class-and-slots (etypecase class-and-slots (class-and-slots class-and-slots) ((or symbol standard-db-class) ;; find the first class with slots for us to select (this should be) ;; the first of its classes / parent-classes with slots (first (reverse (view-classes-and-storable-slots (to-class class-and-slots) :to-database-p nil)))))) (class (view-class class-and-slots)) (join-slots (when do-joins-p (immediate-join-slots class)))) (multiple-value-bind (slots sqls) (loop for slot in (slot-defs class-and-slots) for sql = (generate-attribute-reference class slot) collect slot into slots collect sql into sqls finally (return (values slots sqls))) (unless slots (error "No slots of type :base in view-class ~A" (class-name class))) (let ((sl (make-instance 'select-list :view-class class :select-list sqls :slot-list slots :join-slots join-slots ;; only do a single layer of join objects :joins (when do-joins-p (loop for js in join-slots collect (make-select-list (join-slot-class js) :do-joins-p nil :database database)))))) (filter-select-list (make-instance class) sl database) sl)))) (defun full-select-list ( select-lists ) "Returns a list of sql-ref of things to select for the given classes THIS NEEDS TO MATCH THE ORDER OF build-objects " (loop for s in (listify select-lists) appending (select-list s) appending (loop for join in (joins s) appending (select-list join)))) (defun build-objects (select-lists row database &optional existing-instances) "Used by find-all to build objects. THIS NEEDS TO MATCH THE ORDER OF FULL-SELECT-LIST TODO: this caching scheme seems bad for a number of reasons * order is not guaranteed so references being held by one object might change to represent a different database row (seems HIGHLY suspect) * also join objects are overwritten rather than refreshed TODO: the way we handle immediate joins seems only valid if it is a single object. I suspect that making a :set :immediate join column would result in an invalid number of objects returned from the database, because there would be multiple rows per object, but we would return an object per row " (setf existing-instances (listify existing-instances)) (loop for select-list in select-lists for class = (view-class select-list) for existing = (pop existing-instances) for object = (or existing (make-instance class :view-database database)) do (loop for slot in (slot-list select-list) do (update-slot-from-db-value object slot (pop row))) do (loop for join-slot in (join-slots select-list) for join in (joins select-list) for join-class = (view-class join) for join-object = (setf (easy-slot-value object join-slot) (make-instance join-class)) do (loop for slot in (slot-list join) do (update-slot-from-db-value join-object slot (pop row)))) do (when existing (instance-refreshed object)) collect object)) (defun find-all (view-classes &rest args &key all set-operation distinct from where group-by having order-by offset limit refresh flatp result-types inner-join on (database *default-database*) instances parameters) "Called by SELECT to generate object query results when the View Classes VIEW-CLASSES are passed as arguments to SELECT. TODO: the caching scheme of passing in instances and overwriting their values seems bad for a number of reasons * order is not guaranteed so references being held by one object might change to represent a different database row (seems HIGHLY suspect) TODO: the way we handle immediate joins seems only valid if it is a single object. I suspect that making a :set :immediate join column would result in an invalid number of objects returned from the database, because there would be multiple objects returned from the database " (declare (ignore all set-operation group-by having offset limit on parameters distinct order-by) (dynamic-extent args)) (let* ((args (filter-plist args :from :where :flatp :additional-fields :result-types :instances)) (*db-deserializing* t) (sclasses (mapcar #'to-class view-classes)) (tables (%tables-for-query sclasses from where inner-join)) (join-where (loop for class in sclasses appending (loop for slot in (immediate-join-slots class) collect (join-slot-qualifier class slot)))) (select-lists (loop for class in sclasses collect (make-select-list class :do-joins-p t :database database))) (full-select-list (full-select-list select-lists)) (where (clsql-ands (append (listify where) (listify join-where)))) #| (_ (format t "~&sclasses: ~W~%ijc: ~W~%tables: ~W~%" sclasses immediate-join-classes tables)) |# (rows (apply #'select (append full-select-list (list :from tables :result-types result-types :where where) args))) (return-objects (loop for row in rows for old-objs = (pop instances) for objs = (build-objects select-lists row database (when refresh old-objs)) collecting (if flatp (delist-if-single objs) objs)))) return-objects)) (defmethod instance-refreshed ((instance standard-db-object))) (defvar *default-caching* t "Controls whether SELECT caches objects by default. The CommonSQL specification states caching is on by default.") (defun select (&rest select-all-args) "Executes a query on DATABASE, which has a default value of *DEFAULT-DATABASE*, specified by the SQL expressions supplied using the remaining arguments in SELECT-ALL-ARGS. The SELECT argument can be used to generate queries in both functional and object oriented contexts. In the functional case, the required arguments specify the columns selected by the query and may be symbolic SQL expressions or strings representing attribute identifiers. Type modified identifiers indicate that the values selected from the specified column are converted to the specified lisp type. The keyword arguments ALL, DISTINCT, FROM, GROUP-by, HAVING, ORDER-BY, SET-OPERATION and WHERE are used to specify, using the symbolic SQL syntax, the corresponding components of the SQL query generated by the call to SELECT. RESULT-TYPES is a list of symbols which specifies the lisp type for each field returned by the query. If RESULT-TYPES is nil all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field. FIELD-NAMES is t by default which means that the second value returned is a list of strings representing the columns selected by the query. If FIELD-NAMES is nil, the list of column names is not returned as a second value. In the object oriented case, the required arguments to SELECT are symbols denoting View Classes which specify the database tables to query. In this case, SELECT returns a list of View Class instances whose slots are set from the attribute values of the records in the specified table. Slot-value is a legal operator which can be employed as part of the symbolic SQL syntax used in the WHERE keyword argument to SELECT. REFRESH is nil by default which means that the View Class instances returned are retrieved from a cache if an equivalent call to SELECT has previously been issued. If REFRESH is true, the View Class instances returned are updated as necessary from the database and the generic function INSTANCE-REFRESHED is called to perform any necessary operations on the updated instances. In both object oriented and functional contexts, FLATP has a default value of nil which means that the results are returned as a list of lists. If FLATP is t and only one result is returned for each record selected in the query, the results are returned as elements of a list." (multiple-value-bind (target-args qualifier-args) (query-get-selections select-all-args) (unless (or *default-database* (getf qualifier-args :database)) (signal-no-database-error nil)) (let ((caching (getf qualifier-args :caching *default-caching*)) (result-types (getf qualifier-args :result-types :auto)) (refresh (getf qualifier-args :refresh nil)) (database (getf qualifier-args :database *default-database*))) (cond ((and target-args (every #'(lambda (arg) (and (symbolp arg) (find-class arg nil))) target-args)) (setf qualifier-args (filter-plist qualifier-args :caching :refresh :result-types)) ;; Add explicity table name to order-by if not specified and only ;; one selected table. This is required so FIND-ALL won't duplicate ;; the field (let ((order-by (getf qualifier-args :order-by))) (when (and order-by (= 1 (length target-args))) (let ((table-name (view-table (find-class (car target-args)))) (order-by-list (copy-seq (listify order-by)))) (labels ((sv (val name) (ignore-errors (slot-value val name))) (set-table-if-needed (val) (typecase val (sql-ident-attribute (handler-case (if (sv val 'qualifier) val (make-instance 'sql-ident-attribute :name (sv val 'name) :qualifier table-name)) (simple-error () ;; TODO: Check for a specific error we expect ))) (cons (cons (set-table-if-needed (car val)) (cdr val))) (t val)))) (setf order-by-list (loop for i from 0 below (length order-by-list) for id in order-by-list collect (set-table-if-needed id)))) (setf (getf qualifier-args :order-by) order-by-list)))) (cond ((null caching) (apply #'find-all target-args :result-types result-types :refresh refresh qualifier-args)) (t (let ((cached (records-cache-results target-args qualifier-args database))) (if (and cached (not refresh)) cached (let ((results (apply #'find-all target-args :result-types :auto :refresh refresh :instances cached qualifier-args))) (setf (records-cache-results target-args qualifier-args database) results) results)))))) (t (let* ((expr (apply #'make-query select-all-args)) (parameters (second (member :parameters select-all-args))) (specified-types (mapcar #'(lambda (attrib) (if (typep attrib 'sql-ident-attribute) (let ((type (slot-value attrib 'type))) (if type type t)) t)) (slot-value expr 'selections))) (flatp (getf qualifier-args :flatp)) (field-names (getf qualifier-args :field-names t))) (when parameters (setf expr (command-object (sql-output expr database) parameters))) (query expr :flatp flatp :result-types ;; specifying a type for an attribute overrides result-types (if (some #'(lambda (x) (not (eq t x))) specified-types) specified-types result-types) :field-names field-names :database database))))))) (defun compute-records-cache-key (targets qualifiers) (list targets (do ((args *select-arguments* (cdr args)) (results nil)) ((null args) results) (let* ((arg (car args)) (value (getf qualifiers arg))) (when value (push (list arg (typecase value (cons (cons (sql (car value)) (cdr value))) (%sql-expression (sql value)) (t value))) results)))))) (defun records-cache-results (targets qualifiers database) (when (record-caches database) (gethash (compute-records-cache-key targets qualifiers) (record-caches database)))) (defun (setf records-cache-results) (results targets qualifiers database) (unless (record-caches database) (setf (record-caches database) (make-weak-hash-table :test 'equal))) (setf (gethash (compute-records-cache-key (copy-list targets) qualifiers) (record-caches database)) results) results) ;;; Serialization functions (defun write-instance-to-stream (obj stream) "Writes an instance to a stream where it can be later be read. NOTE: an error will occur if a slot holds a value which can not be written readably." (let* ((class (class-of obj)) (alist '())) (dolist (slot (ordered-class-slots (class-of obj))) (let ((name (slot-definition-name slot))) (when (and (not (eq 'view-database name)) (slot-boundp obj name)) (push (cons name (slot-value obj name)) alist)))) (setq alist (reverse alist)) (write (cons (class-name class) alist) :stream stream :readably t)) obj) (defun read-instance-from-stream (stream) (let ((raw (read stream nil nil))) (when raw (let ((obj (make-instance (car raw)))) (dolist (pair (cdr raw)) (setf (slot-value obj (car pair)) (cdr pair))) obj)))) cl-sql-6.7.2/sql/ooddl.lisp0000644000175000017500000002506412303270414014527 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; The CLSQL Object Oriented Data Definitional Language (OODDL) ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass standard-db-object () ((view-database :initform nil :initarg :view-database :reader view-database :db-kind :virtual)) (:metaclass standard-db-class) (:documentation "Superclass for all CLSQL View Classes.")) (defparameter *default-string-length* 255 "The length of a string which does not have a user-specified length.") (defvar *db-auto-sync* nil "A non-nil value means that creating View Class instances or setting their slots automatically creates/updates the corresponding records in the underlying database.") (defvar *db-deserializing* nil) (defvar *db-initializing* nil) (defmethod slot-value-using-class ((class standard-db-class) instance slot-def) "When a slot is unbound but should contain a join object or a value from a normalized view-class, then retrieve and set those slots, so the value can be returned" (declare (optimize (speed 3))) (unless *db-deserializing* (let* ((slot-name (%svuc-slot-name slot-def)) (slot-object (%svuc-slot-object slot-def class))) (unless (slot-boundp instance slot-name) (let ((*db-deserializing* t)) (cond ((join-slot-p slot-def) (setf (slot-value instance slot-name) (if (view-database instance) (fault-join-slot class instance slot-object) ;; TODO: you could in theory get a join object even if ;; its joined-to object was not in the database nil ))) ((not-direct-normalized-slot-p class slot-def) (if (view-database instance) (update-fault-join-normalized-slot class instance slot-def) (setf (slot-value instance slot-name) nil)))))))) (call-next-method)) (defmethod (setf slot-value-using-class) (new-value (class standard-db-class) instance slot-def) "Handle auto syncing values to the database if *db-auto-sync* is t" (declare (ignore new-value)) (let* ((slot-name (%svuc-slot-name slot-def)) (slot-object (%svuc-slot-object slot-def class)) (slot-kind (view-class-slot-db-kind slot-object))) (prog1 (call-next-method) (when (and *db-auto-sync* (not *db-initializing*) (not *db-deserializing*) (not (eql slot-kind :virtual))) (update-record-from-slot instance slot-name))))) (defmethod initialize-instance ((object standard-db-object) &rest all-keys &key &allow-other-keys) (declare (ignore all-keys)) (let ((*db-initializing* t)) (call-next-method) (when (and *db-auto-sync* (not *db-deserializing*)) (update-records-from-instance object)))) ;; ;; Build the database tables required to store the given view class ;; (defun create-view-from-class (view-class-name &key (database *default-database*) (transactions t)) "Creates a table as defined by the View Class VIEW-CLASS-NAME in DATABASE which defaults to *DEFAULT-DATABASE*." (let ((tclass (find-class view-class-name))) (if tclass (let ((*default-database* database) (pclass (car (class-direct-superclasses tclass)))) (when (and (normalizedp tclass) (not (table-exists-p pclass))) (create-view-from-class (class-name pclass) :database database :transactions transactions)) (%install-class tclass database :transactions transactions)) (error "Class ~s not found." view-class-name))) (values)) (defmethod auto-increment-column-p (slotdef &optional (database clsql-sys:*default-database*)) (declare (ignore database)) (or (intersection +auto-increment-names+ (listify (view-class-slot-db-constraints slotdef))) (slot-value slotdef 'autoincrement-sequence))) (defmethod %install-class ((self standard-db-class) database &key (transactions t)) (let ((schemadef '()) (ordered-slots (slots-for-possibly-normalized-class self))) (dolist (slotdef ordered-slots) (let ((res (database-generate-column-definition self slotdef database))) (when res (push res schemadef)))) (if (not schemadef) (unless (normalizedp self) (error "Class ~s has no :base slots" self)) (progn (database-add-autoincrement-sequence self database) (create-table (sql-expression :table (database-identifier self database)) (nreverse schemadef) :database database :transactions transactions :constraints (database-pkey-constraint self database)) (push self (database-view-classes database))))) t) (defmethod database-pkey-constraint ((class standard-db-class) database) ;; Keylist will always be a list of escaped-indentifier (let ((keylist (mapcar #'(lambda (x) (escaped-database-identifier x database)) (keyslots-for-class class))) (table (escaped (combine-database-identifiers (list class 'PK) database)))) (when keylist (format nil "CONSTRAINT ~A PRIMARY KEY (~{~A~^,~})" table keylist)))) (defmethod database-generate-column-definition (class slotdef database) (declare (ignore class)) (when (key-or-base-slot-p slotdef) (let ((cdef (list (sql-expression :attribute (database-identifier slotdef database)) (specified-type slotdef)))) (setf cdef (append cdef (list (view-class-slot-db-type slotdef)))) (let ((const (view-class-slot-db-constraints slotdef))) (when const (setq cdef (append cdef (listify const))))) cdef))) ;; ;; Drop the tables which store the given view class ;; (defun drop-view-from-class (view-class-name &key (database *default-database*) (owner nil)) "Removes a table defined by the View Class VIEW-CLASS-NAME from DATABASE which defaults to *DEFAULT-DATABASE*." (let ((tclass (find-class view-class-name))) (if tclass (let ((*default-database* database)) (%uninstall-class tclass :owner owner)) (error "Class ~s not found." view-class-name))) (values)) (defun %uninstall-class (self &key (database *default-database*) (owner nil)) (drop-table (sql-expression :table (database-identifier self database)) :if-does-not-exist :ignore :database database :owner owner) (database-remove-autoincrement-sequence self database) (setf (database-view-classes database) (remove self (database-view-classes database)))) ;; ;; List all known view classes ;; (defun list-classes (&key (test #'identity) (root-class (find-class 'standard-db-object)) (database *default-database*)) "Returns a list of all the View Classes which are connected to DATABASE, which defaults to *DEFAULT-DATABASE*, and which descend from the class ROOT-CLASS and which satisfy the function TEST. By default ROOT-CLASS is STANDARD-DB-OBJECT and TEST is IDENTITY." (flet ((find-superclass (class) (member root-class (class-precedence-list class)))) (let ((view-classes (and database (database-view-classes database)))) (when view-classes (remove-if #'(lambda (c) (or (not (funcall test c)) (not (find-superclass c)))) view-classes))))) ;; ;; Define a new view class ;; (defmacro def-view-class (class supers slots &rest cl-options) "Creates a View Class called CLASS whose slots SLOTS can map onto the attributes of a table in a database. If SUPERS is nil then the superclass of CLASS will be STANDARD-DB-OBJECT, otherwise SUPERS is a list of superclasses for CLASS which must include STANDARD-DB-OBJECT or a descendent of this class. The syntax of DEFCLASS is extended through the addition of a class option :base-table which defines the database table onto which the View Class maps and which defaults to CLASS. The DEFCLASS syntax is also extended through additional slot options. The :db-kind slot option specifies the kind of DB mapping which is performed for this slot and defaults to :base which indicates that the slot maps to an ordinary column of the database table. A :db-kind value of :key indicates that this slot is a special kind of :base slot which maps onto a column which is one of the unique keys for the database table, the value :join indicates this slot represents a join onto another View Class which contains View Class objects, and the value :virtual indicates a standard CLOS slot which does not map onto columns of the database table. If a slot is specified with :db-kind :join, the slot option :db-info contains a list which specifies the nature of the join. For slots of :db-kind :base or :key, the :type slot option has a special interpretation such that Lisp types, such as string, integer and float are automatically converted into appropriate SQL types for the column onto which the slot maps. This behaviour may be over-ridden using the :db-type slot option which is a string specifying the vendor-specific database type for this slot's column definition in the database. The :column slot option specifies the name of the SQL column which the slot maps onto, if :db-kind is not :virtual, and defaults to the slot name. The :void-value slot option specifies the value to store if the SQL value is NULL and defaults to NIL. The :db-constraints slot option is a string representing an SQL table constraint expression or a list of such strings." `(progn (defclass ,class ,supers ,slots ,@(if (find :metaclass `,cl-options :key #'car) `,cl-options (cons '(:metaclass clsql-sys::standard-db-class) `,cl-options))) (finalize-inheritance (find-class ',class)) (find-class ',class))) (defun keyslots-for-class (class) (slot-value class 'key-slots)) cl-sql-6.7.2/sql/base-classes.lisp0000644000175000017500000000521311335067642016000 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: base-classes.lisp ;;;; Purpose: Base classes for high-level SQL interface ;;;; Programmers: Kevin M. Rosenberg based on ;;;; original code by Pierre R. Mai ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass database () ((name :initform nil :initarg :name :reader database-name) (connection-spec :initform nil :initarg :connection-spec :reader connection-spec :documentation "Required to use connection pool.") (database-type :initarg :database-type :initform :unknown :reader database-type) (encoding :initarg :encoding :initform nil :documentation "External format character encoding.") (state :initform :closed :reader database-state) (autocommit :initform t :accessor database-autocommit) (command-recording-stream :accessor command-recording-stream :initform nil) (result-recording-stream :accessor result-recording-stream :initform nil) (record-caches :accessor record-caches :initform nil) (view-classes :accessor database-view-classes :initform nil) (transaction-level :initform 0 :accessor transaction-level) (transaction :initform nil :accessor transaction) (conn-pool :initform nil :initarg :conn-pool :accessor conn-pool) (attribute-cache :initform (make-hash-table :size 100 :test 'equal) :accessor attribute-cache :documentation "Internal cache of table attributes. It is keyed by table-name. Values are a list of ACTION specified for table and any cached value of list-attributes-types.")) (:documentation "This class is the supertype of all databases handled by CLSQL.")) (defmethod print-object ((object database) stream) (print-unreadable-object (object stream :type t :identity t) (format stream "~A ~A" (if (slot-boundp object 'name) (database-name object) "") (database-state object))) object) (setf (documentation 'database-name 'function) "Returns the name of a database.") cl-sql-6.7.2/sql/pool.lisp0000644000175000017500000001701112473715066014407 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: pool.lisp ;;;; Purpose: Support function for connection pool ;;;; Programmers: Kevin M. Rosenberg, Marc Battyani ;;;; Date Started: Apr 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defparameter *db-pool-max-free-connections* 4 "Threshold of free-connections in the pool before we disconnect a database rather than returning it to the pool. NIL for no limit. This is really a heuristic that should, on avg keep the free connections about this size.") (defvar *db-pool* (make-hash-table :test #'equal)) (defvar *db-pool-lock* (make-process-lock "DB Pool lock")) (defclass conn-pool () ((connection-spec :accessor connection-spec :initarg :connection-spec) (database-type :accessor pool-database-type :initarg :pool-database-type) (free-connections :accessor free-connections :initform nil) (all-connections :accessor all-connections :initform nil) (lock :accessor conn-pool-lock :initform (make-process-lock "Connection pool")))) (defun acquire-from-pool (connection-spec database-type &optional pool (encoding *default-encoding*)) "Try to find a working database connection in the pool or create a new one if needed. This performs 1 query against the DB to ensure it's still valid. When possible (postgres, mssql) that query will be a reset command to put the connection back into its default state." (unless (typep pool 'conn-pool) (setf pool (find-or-create-connection-pool connection-spec database-type))) (or (loop for pconn = (with-process-lock ((conn-pool-lock pool) "Acquire") (pop (free-connections pool))) always pconn thereis ;; test if connection still valid. ;; (e.g. db reboot -> invalid connection ) (handler-case (progn (database-acquire-from-conn-pool pconn) pconn) (sql-database-error (e) ;; we could check for a specific error, ;; but, it's safer just to disconnect the pooled conn for any error ? (warn "Database connection ~S had an error while acquiring from the pool: ~S Disconnecting.~%" pconn e) ;;run database disconnect to give chance for cleanup ;;there, then remove it from the lists of connected ;;databases. (%pool-force-disconnect pconn) (with-process-lock ((conn-pool-lock pool) "remove dead conn") (setf (all-connections pool) (delete pconn (all-connections pool)))) nil))) (let ((conn (connect (connection-spec pool) :database-type (pool-database-type pool) :if-exists :new :make-default nil :encoding encoding))) (setf (conn-pool conn) pool) (with-process-lock ((conn-pool-lock pool) "new conection") (push conn (all-connections pool))) conn))) (defun release-to-pool (database &optional (pool (conn-pool database))) "Release a database connection to the pool. The backend will have a chance to do cleanup." (unless (conn-pool database) (setf (conn-pool database) pool)) (cond ;;We read the list of free-connections outside the lock. This ;;should be fine as long as that list is never dealt with ;;destructively (push and pop destructively modify the place, ;;not the list). Multiple threads getting to this test at the ;;same time might result in the free-connections getting ;;longer... meh. ((or (and *db-pool-max-free-connections* (>= (length (free-connections pool)) *db-pool-max-free-connections*))) (%pool-force-disconnect database) (with-process-lock ((conn-pool-lock pool) "Remove extra Conn") (setf (all-connections pool) (delete database (all-connections pool))))) (t ;;let it do cleanup (database-release-to-conn-pool database) (with-process-lock ((conn-pool-lock pool) "Release to pool") (push database (free-connections pool)))))) (defmethod database-acquire-from-conn-pool (database) (case (database-underlying-type database) (:postgresql (database-execute-command "RESET ALL" database)) (:mysql (database-query "SHOW ERRORS LIMIT 1" database nil nil)) (:mssql ;; rpc escape sequence since this can't be called as a normal sp. ;;http://msdn.microsoft.com/en-us/library/aa198358%28SQL.80%29.aspx (database-execute-command "{rpc sp_reset_connection}" database)) (T (database-query "SELECT 1;" database '(integer) nil)))) (defmethod database-release-to-conn-pool (database) (case (database-underlying-type database) (:postgresql (ignore-errors ;;http://www.postgresql.org/docs/current/static/sql-discard.html ;;this was introduced relatively recently, wrap in ignore-errors ;;so that it doesn't choke older versions. (database-execute-command "DISCARD ALL" database))))) (defun clear-conn-pool (pool) "Be careful this function will disconnect connections without regard to whether another thread is actively using them." (with-process-lock ((conn-pool-lock pool) "Clear pool") (mapc #'%pool-force-disconnect (all-connections pool)) (setf (all-connections pool) nil (free-connections pool) nil)) nil) (defun find-or-create-connection-pool (connection-spec database-type) "Find connection pool in hash table, creates a new connection pool if not found" (let ((key (list connection-spec database-type))) (with-process-lock (*db-pool-lock* "Find-or-create connection") (or (gethash key *db-pool*) (setf (gethash key *db-pool*) (make-instance 'conn-pool :connection-spec connection-spec :pool-database-type database-type)))))) (defun disconnect-pooled (&optional clear) "Disconnects all connections in the pool. When clear, also deletes the pool objects." (with-process-lock (*db-pool-lock* "Disconnect pooled") (maphash #'(lambda (key conn-pool) (declare (ignore key)) (clear-conn-pool conn-pool)) *db-pool*) (when clear (clrhash *db-pool*))) t) (defun %pool-force-disconnect (database) "Force disconnection of a connection from the pool." ;;so it isn't just returned to pool (setf (conn-pool database) nil) ;; disconnect may error if remote side closed connection (ignore-errors (disconnect :database database))) ;(defun pool-start-sql-recording (pool &key (types :command)) ; "Start all stream in the pool recording actions of TYPES" ; (dolist (con (pool-connections pool)) ; (start-sql-recording :type types ; :database (connection-database con)))) ;(defun pool-stop-sql-recording (pool &key (types :command)) ; "Start all stream in the pool recording actions of TYPES" ; (dolist (con (pool-connections pool)) ; (stop-sql-recording :type types ; :database (connection-database con)))) ;(defmacro with-database-connection (pool &body body) ; `(let ((connection (obtain-connection ,pool)) ; (results nil)) ; (unwind-protect ; (with-database ((connection-database connection)) ; (setq results (multiple-value-list (progn ,@body)))) ; (release-connection connection)) ; (values-list results))) cl-sql-6.7.2/sql/utils.lisp0000644000175000017500000004234612651763366014613 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: utils.lisp ;;;; Purpose: SQL utility functions ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Mar 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defmacro defaulting (&rest place-value-plist) "for places and values (as an &rest plist) if place-n is null set it to value-n" `(progn ,@(loop for (place value . rest) on place-value-plist by #'cddr collect `(unless ,place (setf ,place ,value))))) (defmacro pop-n (place &optional (n 1)) "pops n items off of a list in place and returns their values in a new list if n > the length of the list in place, then we return the full list, setting the place to nil" `(loop repeat ,n while ,place collect (pop ,place))) (defun %get-int (v) (etypecase v (string (parse-integer v :junk-allowed t)) (integer v) (number (truncate v)))) (defun dequote (it) (if (and (listp it) (eql (first it) 'quote)) (second it) it)) (defvar +whitespace-chars+ '(#\space #\tab #\newline #\return ;; Tested: sbcl unicode, allegrocl, openmcl,clisp use #\no-break_space ;; lispworks uses #\no-break-space ;; sbcl non-unicode doesn't support no break space ;; AllegroCL 8-bit strings don't fail on reading #\no-break_space, ;; but can't represent such a character ;; CMUCL errors when trying to read #\no-break_space #+(and lispworks unicode) #\no-break-space #+(or (and sbcl sb-unicode) (and allegro ics) (and clisp i18n) (and openmcl openmcl-unicode-strings)) #\no-break_space ) "List of whitespace characters for this lisp implementation.") (defun number-to-sql-string (num) (etypecase num (integer (princ-to-string num)) (rational (float-to-sql-string (coerce num 'double-float))) (number (float-to-sql-string num)))) (defun float-to-sql-string (num) "Convert exponent character for SQL" (let ((str (write-to-string num :readably t))) (declare (type string str)) (cond ((find #\f str) (substitute #\e #\f str)) ((find #\d str) (substitute #\e #\d str)) ((find #\l str) (substitute #\e #\l str)) ((find #\s str) (substitute #\e #\S str)) ((find #\F str) (substitute #\e #\F str)) ((find #\D str) (substitute #\e #\D str)) ((find #\L str) (substitute #\e #\L str)) ((find #\S str) (substitute #\e #\S str)) (t str)))) (defun sql-escape (identifier) "Change hyphens to underscores, ensure string" (let ((unescaped (etypecase identifier (symbol (symbol-name identifier)) (string identifier)))) (substitute #\_ #\- unescaped))) #+lispworks (defvar +lw-has-without-preemption+ #-(or lispworks5 lispworks4) nil #+(or lispworks5 lispworks4) t) #+lispworks (defvar +lw-global-lock+ (unless +lw-has-without-preemption+ (mp:make-lock :name "CLSQL" :important-p nil :safep t :recursivep nil :sharing t))) (defmacro without-interrupts (&body body) #+allegro `(mp:without-scheduling ,@body) #+clisp `(progn ,@body) #+cmu `(system:without-interrupts ,@body) #+lispworks (if +lw-has-without-preemption+ `(mp:without-preemption ,@body) `(mp:with-exclusive-lock (+lw-global-lock+) ,@body)) #+openmcl `(ccl:without-interrupts ,@body) #+sbcl `(sb-sys::without-interrupts ,@body)) (defun make-process-lock (name) #+allegro (mp:make-process-lock :name name) #+cmu (mp:make-lock name) #+lispworks (mp:make-lock :name name) #+openmcl (ccl:make-lock name) #+sb-thread (sb-thread:make-mutex :name name) #+scl (thread:make-lock name) #-(or allegro cmu lispworks openmcl sb-thread scl) (declare (ignore name)) #-(or allegro cmu lispworks openmcl sb-thread scl) nil) (defmacro with-process-lock ((lock desc) &body body) #+(or cmu allegro lispworks openmcl sb-thread) (declare (ignore desc)) #+(or allegro cmu lispworks openmcl sb-thread) (let ((l (gensym))) `(let ((,l ,lock)) #+allegro (mp:with-process-lock (,l) ,@body) #+cmu (mp:with-lock-held (,l) ,@body) #+openmcl (ccl:with-lock-grabbed (,l) ,@body) #+lispworks (mp:with-lock (,l) ,@body) #+sb-thread (sb-thread:with-recursive-lock (,l) ,@body) )) #+scl `(thread:with-lock-held (,lock ,desc) ,@body) #-(or cmu allegro lispworks openmcl sb-thread scl) (declare (ignore lock desc)) #-(or cmu allegro lispworks openmcl sb-thread scl) `(progn ,@body)) (defun sql-escape-quotes (s) "Escape quotes for SQL string writing" (substitute-string-for-char s #\' "''")) (defun substitute-string-for-char (procstr match-char subst-str) "Substitutes a string for a single matching character of a string" (when procstr (locally (declare (type string procstr)) (let ((pos (position match-char procstr))) (if pos (concatenate 'string (subseq procstr 0 pos) subst-str (substitute-string-for-char (subseq procstr (1+ pos)) match-char subst-str)) procstr))))) (defun position-char (char string start max) "From KMRCL." (declare (optimize (speed 3) (safety 0) (space 0)) (fixnum start max) (simple-string string)) (do* ((i start (1+ i))) ((= i max) nil) (declare (fixnum i)) (when (char= char (schar string i)) (return i)))) (defun delimited-string-to-list (string &optional (separator #\space) skip-terminal) "Split a string with delimiter, from KMRCL." (declare (optimize (speed 3) (safety 0) (space 0) (compilation-speed 0)) (type string string) (type character separator)) (do* ((len (length string)) (output '()) (pos 0) (end (position-char separator string pos len) (position-char separator string pos len))) ((null end) (if (< pos len) (push (subseq string pos) output) (when (or (not skip-terminal) (zerop len)) (push "" output))) (nreverse output)) (declare (type fixnum pos len) (type (or null fixnum) end)) (push (subseq string pos end) output) (setq pos (1+ end)))) (defun string-to-list-connection-spec (str) (declare (type string str)) (let ((at-pos (position-char #\@ str 0 (length str)))) (cond ((and at-pos (> (length str) at-pos)) ;; Connection spec is SQL*NET format (cons (subseq str (1+ at-pos)) (delimited-string-to-list (subseq str 0 at-pos) #\/))) (t (delimited-string-to-list str #\/))))) #+allegro (eval-when (:compile-toplevel :load-toplevel :execute) (unless (find-package '#:excl.osi) (require 'osi))) (defun command-output (control-string &rest args) ;; Concatenates output and error since Lispworks combines ;; these, thus CLSQL can't depend upon separate results (multiple-value-bind (output error status) (apply #'%command-output control-string args) (values (concatenate 'string (if output output "") (if error error "")) status))) (defun read-stream-to-string (in) (with-output-to-string (out) (let ((eof (gensym))) (do ((line (read-line in nil eof) (read-line in nil eof))) ((eq line eof)) (format out "~A~%" line))))) ;; From KMRCL (defun %command-output (control-string &rest args) "Interpolate ARGS into CONTROL-STRING as if by FORMAT, and synchronously execute the result using a Bourne-compatible shell, returns (VALUES string-output error-output exit-status)" (let ((command (apply #'format nil control-string args))) #+sbcl (let* ((process (sb-ext:run-program "/bin/sh" (list "-c" command) :input nil :output :stream :error :stream)) (output (read-stream-to-string (sb-impl::process-output process))) (error (read-stream-to-string (sb-impl::process-error process)))) (close (sb-impl::process-output process)) (close (sb-impl::process-error process)) (values output error (sb-impl::process-exit-code process))) #+(or cmu scl) (let* ((process (ext:run-program "/bin/sh" (list "-c" command) :input nil :output :stream :error :stream)) (output (read-stream-to-string (ext::process-output process))) (error (read-stream-to-string (ext::process-error process)))) (close (ext::process-output process)) (close (ext::process-error process)) (values output error (ext::process-exit-code process))) #+allegro (multiple-value-bind (output error status) (excl.osi:command-output command :whole t) (values output error status)) #+lispworks ;; BUG: Lispworks combines output and error streams (let ((output (make-string-output-stream))) (unwind-protect (let ((status (system:call-system-showing-output command :shell-type "/bin/sh" :output-stream output))) (values (get-output-stream-string output) nil status)) (close output))) #+clisp ;; BUG: CLisp doesn't allow output to user-specified stream (values nil nil (ext:run-shell-command command :output :terminal :wait t)) #+openmcl (let* ((process (ccl:run-program "/bin/sh" (list "-c" command) :input nil :output :stream :error :stream :wait t)) (output (read-stream-to-string (ccl::external-process-output-stream process))) (error (read-stream-to-string (ccl::external-process-error-stream process)))) (close (ccl::external-process-output-stream process)) (close (ccl::external-process-error-stream process)) (values output error (nth-value 1 (ccl::external-process-status process)))) #-(or openmcl clisp lispworks allegro scl cmu sbcl) (error "COMMAND-OUTPUT not implemented for this Lisp") )) ;; From KMRCL (defmacro in (obj &rest choices) (let ((insym (gensym))) `(let ((,insym ,obj)) (or ,@(mapcar #'(lambda (c) `(eql ,insym ,c)) choices))))) ;; From KMRCL (defun substitute-char-string (procstr match-char subst-str) "Substitutes a string for a single matching character of a string" (substitute-chars-strings procstr (list (cons match-char subst-str)))) (defun replaced-string-length (str repl-alist) (declare (simple-string str) (optimize (speed 3) (safety 0) (space 0))) (do* ((i 0 (1+ i)) (orig-len (length str)) (new-len orig-len)) ((= i orig-len) new-len) (declare (fixnum i orig-len new-len)) (let* ((c (char str i)) (match (assoc c repl-alist :test #'char=))) (declare (character c)) (when match (incf new-len (1- (length (the simple-string (cdr match))))))))) (defun substitute-chars-strings (str repl-alist) "Replace all instances of a chars with a string. repl-alist is an assoc list of characters and replacement strings." (declare (simple-string str) (optimize (speed 3) (safety 0) (space 0))) (do* ((orig-len (length str)) (new-string (make-string (replaced-string-length str repl-alist))) (spos 0 (1+ spos)) (dpos 0)) ((>= spos orig-len) new-string) (declare (fixnum spos dpos) (simple-string new-string)) (let* ((c (char str spos)) (match (assoc c repl-alist :test #'char=))) (declare (character c)) (if match (let* ((subst (cdr match)) (len (length subst))) (declare (fixnum len) (simple-string subst)) (dotimes (j len) (declare (fixnum j)) (setf (char new-string dpos) (char subst j)) (incf dpos))) (progn (setf (char new-string dpos) c) (incf dpos)))))) (defun getenv (var) "Return the value of the environment variable." #+allegro (sys::getenv (string var)) #+clisp (ext:getenv (string var)) #+(or cmu scl) (cdr (assoc (string var) ext:*environment-list* :test #'equalp :key #'string)) #+lispworks (lw:environment-variable (string var)) #+ccl (ccl::getenv var) #+sbcl (sb-ext:posix-getenv var)) (eval-when (:compile-toplevel :load-toplevel :execute) (when (char= #\a (schar (symbol-name '#:a) 0)) (pushnew :clsql-lowercase-reader *features*))) (defun symbol-name-default-case (str) #-clsql-lowercase-reader (string-upcase str) #+clsql-lowercase-reader (string-downcase str)) (defun convert-to-db-default-case (str database) (if database (case (db-type-default-case (database-underlying-type database)) (:upper (string-upcase str)) (:lower (string-downcase str)) (t str)) ;; Default CommonSQL behavior is to upcase strings (string-upcase str))) (defun ensure-keyword (name) "Returns keyword for a name." (etypecase name (keyword name) (string (nth-value 0 (intern (symbol-name-default-case name) :keyword))) (symbol (nth-value 0 (intern (symbol-name name) :keyword))))) (eval-when (:compile-toplevel :load-toplevel :execute) (setq cl:*features* (delete :clsql-lowercase-reader cl:*features*))) (defun replace-all (string part replacement &key (test #'char=) stream) "Returns a new string in which all the occurences of the part is replaced with replacement. [FROM http://cl-cookbook.sourceforge.net/strings.html#manip]" (let ((out (or stream (make-string-output-stream)))) (loop with part-length = (length part) for old-pos = 0 then (+ pos part-length) for pos = (search part string :start2 old-pos :test test) do (write-string string out :start old-pos :end (or pos (length string))) when pos do (write-string replacement out) while pos) (unless stream (get-output-stream-string out)))) (defun read-decimal-value (string) (let* ((comma 0) (dot 0) (last)) (loop for c across string do (case c (#\. (incf dot) (setf last 'dot)) (#\, (incf comma) (setf last 'comma)))) (let* ((bag (if (and (eql last 'dot) (eql dot 1)) ".0123456789+-" ",0123456789+-")) (clean (with-output-to-string (out) (loop for c across string do (when (find c bag :test #'char=) (write-char c out)))))) (if (and (eql last 'dot) (eql dot 1)) (decimals:parse-decimal-number clean) (decimals:parse-decimal-number clean :decimal-separator #\,))))) (defun filter-plist (plist &rest keys-to-remove) "Returns a copy of the given plist with indicated key-value pairs removed. keys are searched with #'MEMBER" (declare (dynamic-extent keys-to-remove)) (when plist (loop for (k v . rest) = plist then rest unless (member k keys-to-remove) collect k and collect v while rest))) (defmacro make-weak-hash-table (&rest args) "Creates a weak hash table for use in a cache." `(progn ;;NB: These are generally used for caches that may not have an alternate ;;clearing mechanism. If you are on an implementation that doesn't support ;;weak hash tables then you're memory may accumulate. #-(or sbcl allegro clisp lispworks ccl) (warn "UNSAFE! use of weak hash on implementation without support. (see clsql/sql/utils.lisp to add)") (make-hash-table #+allegro :values #+allegro :weak #+clisp :weak #+clisp :value #+lispworks :weak-kind #+lispworks :value #+sbcl :weakness #+sbcl :value #+ccl :weak #+ccl :value ,@args) )) (defun to-slot-name (slot) "try to turn what we got representing the slot into a slot name" (etypecase slot (symbol slot) (slot-definition (slot-definition-name slot)))) (defun to-class (it) (etypecase it (class it) (symbol (find-class it)) (standard-object (class-of it)))) (defun to-class-name (o) (etypecase o (symbol o) (standard-class (class-name o)) (standard-object (class-name (class-of o))))) (defun easy-slot-value (obj slot) "like slot-value except it accepts slot-names or defs and returns nil when the slot is unbound" (let ((n (to-slot-name slot))) (when (and obj (slot-boundp obj n)) (slot-value obj n)))) (defun (setf easy-slot-value) (new obj slot) "like slot-value except it accepts slot-names or defs" (setf (slot-value obj (to-slot-name slot)) new)) (defun delist-if-single (x) "if this is a single item in a list return it" (if (and (listp x) (= 1 (length x))) (first x) x)) cl-sql-6.7.2/sql/syntax.lisp0000644000175000017500000001772211616055736014774 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; CLSQL square bracket symbolic query syntax. Functions for ;;;; enabling and disabling the syntax and for building SQL ;;;; expressions using the syntax. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defvar *original-readtable* nil) (defvar *sql-macro-open-char* #\[) (defvar *sql-macro-close-char* #\]) (defvar *restore-sql-reader-syntax* nil) ;; Exported functions for disabling SQL syntax. (defmacro disable-sql-reader-syntax () "Turns off the SQL reader syntax setting the syntax state such that if the syntax is subsequently enabled, RESTORE-SQL-READER-SYNTAX-STATE will disable it again." '(eval-when (:compile-toplevel :load-toplevel :execute) (setf *restore-sql-reader-syntax* nil) (%disable-sql-reader-syntax))) (defmacro locally-disable-sql-reader-syntax () "Turns off the SQL reader syntax without changing the syntax state such that RESTORE-SQL-READER-SYNTAX-STATE will re-establish the current syntax state." '(eval-when (:compile-toplevel :load-toplevel :execute) (%disable-sql-reader-syntax))) (defun %disable-sql-reader-syntax () (when *original-readtable* (setf *readtable* *original-readtable* *original-readtable* nil)) (values)) ;; Exported functions for enabling SQL syntax. (defmacro enable-sql-reader-syntax () "Turns on the SQL reader syntax setting the syntax state such that if the syntax is subsequently disabled, RESTORE-SQL-READER-SYNTAX-STATE will enable it again." '(eval-when (:compile-toplevel :load-toplevel :execute) (setf *restore-sql-reader-syntax* t) (%enable-sql-reader-syntax))) (defmacro locally-enable-sql-reader-syntax () "Turns on the SQL reader syntax without changing the syntax state such that RESTORE-SQL-READER-SYNTAX-STATE will re-establish the current syntax state." '(eval-when (:compile-toplevel :load-toplevel :execute) (%enable-sql-reader-syntax))) (defmacro file-enable-sql-reader-syntax () "Turns on the SQL reader syntax for the rest of the file. The CL spec says that when finished loading a file the original *readtable* is restored. clhs COMPILE-FILE" '(eval-when (:compile-toplevel :load-toplevel :execute) (setf *readtable* (copy-readtable)) (set-macro-character *sql-macro-open-char* #'sql-reader-open) (set-macro-character *sql-macro-close-char* (get-macro-character #\))))) (defun %enable-sql-reader-syntax () (unless *original-readtable* (setf *original-readtable* *readtable* *readtable* (copy-readtable)) (set-macro-character *sql-macro-open-char* #'sql-reader-open) (set-macro-character *sql-macro-close-char* (get-macro-character #\)))) (values)) (defmacro restore-sql-reader-syntax-state () "Enables the SQL reader syntax if ENABLE-SQL-READER-SYNTAX has been called more recently than DISABLE-SQL-READER-SYNTAX and otherwise disables the SQL reader syntax. By default, the SQL reader syntax is disabled." '(eval-when (:compile-toplevel :load-toplevel :execute) (if *restore-sql-reader-syntax* (%enable-sql-reader-syntax) (%disable-sql-reader-syntax)))) (defun sql-reader-open (stream char) (declare (ignore char)) (let ((sqllist (read-delimited-list #\] stream t))) (unless *read-suppress* (handler-case (cond ((string= (write-to-string (car sqllist)) "||") (cons (sql-operator 'concat-op) (cdr sqllist))) ((and (= (length sqllist) 1) (eql (car sqllist) '*)) (apply #'generate-sql-reference sqllist)) ((sql-operator (car sqllist)) (cons (sql-operator (car sqllist)) (cdr sqllist))) (t (apply #'generate-sql-reference sqllist))) (sql-user-error (c) (error 'sql-user-error :message (format nil "Error ~A occured while attempting to parse '~A' at file position ~A" (sql-user-error-message c) sqllist (file-position stream)))))))) (defun generate-sql-reference (&rest arglist) (cond ((= (length arglist) 1) ; string, table or attribute (let ((arg (first arglist))) (typecase arg (string (sql-expression :string arg)) (symbol ;; handle . separated names (let* ((sn (symbol-name arg)) (idx (position #\. sn))) (cond (idx (sql-expression :table (intern (subseq sn 0 idx)) :attribute (intern (subseq sn (+ idx 1))) )) (T (sql-expression :attribute arg)))) )))) ((<= 2 (length arglist)) (let ((sqltype (when (keywordp (caddr arglist)) (caddr arglist) nil))) (cond ((stringp (cadr arglist)) (sql-expression :table (car arglist) :alias (cadr arglist) :type sqltype)) ((keywordp (cadr arglist)) (sql-expression :attribute (car arglist) :type (cadr arglist))) (t (sql-expression :attribute (cadr arglist) :table (car arglist) :type sqltype))))) (t (error 'sql-user-error :message "bad expression syntax")))) ;; Exported functions for dealing with SQL syntax (defun sql (&rest args) "Returns an SQL string generated from the expressions ARGS. The expressions are translated into SQL strings and then concatenated with a single space delimiting each expression. An error of type SQL-USER-ERROR is signalled if any element in ARGS is not of the supported types (a symbol, string, number or symbolic SQL expression) or a list or vector containing only these supported types." (format nil "~{~A~^ ~}" (mapcar #'sql-output args))) (defun sql-expression (&key string table alias attribute type) "Returns an SQL expression constructed from the supplied arguments which may be combined as follows: ATTRIBUTE and TYPE; ATTRIBUTE; ALIAS or TABLE and ATTRIBUTE and TYPE; ALIAS or TABLE and ATTRIBUTE; TABLE, ATTRIBUTE and TYPE; TABLE and ATTRIBUTE; TABLE and ALIAS; TABLE; and STRING. An error of type SQL-USER-ERROR is signalled if an unsupported combination of keyword arguments is specified." (cond (string (make-instance 'sql :string string)) (attribute (make-instance 'sql-ident-attribute :name attribute :qualifier (or table alias) :type type)) ((and table (not attribute)) (make-instance 'sql-ident-table :name table :table-alias alias)))) (defun sql-operator (operator) "Returns the Lisp symbol corresponding to the SQL operator represented by the symbol OPERATOR. If OPERATOR does not represent a supported SQL operator or is not a symbol, nil is returned." (typecase operator (string nil) (symbol (values (gethash (symbol-name-default-case (symbol-name operator)) *sql-op-table*))))) (defun sql-operation (operator &rest args) "Returns an SQL expression constructed from the supplied symbol OPERATOR representing an SQL operator or function and its arguments ARGS. An error of type SQL-USER-ERROR is signalled if OPERATOR is not a symbol representing a supported SQL operator. If OPERATOR is passed the symbol FUNCTION then the first value in ARGS must be a string representing a valid SQL function and the remaining values in ARGS its arguments as strings." (if (sql-operator operator) (apply (symbol-function (sql-operator operator)) args) (error 'sql-user-error :message (format nil "~A is not a recognized SQL operator." operator)))) cl-sql-6.7.2/sql/loop-extension.lisp0000644000175000017500000002160311335067642016417 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: loop-extension.lisp ;;;; Purpose: Extensions to the Loop macro for CLSQL ;;;; ;;;; Copyright (c) 2001-2006 Kevin Rosenberg and (c) 1999-2001 Pierre R. Mai ;;;; ;;;; ************************************************************************* (in-package #:clsql-sys) #+(or allegro sbcl) (eval-when (:compile-toplevel :load-toplevel :execute) (defpackage #:ansi-loop (:import-from #+sbcl #:sb-loop #+allegro #:excl #:*loop-epilogue* #:*loop-ansi-universe* #:add-loop-path))) #+(or allegro sbcl) (defun ansi-loop::loop-gentemp (&optional (pref 'loopva-)) (gensym (string pref))) #+clisp (eval-when (:compile-toplevel :load-toplevel :execute) (when (find-package "ANSI-LOOP") (push :clisp-aloop cl:*features*))) #+(or allegro clisp-aloop cmu openmcl sbcl scl) (defun loop-record-iteration-path (variable data-type prep-phrases) (let ((in-phrase nil) (from-phrase nil)) (loop for (prep . rest) in prep-phrases do (case prep ((:in :of) (when in-phrase (error 'clsql:sql-user-error :message (format nil "Duplicate OF or IN iteration path: ~S." (cons prep rest)))) (setq in-phrase rest)) ((:from) (when from-phrase (error 'clsql:sql-user-error :message (format nil "Duplicate FROM iteration path: ~S." (cons prep rest)))) (setq from-phrase rest)) (t (error 'clsql:sql-user-error :message (format nil"Unknown preposition: ~S." prep))))) (unless in-phrase (error 'clsql:sql-user-error :message "Missing OF or IN iteration path.")) (unless from-phrase (setq from-phrase '(*default-database*))) (unless (consp variable) (setq variable (list variable))) (cond ;; object query ((and (consp (first in-phrase)) (string-equal "sql-query" (symbol-name (caar in-phrase))) (consp (second (first in-phrase))) (eq 'quote (first (second (first in-phrase)))) (symbolp (second (second (first in-phrase))))) (let ((result-var (ansi-loop::loop-gentemp 'loop-record-result-)) (step-var (ansi-loop::loop-gentemp 'loop-record-step-))) `(((,variable nil ,@(and data-type (list data-type))) (,result-var (query ,(first in-phrase))) (,step-var nil)) () () () (if (null ,result-var) t (progn (setq ,step-var (first ,result-var)) (setq ,result-var (rest ,result-var)) nil)) (,variable ,step-var) (null ,result-var) () (if (null ,result-var) t (progn (setq ,step-var (first ,result-var)) (setq ,result-var (rest ,result-var)) nil)) (,variable ,step-var)))) ((consp variable) (let ((query-var (ansi-loop::loop-gentemp 'loop-record-)) (db-var (ansi-loop::loop-gentemp 'loop-record-database-)) (result-set-var (ansi-loop::loop-gentemp 'loop-record-result-set-)) (step-var (ansi-loop::loop-gentemp 'loop-record-step-))) (push `(when ,result-set-var (database-dump-result-set ,result-set-var ,db-var)) ansi-loop::*loop-epilogue*) `(((,variable nil ,@(and data-type (list data-type))) (,query-var ,(first in-phrase)) (,db-var ,(first from-phrase)) (,result-set-var t) (,step-var nil)) ((multiple-value-bind (%rs %cols) (database-query-result-set ,query-var ,db-var :result-types :auto) (setq ,result-set-var %rs ,step-var (make-list %cols)))) () () (not (database-store-next-row ,result-set-var ,db-var ,step-var)) (,variable ,step-var) (not ,result-set-var) () (not (database-store-next-row ,result-set-var ,db-var ,step-var)) (,variable ,step-var))))))) #+(or allegro clisp-aloop cmu openmcl sbcl scl) (ansi-loop::add-loop-path '(record records tuple tuples) 'loop-record-iteration-path ansi-loop::*loop-ansi-universe* :preposition-groups '((:of :in) (:from)) :inclusive-permitted nil) #+lispworks (cl-user::define-loop-method (loop::record loop::records loop::tuple loop::tuples) clsql-loop-method (loop::in loop::of loop::from)) #+lispworks (defun clsql-loop-method (method-name iter-var iter-var-data-type prep-phrases inclusive? allowed-preps method-specific-data) (declare (ignore method-name iter-var-data-type inclusive? allowed-preps method-specific-data)) (let ((in-phrase nil) (from-phrase nil)) (loop for (prep . rest) in prep-phrases do (cond ((or (eq prep 'loop::in) (eq prep 'loop::of)) (when in-phrase (error 'clsql:sql-user-error :message (format nil "Duplicate OF or IN iteration path: ~S." (cons prep rest)))) (setq in-phrase rest)) ((eq prep 'loop::from) (when from-phrase (error 'clsql:sql-user-error :message (format nil "Duplicate FROM iteration path: ~S." (cons prep rest)))) (setq from-phrase rest)) (t (error 'clsql:sql-user-error :message (format nil "Unknown preposition: ~S." prep))))) (unless in-phrase (error 'clsql:sql-user-error :message "Missing OF or IN iteration path.")) (unless from-phrase (setq from-phrase '(clsql:*default-database*))) (unless (consp iter-var) (setq iter-var (list iter-var))) (cond ;; object query ((and (consp in-phrase) (string-equal "sql-query" (symbol-name (car in-phrase))) (consp (second in-phrase)) (eq 'quote (first (second in-phrase))) (symbolp (second (second in-phrase)))) (let ((result-var (gensym "LOOP-RECORD-RESULT-")) (step-var (gensym "LOOP-RECORD-STEP-"))) (values t nil `(,@(mapcar (lambda (v) `(,v nil)) iter-var) (,result-var (clsql:query ,in-phrase)) (,step-var nil)) () () () `((if (null ,result-var) t (progn (setq ,step-var (first ,result-var)) (setq ,result-var (rest ,result-var)) nil))) `(,iter-var ,step-var) `((if (null ,result-var) t (progn (setq ,step-var (first ,result-var)) (setq ,result-var (rest ,result-var)) nil))) `(,iter-var ,step-var) () () ))) ((consp iter-var) (let ((query-var (gensym "LOOP-RECORD-")) (db-var (gensym "LOOP-RECORD-DATABASE-")) (result-set-var (gensym "LOOP-RECORD-RESULT-SET-")) (step-var (gensym "LOOP-RECORD-STEP-"))) (values t nil `(,@(mapcar (lambda (v) `(,v nil)) iter-var) (,query-var ,in-phrase) (,db-var ,(first from-phrase)) (,result-set-var nil) (,step-var nil)) `((multiple-value-bind (%rs %cols) (clsql-sys:database-query-result-set ,query-var ,db-var :result-types :auto) (setq ,result-set-var %rs ,step-var (make-list %cols)))) () () `((unless (clsql-sys:database-store-next-row ,result-set-var ,db-var ,step-var) (when ,result-set-var (clsql-sys:database-dump-result-set ,result-set-var ,db-var)) t)) `(,iter-var ,step-var) `((unless (clsql-sys:database-store-next-row ,result-set-var ,db-var ,step-var) (when ,result-set-var (clsql-sys:database-dump-result-set ,result-set-var ,db-var)) t)) `(,iter-var ,step-var) () ())))))) #+clisp-aloop (eval-when (:compile-toplevel :load-toplevel :execute) (setq cl:*features* (delete :clisp-aloop cl:*features*))) cl-sql-6.7.2/sql/db-interface.lisp0000644000175000017500000005117412651763351015767 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: db-interface.lisp ;;;; Purpose: Generic function definitions for DB interfaces ;;;; Programmers: Kevin M. Rosenberg based on ;;;; Original code by Pierre R. Mai. Additions from ;;;; onShoreD to support UncommonSQL front-end ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai, and onShoreD ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defgeneric database-type-load-foreign (database-type) (:documentation "The internal generic implementation of reload-database-types.")) (defgeneric database-type-library-loaded (database-type) (:documentation "The internal generic implementation for checking if database type library loaded successfully.")) (defgeneric database-initialize-database-type (database-type) (:documentation "The internal generic implementation of initialize-database-type.")) (defgeneric database-name-from-spec (connection-spec database-type) (:documentation "Returns the name of the database that would be created if connect was called with the connection-spec.")) (defgeneric database-connect (connection-spec database-type) (:documentation "Internal generic implementation of connect.")) (defgeneric database-reconnect (database) (:method ((database t)) (signal-no-database-error database)) (:documentation "Internal generic implementation of reconnect.")) (defgeneric database-disconnect (database) (:method ((database t)) (signal-no-database-error database)) (:documentation "Internal generic implementation of disconnect.")) (defgeneric database-query (query-expression database result-types field-names) (:method (query-expression (database t) result-types field-names) (declare (ignore query-expression result-types field-names)) (signal-no-database-error database)) (:method (query-expression (database database) result-types field-names) (declare (ignore query-expression result-types field-names)) (warn "database-query not implemented for database type ~A." (database-type database))) (:documentation "Internal generic implementation of query.")) (defgeneric database-execute-command (sql-expression database) (:method (sql-expression (database t)) (declare (ignore sql-expression)) (signal-no-database-error database)) (:method (sql-expression (database database)) (declare (ignore sql-expression)) (warn "database-execute-command not implemented for database type ~A." (database-type database))) (:documentation "Internal generic implementation of execute-command.")) ;;; Mapping and iteration (defgeneric database-query-result-set (query-expression database &key full-set result-types) (:method (query-expression (database t) &key full-set result-types) (declare (ignore query-expression full-set result-types)) (signal-no-database-error database) (values nil nil nil)) (:method (query-expression (database database) &key full-set result-types) (declare (ignore query-expression full-set result-types)) (warn "database-query-result-set not implemented for database type ~A." (database-type database)) (values nil nil nil)) (:documentation "Internal generic implementation of query mapping. Starts the query specified by query-expression on the given database and returns a result-set to be used with database-store-next-row and database-dump-result-set to access the returned data. The second value is the number of columns in the result-set, if there are any. If full-set is true, the number of rows in the result-set is returned as a third value, if this is possible (otherwise nil is returned for the third value). This might have memory and resource usage implications, since many databases will require the query to be executed in full to answer this question. If the query produced no results then nil is returned for all values that would have been returned otherwise. If an error occurs during query execution, the function should signal a sql-database-data-error.")) (defgeneric database-dump-result-set (result-set database) (:method (result-set (database t)) (declare (ignore result-set)) (signal-no-database-error database)) (:method (result-set (database database)) (declare (ignore result-set)) (warn "database-dump-result-set not implemented for database type ~A." (database-type database))) (:documentation "Dumps the received result-set.")) (defgeneric database-store-next-row (result-set database list) (:method (result-set (database t) list) (declare (ignore result-set list)) (signal-no-database-error database)) (:method (result-set (database database) list) (declare (ignore result-set list)) (warn "database-store-next-row not implemented for database type ~A." (database-type database))) (:documentation "Returns t and stores the next row in the result set in list or returns nil when result-set is finished.")) (defgeneric database-create (connection-spec type) (:documentation "Creates a database, returns T if successfull or signals an error.")) (defgeneric database-probe (connection-spec type) (:method (spec type) (declare (ignore spec)) (warn "database-probe not support for database-type ~A." type)) (:documentation "Probes for the existence of a database, returns T if database found or NIL if not found. May signal an error if unable to communicate with database server.")) (defgeneric database-list (connection-spec type) (:method (spec type) (declare (ignore spec)) (warn "database-list not support for database-type ~A." type)) (:documentation "Lists all databases found for TYPE. May signal an error if unable to communicate with database server.")) (defgeneric database-truncate (database) (:method ((database t)) (signal-no-database-error database)) (:documentation "Remove all data from database.")) (defgeneric database-destroy (connection-spec type) (:documentation "Destroys (drops) a database, returns T if successfull or signals an error if unable to destory.")) (defgeneric database-create-sequence (name database) (:documentation "Create a sequence in DATABASE.")) (defgeneric database-drop-sequence (name database) (:documentation "Drop a sequence from DATABASE.")) (defgeneric database-sequence-next (name database) (:documentation "Increment a sequence in DATABASE.")) (defgeneric database-list-sequences (database &key owner) (:documentation "List all sequences in DATABASE.")) (defgeneric database-set-sequence-position (name position database) (:documentation "Set the position of the sequence called NAME in DATABASE.")) (defgeneric database-sequence-last (name database) (:documentation "Select the last value in sequence NAME in DATABASE.")) (defgeneric database-last-autoincrement-id (database table column) (:documentation "Many databases have the notion of an auto-increment id; i.e. a sequence implicitly on a table. This function should return that ID." )) (defgeneric database-start-transaction (database) (:documentation "Start a transaction in DATABASE.") (:method ((database t)) (signal-no-database-error database))) (defgeneric database-commit-transaction (database) (:documentation "Commit current transaction in DATABASE.") (:method ((database t)) (signal-no-database-error database))) (defgeneric database-abort-transaction (database) (:documentation "Abort current transaction in DATABASE.") (:method ((database t)) (signal-no-database-error database))) (defgeneric database-get-type-specifier (type args database db-underlying-type) (:documentation "Return the type SQL type specifier as a string, for the given lisp type and parameters.")) (defgeneric database-list-tables (database &key owner) (:documentation "List all tables in the given database") (:method ((database database) &key owner) (declare (ignore owner)) (warn "database-list-tables not implemented for database type ~A." (database-type database))) (:method ((database t) &key owner) (declare (ignore owner)) (signal-no-database-error database))) (defgeneric database-list-tables-and-sequences (database &key owner) (:documentation "List all tables in the given database, may include seqeneces") (:method ((database t) &key owner) (declare (ignore owner)) (signal-no-database-error database)) (:method ((database database) &key owner) (database-list-tables database :owner owner))) (defgeneric database-list-views (database &key owner) (:documentation "List all views in the DATABASE.") (:method ((database database) &key owner) (declare (ignore owner)) (warn "database-list-views not implemented for database type ~A." (database-type database))) (:method ((database t) &key owner) (declare (ignore owner)) (signal-no-database-error database))) (defgeneric database-list-indexes (database &key owner) (:documentation "List all indexes in the DATABASE.") (:method ((database database) &key owner) (declare (ignore owner)) (warn "database-list-indexes not implemented for database type ~A." (database-type database))) (:method ((database t) &key owner) (declare (ignore owner)) (signal-no-database-error database))) (defgeneric database-list-table-indexes (table database &key owner) (:documentation "List all indexes for a table in the DATABASE.") (:method (table (database database) &key owner) (declare (ignore table owner)) (warn "database-list-table-indexes not implemented for database type ~A." (database-type database))) (:method (table (database t) &key owner) (declare (ignore table owner)) (signal-no-database-error database))) (defgeneric database-list-attributes (table database &key owner) (:documentation "List all attributes in TABLE.") (:method (table (database database) &key owner) (declare (ignore table owner)) (warn "database-list-attributes not implemented for database type ~A." (database-type database))) (:method (table (database t) &key owner) (declare (ignore table owner)) (signal-no-database-error database))) (defgeneric database-attribute-type (attribute table database &key owner) (:documentation "Return the type of ATTRIBUTE in TABLE. Returns multiple values of TYPE_NAME (keyword) PRECISION SCALE NULLABLE.") (:method (attribute table (database database) &key owner) (declare (ignore attribute table owner)) (warn "database-list-attribute-type not implemented for database type ~A." (database-type database))) (:method (attribute table (database t) &key owner) (declare (ignore attribute table owner)) (signal-no-database-error database))) (defgeneric database-add-attribute (table attribute database) (:documentation "Add the attribute to the table.") (:method (table attribute (database database)) (declare (ignore table attribute)) (warn "database-add-attribute not implemented for database type ~A." (database-type database))) (:method (table attribute (database t)) (declare (ignore table attribute)) (signal-no-database-error database))) (defgeneric database-rename-attribute (table oldatt newname database) (:documentation "Rename the attribute in the table to NEWNAME.") (:method (table oldatt newname (database database)) (declare (ignore table oldatt newname)) (warn "database-rename-attribute not implemented for database type ~A." (database-type database))) (:method (table oldatt newname (database t)) (declare (ignore table oldatt newname)) (signal-no-database-error database))) (defgeneric oid (object) (:documentation "Return the unique ID of a database object.")) ;;; Database backend capabilities (defgeneric database-underlying-type (database) (:method (database) (database-type database)) (:documentation "Returns the type of the underlying database. For ODBC, needs to query ODBC driver.")) (defgeneric db-type-use-column-on-drop-index? (db-type) (:method (db-type) (declare (ignore db-type)) nil) (:documentation "NIL [default] if database-type does not use column name on DROP INDEX.")) (defgeneric db-type-use-fully-qualified-column-on-drop-index? (db-type) (:method (db-type) (declare (ignore db-type)) nil) (:documentation "NIL [default] if database-type does not require fully qualified column name on DROP INDEX.")) (defgeneric db-type-has-views? (db-type) (:method (db-type) (declare (ignore db-type)) ;; SQL92 has views t) (:documentation "T [default] if database-type supports views.")) (defgeneric db-type-has-bigint? (db-type) (:method (db-type) (declare (ignore db-type)) ;; SQL92 has bigint t) (:documentation "T [default] if database-type supports bigint.")) (defgeneric db-type-default-case (db-type) (:method (db-type) (declare (ignore db-type)) ;; By default, CommonSQL converts identifiers to UPPER case. :upper) (:documentation ":upper [default] if means identifiers mapped to UPPER case SQL like CommonSQL API. However, Postgresql maps identifiers to lower case, so PostgreSQL uses a value of :lower for this result.")) (defgeneric db-type-has-fancy-math? (db-type) (:method (db-type) (declare (ignore db-type)) nil) (:documentation "NIL [default] if database-type does not have fancy math.")) (defgeneric db-type-has-subqueries? (db-type) (:method (db-type) (declare (ignore db-type)) t) (:documentation "T [default] if database-type supports views.")) (defgeneric db-type-has-boolean-where? (db-type) (:method (db-type) (declare (ignore db-type)) ;; SQL99 has boolean where t) (:documentation "T [default] if database-type supports boolean WHERE clause, such as 'WHERE MARRIED'.")) (defgeneric db-type-has-union? (db-type) (:method (db-type) (declare (ignore db-type)) t) (:documentation "T [default] if database-type supports boolean UNION.")) (defgeneric db-backend-has-create/destroy-db? (db-type) (:method (db-type) (declare (ignore db-type)) t) (:documentation "T [default] if backend can destroy and create databases.")) (defgeneric db-type-transaction-capable? (db database) (:method (db database) (declare (ignore db database)) t) (:documentation "T [default] if database can supports transactions.")) (defgeneric db-type-has-prepared-stmt? (db-type) (:method ((db-type t)) nil) (:documentation "T if database backend supports prepared statements.")) (defgeneric db-type-has-intersect? (db-type) (:method (db-type) (declare (ignore db-type)) t) (:documentation "T [default] if database-type supports INTERSECT.")) (defgeneric db-type-has-except? (db-type) (:method (db-type) (declare (ignore db-type)) t) (:documentation "T [default] if database-type supports EXCEPT.")) (defgeneric db-type-has-auto-increment? (db-type) (:method (db-type) (declare (ignore db-type)) nil) (:documentation "NIL [default] if database-type supports auto-incrementing columns.")) ;;; Large objects support (Marc Battyani) (defgeneric database-create-large-object (database) (:documentation "Creates a new large object in the database and returns the object identifier")) (defgeneric database-write-large-object (object-id data database) (:documentation "Writes data to the large object")) (defgeneric database-read-large-object (object-id database) (:documentation "Reads the large object content")) (defgeneric database-delete-large-object (object-id database) (:documentation "Deletes the large object in the database")) ;; Prepared statements (defgeneric database-prepare (stmt types database result-types field-names) (:method (stmt types (database t) result-types field-names) (declare (ignore stmt types result-types field-names)) (signal-no-database-error database)) (:method (stmt types (database database) result-types field-names) (declare (ignore stmt types result-types field-names)) (error 'sql-database-error :message (format nil "DATABASE-PREPARE not implemented for ~S" database))) (:documentation "Prepare a statement for later execution.")) (defgeneric database-bind-parameter (prepared-stmt position value) (:method ((pstmt t) position value) (declare (ignore position value)) (error 'sql-database-error :message (format nil "database-bind-paremeter not implemented for ~S" pstmt))) (:documentation "Bind a parameter for a prepared statement.")) (defgeneric database-run-prepared (prepared-stmt) (:method ((pstmt t)) (error 'sql-database-error :message (format nil "database-run-prepared not specialized for ~S" pstmt))) (:documentation "Execute a prepared statement.")) (defgeneric database-free-prepared (prepared-stmt) (:method ((pstmt t)) ;; nothing to do by default nil) (:documentation "Free the resources of a prepared statement.")) (defgeneric database-acquire-from-conn-pool (database) (:documentation "Acquire a database connection from the pool. This is a chance to test the connection for validity before returning it to the user. If this function returns NIL or throws an error that database connection is considered bad and we make a new one. Database objects have a chance to specialize, otherwise the default method uses the database-underlying-type and tries to do something appropriate.")) (defgeneric database-release-to-conn-pool (database) (:documentation "Chance for the database to cleanup before it is returned to the connection pool.")) ;; Checks for closed database (defmethod database-disconnect :before ((database database)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-query :before (query-expression (database database) result-set field-names) (declare (ignore query-expression result-set field-names)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-execute-command :before (sql-expression (database database)) (declare (ignore sql-expression)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-query-result-set :before (expr (database database) &key full-set result-types) (declare (ignore expr full-set result-types)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-dump-result-set :before (result-set (database database)) (declare (ignore result-set)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-store-next-row :before (result-set (database database) list) (declare (ignore result-set list)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-commit-transaction :before ((database database)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-start-transaction :before ((database database)) (unless (is-database-open database) (signal-closed-database-error database))) (defmethod database-abort-transaction :before ((database database)) (unless (is-database-open database) (signal-closed-database-error database))) (defvar *foreign-library-search-paths* nil "A list of pathnames denoting directories where CLSQL will look for foreign libraries \(in addition to the default places).") (defun push-library-path (path) "Adds the pathspec PATH \(which should denote a directory) to the list *FOREIGN-LIBRARY-SEARCH-PATHS*." (pushnew path *foreign-library-search-paths* :test #'equal)) cl-sql-6.7.2/sql/expressions.lisp0000644000175000017500000012304712651763351016025 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Classes defining SQL expressions and methods for formatting the ;;;; appropriate SQL commands. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defvar +empty-string+ "''") (defvar +null-string+ "NULL") (defvar *sql-stream* nil "stream which accumulates SQL output") (defclass %database-identifier () ((escaped :accessor escaped :initarg :escaped :initform nil) (unescaped :accessor unescaped :initarg :unescaped :initform nil)) (:documentation "A database identifier represents a string/symbol ready to be spliced into a sql string. It keeps references to both the escaped and unescaped versions so that unescaped versions can be compared to the results of list-tables/views/attributes etc. It also allows you to be sure that an identifier is escaped only once. (escaped-database-identifiers *any-reasonable-object*) should be called to produce a string that is safe to splice directly into sql strings. (unescaped-database-identifier *any-reasonable-object*) is generally what you pass to it with the exception that symbols have been clsql-sys:sql-escape which converts to a string and changes - to _ (so that unescaped can be compared to the results of eg: list-tables) ")) (defmethod escaped ((it null)) it) (defmethod unescaped ((it null)) it) (defun database-identifier-equal (i1 i2 &optional (database clsql-sys:*default-database*)) (setf i1 (database-identifier i1 database) i2 (database-identifier i2 database)) (flet ((cast (i) (if (symbolp (unescaped i)) (sql-escape (unescaped i)) (unescaped i)))) (or ;; check for an exact match (equal (escaped-database-identifier i1) (escaped-database-identifier i2)) ;; check for an inexact match if we had symbols in the mix (string-equal (cast i1) (cast i2))))) (defun delistify-dsd (list) "Some MOPs, like openmcl 0.14.2, cons attribute values in a list." (if (and (listp list) (null (cdr list))) (car list) list)) (defun special-char-p (s) "Check if a string has any special characters" (loop for char across s thereis (find char '(#\space #\, #\. #\! #\@ #\# #\$ #\% #\' #\" #\^ #\& #\* #\| #\( #\) #\- #\+ #\< #\> #\{ #\})))) (defun special-cased-symbol-p (sym) "Should the symbols case be preserved, or should we convert to default casing" (let ((name (symbol-name sym))) (case (readtable-case *readtable*) (:upcase (not (string= (string-upcase name) name))) (:downcase (not (string= (string-downcase name) name))) (t t)))) (defun %make-database-identifier (inp &optional database) "We want to quote an identifier if it came to us as a string or if it has special characters in it." (labels ((%escape-identifier (inp &optional orig) "Quote an identifier unless it is already quoted" (cond ;; already quoted ((and (eql #\" (elt inp 0)) (eql #\" (elt inp (- (length inp) 1)))) (make-instance '%database-identifier :unescaped (or orig inp) :escaped inp)) (T (make-instance '%database-identifier :unescaped (or orig inp) :escaped (concatenate 'string "\"" (replace-all inp "\"" "\\\"") "\"")))))) (typecase inp (string (%escape-identifier inp)) (%database-identifier inp) (symbol (let ((s (sql-escape inp))) (if (and (not (eql '* inp)) (special-char-p s)) (%escape-identifier (if (special-cased-symbol-p inp) s (convert-to-db-default-case s database)) inp) (make-instance '%database-identifier :escaped s :unescaped inp)) ))))) (defun combine-database-identifiers (ids &optional (database clsql-sys:*default-database*) &aux res all-sym? pkg) "Create a new database identifier by combining parts in a reasonable way " (setf ids (mapcar #'database-identifier ids) all-sym? (every (lambda (i) (symbolp (unescaped i))) ids) pkg (when all-sym? (symbol-package (unescaped (first ids))))) (labels ((cast ( i ) (typecase i (null nil) (%database-identifier (cast (unescaped i))) (symbol (if all-sym? (sql-escape i) (convert-to-db-default-case (sql-escape i) database))) (string i))) (comb (i1 i2) (setf i1 (cast i1) i2 (cast i2)) (if (and i1 i2) (concatenate 'string (cast i1) "_" (cast i2)) (or i1 i2)))) (setf res (reduce #'comb ids)) (database-identifier (if all-sym? (intern res pkg) res) database))) (defun escaped-database-identifier (name &optional database find-class-p) (escaped (database-identifier name database find-class-p))) (defun unescaped-database-identifier (name &optional database find-class-p) (unescaped (database-identifier name database find-class-p))) (defun sql-output (sql-expr &optional (database *default-database*)) "Top-level call for generating SQL strings. Returns an SQL string appropriate for DATABASE which corresponds to the supplied lisp expression SQL-EXPR." (with-output-to-string (*sql-stream*) (output-sql sql-expr database))) (defmethod output-sql (expr database) (write-string (database-output-sql expr database) *sql-stream*) (values)) (defvar *output-hash* (make-weak-hash-table :test #'equal) "For caching generated SQL strings, set to NIL to disable." ) (defmethod output-sql :around ((sql t) database) (if (null *output-hash*) (call-next-method) (let* ((hash-key (output-sql-hash-key sql database)) (hash-value (when hash-key (gethash hash-key *output-hash*)))) (cond ((and hash-key hash-value) (write-string hash-value *sql-stream*)) (hash-key (let ((*sql-stream* (make-string-output-stream))) (call-next-method) (setf hash-value (get-output-stream-string *sql-stream*)) (setf (gethash hash-key *output-hash*) hash-value)) (write-string hash-value *sql-stream*)) (t (call-next-method)))))) (defmethod output-sql-hash-key (expr database) (declare (ignore expr database)) nil) (defclass %sql-expression () ()) (defmethod output-sql ((expr %sql-expression) database) (declare (ignore database)) (write-string +null-string+ *sql-stream*)) (defmethod print-object ((self %sql-expression) stream) (print-unreadable-object (self stream :type t) (write-string (sql-output self) stream)) self) ;; For straight up strings (defclass sql (%sql-expression) ((text :initarg :string :initform "")) (:documentation "A literal SQL expression.")) (defmethod make-load-form ((sql sql) &optional environment) (declare (ignore environment)) (with-slots (text) sql `(make-instance 'sql :string ',text))) (defmethod output-sql ((expr sql) database) (declare (ignore database)) (write-string (slot-value expr 'text) *sql-stream*) t) (defmethod print-object ((ident sql) stream) (format stream "#<~S \"~A\">" (type-of ident) (sql-output ident nil)) ident) ;; For SQL Identifiers of generic type (defclass sql-ident (%sql-expression) ((name :initarg :name :initform +null-string+)) (:documentation "An SQL identifer.")) (defmethod make-load-form ((sql sql-ident) &optional environment) (declare (ignore environment)) (with-slots (name) sql `(make-instance 'sql-ident :name ',name))) (defmethod output-sql ((expr %database-identifier) database) (write-string (escaped expr) *sql-stream*)) (defmethod output-sql ((expr sql-ident) database) (with-slots (name) expr (write-string (escaped-database-identifier name database) *sql-stream*)) t) ;; For SQL Identifiers for attributes (defclass sql-ident-attribute (sql-ident) ((qualifier :initarg :qualifier :initform +null-string+) (type :initarg :type :initform +null-string+)) (:documentation "An SQL Attribute identifier.")) (defmethod collect-table-refs (sql) (declare (ignore sql)) nil) (defmethod collect-table-refs ((sql list)) (loop for i in sql appending (listify (collect-table-refs i)))) (defmethod collect-table-refs ((sql sql-ident-attribute)) (let ((qual (slot-value sql 'qualifier))) (when qual ;; going to be used as a table, search classes (list (make-instance 'sql-ident-table :name (database-identifier qual nil t)))))) (defmethod make-load-form ((sql sql-ident-attribute) &optional environment) (declare (ignore environment)) (with-slots (qualifier type name) sql `(make-instance 'sql-ident-attribute :name ',name :qualifier ',qualifier :type ',type))) (defmethod output-sql-hash-key ((expr sql-ident-attribute) database) (with-slots (qualifier name type) expr (list (and database (database-underlying-type database)) 'sql-ident-attribute (unescaped-database-identifier qualifier) (unescaped-database-identifier name) type))) ;; For SQL Identifiers for tables (defclass sql-ident-table (sql-ident) ((alias :initarg :table-alias :initform nil)) (:documentation "An SQL table identifier.")) (defmethod make-load-form ((sql sql-ident-table) &optional environment) (declare (ignore environment)) (with-slots (alias name) sql `(make-instance 'sql-ident-table :name ',name :table-alias ',alias))) (defmethod collect-table-refs ((sql sql-ident-table)) (list sql)) (defmethod output-sql ((expr sql-ident-table) database) (with-slots (name alias) expr (flet ((p (s) ;; the etypecase is in sql-escape too (write-string (escaped-database-identifier s database) *sql-stream*))) (p name) (when alias (princ #\space *sql-stream*) (p alias)))) t) (defmethod output-sql ((expr sql-ident-attribute) database) ;;; KMR: The TYPE field is used by CommonSQL for type conversion -- it ;;; should not be output in SQL statements (let ((*print-pretty* nil)) (with-slots (qualifier name type) expr (format *sql-stream* "~@[~a.~]~a" (when qualifier ;; check for classes (escaped-database-identifier qualifier database T)) (escaped-database-identifier name database)) t))) (defmethod output-sql-hash-key ((expr sql-ident-table) database) (with-slots (name alias) expr (list (and database (database-underlying-type database)) 'sql-ident-table (unescaped-database-identifier name) (unescaped-database-identifier alias)))) (defclass sql-relational-exp (%sql-expression) ((operator :initarg :operator :initform nil) (sub-expressions :initarg :sub-expressions :initform nil)) (:documentation "An SQL relational expression.")) (defmethod make-load-form ((self sql-relational-exp) &optional environment) (make-load-form-saving-slots self :slot-names '(operator sub-expressions) :environment environment)) (defmethod collect-table-refs ((sql sql-relational-exp)) (let ((tabs nil)) (dolist (exp (slot-value sql 'sub-expressions)) (let ((refs (collect-table-refs exp))) (if refs (setf tabs (append refs tabs))))) (remove-duplicates tabs :test #'database-identifier-equal))) ;; Write SQL for relational operators (like 'AND' and 'OR'). ;; should do arity checking of subexpressions (defun %write-operator (operator database) (typecase operator (string (write-string operator *sql-stream*)) (symbol (write-string (symbol-name operator) *sql-stream*)) (T (output-sql operator database)))) (defmethod output-sql ((expr sql-relational-exp) database) (with-slots (operator sub-expressions) expr ;; we do this as two runs so as not to emit confusing superflous parentheses ;; The first loop renders all the child outputs so that we can skip anding with ;; empty output (which causes sql errors) ;; the next loop simply emits each sub-expression with the appropriate number of ;; parens and operators (flet ((trim (sub) (string-trim +whitespace-chars+ (with-output-to-string (*sql-stream*) (output-sql sub database))))) (let ((str-subs (loop for sub in sub-expressions for str-sub = (trim sub) when (and str-sub (> (length str-sub) 0)) collect str-sub))) (case (length str-subs) (0 nil) (1 (write-string (first str-subs) *sql-stream*)) (t (write-char #\( *sql-stream*) (write-string (first str-subs) *sql-stream*) (loop for str-sub in (rest str-subs) do (write-char #\Space *sql-stream*) ;; do this so that symbols can be output as database identifiers ;; rather than allowing symbols to inject sql (%write-operator operator database) (write-char #\Space *sql-stream*) (write-string str-sub *sql-stream*)) (write-char #\) *sql-stream*)) )))) t) (defclass sql-upcase-like (sql-relational-exp) () (:documentation "An SQL 'like' that upcases its arguments.")) (defmethod output-sql ((expr sql-upcase-like) database) (flet ((write-term (term) (write-string "upper(" *sql-stream*) (output-sql term database) (write-char #\) *sql-stream*))) (with-slots (sub-expressions) expr (let ((subs (if (consp (car sub-expressions)) (car sub-expressions) sub-expressions))) (write-char #\( *sql-stream*) (do ((sub subs (cdr sub))) ((null (cdr sub)) (write-term (car sub))) (write-term (car sub)) (write-string " LIKE " *sql-stream*)) (write-char #\) *sql-stream*)))) t) (defclass sql-assignment-exp (sql-relational-exp) () (:documentation "An SQL Assignment expression.")) (defmethod output-sql ((expr sql-assignment-exp) database) (with-slots (operator sub-expressions) expr (do ((sub sub-expressions (cdr sub))) ((null (cdr sub)) (output-sql (car sub) database)) (output-sql (car sub) database) (write-char #\Space *sql-stream*) (%write-operator operator database) (write-char #\Space *sql-stream*))) t) (defclass sql-value-exp (%sql-expression) ((modifier :initarg :modifier :initform nil) (components :initarg :components :initform nil)) (:documentation "An SQL value expression.") ) (defmethod collect-table-refs ((sql sql-value-exp)) (let ((tabs nil)) (if (listp (slot-value sql 'components)) (progn (dolist (exp (slot-value sql 'components)) (let ((refs (collect-table-refs exp))) (if refs (setf tabs (append refs tabs))))) (remove-duplicates tabs :test #'database-identifier-equal)) nil))) (defmethod output-sql ((expr sql-value-exp) database) (with-slots (modifier components) expr (if modifier (progn (write-char #\( *sql-stream*) (cond ((sql-operator modifier) (%write-operator modifier database)) ((or (stringp modifier) (symbolp modifier)) (write-string (escaped-database-identifier modifier) *sql-stream*)) (t (output-sql modifier database))) (write-char #\Space *sql-stream*) (output-sql components database) (write-char #\) *sql-stream*)) (output-sql components database)))) (defclass sql-typecast-exp (sql-value-exp) () (:documentation "An SQL typecast expression.")) (defmethod output-sql ((expr sql-typecast-exp) database) (with-slots (components) expr (output-sql components database))) (defmethod collect-table-refs ((sql sql-typecast-exp)) (when (slot-value sql 'components) (collect-table-refs (slot-value sql 'components)))) (defclass sql-function-exp (%sql-expression) ((name :initarg :name :initform nil) (args :initarg :args :initform nil)) (:documentation "An SQL function expression.")) (defmethod collect-table-refs ((sql sql-function-exp)) (let ((tabs nil)) (dolist (exp (slot-value sql 'args)) (let ((refs (collect-table-refs exp))) (if refs (setf tabs (append refs tabs))))) (remove-duplicates tabs :test #'database-identifier-equal))) (defvar *in-subselect* nil) (defmethod output-sql ((expr sql-function-exp) database) (with-slots (name args) expr (typecase name ((or string symbol) (write-string (escaped-database-identifier name) *sql-stream*)) (t (output-sql name database))) (let ((*in-subselect* nil)) ;; aboid double parens (when args (output-sql args database)))) t) (defclass sql-between-exp (sql-function-exp) () (:documentation "An SQL between expression.")) (defmethod output-sql ((expr sql-between-exp) database) (with-slots (args) expr (output-sql (first args) database) (write-string " BETWEEN " *sql-stream*) (output-sql (second args) database) (write-string " AND " *sql-stream*) (output-sql (third args) database)) t) (defclass sql-query-modifier-exp (%sql-expression) ((modifier :initarg :modifier :initform nil) (components :initarg :components :initform nil)) (:documentation "An SQL query modifier expression.")) (defmethod output-sql ((expr sql-query-modifier-exp) database) (with-slots (modifier components) expr (%write-operator modifier database) (write-string " " *sql-stream*) (%write-operator (car components) database) (when components (mapc #'(lambda (comp) (write-string ", " *sql-stream*) (output-sql comp database)) (cdr components)))) t) (defclass sql-set-exp (%sql-expression) ((operator :initarg :operator :initform nil) (sub-expressions :initarg :sub-expressions :initform nil)) (:documentation "An SQL set expression.")) (defmethod collect-table-refs ((sql sql-set-exp)) (let ((tabs nil)) (dolist (exp (slot-value sql 'sub-expressions)) (let ((refs (collect-table-refs exp))) (if refs (setf tabs (append refs tabs))))) (remove-duplicates tabs :test #'database-identifier-equal))) (defmethod output-sql ((expr sql-set-exp) database) (with-slots (operator sub-expressions) expr (let ((subs (if (consp (car sub-expressions)) (car sub-expressions) sub-expressions))) (when (= (length subs) 1) (%write-operator operator database) (write-char #\Space *sql-stream*)) (do ((sub subs (cdr sub))) ((null (cdr sub)) (output-sql (car sub) database)) (output-sql (car sub) database) (write-char #\Space *sql-stream*) (%write-operator operator database) (write-char #\Space *sql-stream*)))) t) (defclass sql-query (%sql-expression) ((selections :initarg :selections :initform nil) (all :initarg :all :initform nil) (flatp :initarg :flatp :initform nil) (set-operation :initarg :set-operation :initform nil) (distinct :initarg :distinct :initform nil) (from :initarg :from :initform nil) (where :initarg :where :initform nil) (group-by :initarg :group-by :initform nil) (having :initarg :having :initform nil) (limit :initarg :limit :initform nil) (offset :initarg :offset :initform nil) (order-by :initarg :order-by :initform nil) (inner-join :initarg :inner-join :initform nil) (on :initarg :on :initform nil)) (:documentation "An SQL SELECT query.")) (defclass sql-object-query (%sql-expression) ((objects :initarg :objects :initform nil) (flatp :initarg :flatp :initform nil) (exp :initarg :exp :initform nil) (refresh :initarg :refresh :initform nil))) (defmethod collect-table-refs ((sql sql-query)) (remove-duplicates (collect-table-refs (slot-value sql 'where)) :test #'database-identifier-equal)) (defvar *select-arguments* '(:all :database :distinct :flatp :from :group-by :having :order-by :set-operation :where :offset :limit :inner-join :on ;; below keywords are not a SQL argument, but these keywords may terminate select :caching :refresh)) (defun query-arg-p (sym) (member sym *select-arguments*)) (defun query-get-selections (select-args) "Return two values: the list of select-args up to the first keyword, uninclusive, and the args from that keyword to the end." (let ((first-key-arg (position-if #'query-arg-p select-args))) (if first-key-arg (values (subseq select-args 0 first-key-arg) (subseq select-args first-key-arg)) select-args))) (defun make-query (&rest args) (flet ((select-objects (target-args) (and target-args (every #'(lambda (arg) (and (symbolp arg) (find-class arg nil))) target-args)))) (multiple-value-bind (selections arglist) (query-get-selections args) (if (select-objects selections) (destructuring-bind (&key flatp refresh &allow-other-keys) arglist (make-instance 'sql-object-query :objects selections :flatp flatp :refresh refresh :exp arglist)) (destructuring-bind (&key all flatp set-operation distinct from where group-by having order-by offset limit inner-join on &allow-other-keys) arglist (if (null selections) (error "No target columns supplied to select statement.")) (if (null from) (error "No source tables supplied to select statement.")) (make-instance 'sql-query :selections selections :all all :flatp flatp :set-operation set-operation :distinct distinct :from from :where where :limit limit :offset offset :group-by group-by :having having :order-by order-by :inner-join inner-join :on on)))))) (defun output-sql-where-clause (where database) "ensure that we do not output a \"where\" sql keyword when we will not output a clause. Also sets *in-subselect* to use SQL parentheticals as needed." (when where (let ((where-out (string-trim '(#\newline #\space #\tab #\return) (with-output-to-string (*sql-stream*) (let ((*in-subselect* t)) (output-sql where database)))))) (when (> (length where-out) 0) (write-string " WHERE " *sql-stream*) (write-string where-out *sql-stream*))))) (defmethod output-sql ((query sql-query) database) (with-slots (distinct selections from where group-by having order-by limit offset inner-join on all set-operation) query (when *in-subselect* (write-string "(" *sql-stream*)) (write-string "SELECT " *sql-stream*) (when all (write-string " ALL " *sql-stream*)) (when (and distinct (not all)) (write-string " DISTINCT " *sql-stream*) (unless (eql t distinct) (write-string " ON " *sql-stream*) (output-sql distinct database) (write-char #\Space *sql-stream*))) (when (and limit (eql :mssql (database-underlying-type database))) (write-string " TOP " *sql-stream*) (output-sql limit database) (write-string " " *sql-stream*)) (let ((*in-subselect* t)) (output-sql (apply #'vector selections) database)) (when from (write-string " FROM " *sql-stream*) (typecase from (list (output-sql (apply #'vector (remove-duplicates from :test #'database-identifier-equal)) database)) (string (write-string (escaped-database-identifier from database) *sql-stream*)) (t (let ((*in-subselect* t)) (output-sql from database))))) (when inner-join (write-string " INNER JOIN " *sql-stream*) (output-sql inner-join database)) (when on (write-string " ON " *sql-stream*) (output-sql on database)) (output-sql-where-clause where database) (when group-by (write-string " GROUP BY " *sql-stream*) (if (listp group-by) (do ((order group-by (cdr order))) ((null order)) (let ((item (car order))) (typecase item (cons (output-sql (car item) database) (format *sql-stream* " ~A" (cadr item))) (t (output-sql item database))) (when (cdr order) (write-char #\, *sql-stream*)))) (output-sql group-by database))) (when having (write-string " HAVING " *sql-stream*) (output-sql having database)) (when order-by (write-string " ORDER BY " *sql-stream*) (if (listp order-by) (do ((order order-by (cdr order))) ((null order)) (let ((item (car order))) (typecase item (cons (output-sql (car item) database) (format *sql-stream* " ~A" (cadr item))) (t (output-sql item database))) (when (cdr order) (write-char #\, *sql-stream*)))) (output-sql order-by database))) (when (and limit (not (eql :mssql (database-underlying-type database)))) (write-string " LIMIT " *sql-stream*) (output-sql limit database)) (when offset (write-string " OFFSET " *sql-stream*) (output-sql offset database)) (when *in-subselect* (write-string ")" *sql-stream*)) (when set-operation (write-char #\Space *sql-stream*) (output-sql set-operation database))) t) (defmethod output-sql ((query sql-object-query) database) (declare (ignore database)) (with-slots (objects) query (when objects (format *sql-stream* "(~{~A~^ ~})" objects)))) ;; INSERT (defclass sql-insert (%sql-expression) ((into :initarg :into :initform nil) (attributes :initarg :attributes :initform nil) (values :initarg :values :initform nil) (query :initarg :query :initform nil)) (:documentation "An SQL INSERT statement.")) (defmethod output-sql ((ins sql-insert) database) (with-slots (into attributes values query) ins (write-string "INSERT INTO " *sql-stream*) (output-sql (typecase into (string (sql-expression :table into)) (t into)) database) (when attributes (write-char #\Space *sql-stream*) (output-sql attributes database)) (when values (write-string " VALUES " *sql-stream*) (let ((clsql-sys::*in-subselect* t)) (output-sql values database))) (when query (write-char #\Space *sql-stream*) (output-sql query database))) t) ;; DELETE (defclass sql-delete (%sql-expression) ((from :initarg :from :initform nil) (where :initarg :where :initform nil)) (:documentation "An SQL DELETE statement.")) (defmethod output-sql ((stmt sql-delete) database) (with-slots (from where) stmt (write-string "DELETE FROM " *sql-stream*) (typecase from ((or symbol string) (write-string (sql-escape from) *sql-stream*)) (t (output-sql from database))) (output-sql-where-clause where database)) t) ;; UPDATE (defclass sql-update (%sql-expression) ((table :initarg :table :initform nil) (attributes :initarg :attributes :initform nil) (values :initarg :values :initform nil) (where :initarg :where :initform nil)) (:documentation "An SQL UPDATE statement.")) (defmethod output-sql ((expr sql-update) database) (with-slots (table where attributes values) expr (flet ((update-assignments () (mapcar #'(lambda (a b) (make-instance 'sql-assignment-exp :operator '= :sub-expressions (list a b))) attributes values))) (write-string "UPDATE " *sql-stream*) (output-sql table database) (write-string " SET " *sql-stream*) (let ((clsql-sys::*in-subselect* t)) (output-sql (apply #'vector (update-assignments)) database)) (output-sql-where-clause where database))) t) ;; CREATE TABLE (defclass sql-create-table (%sql-expression) ((name :initarg :name :initform nil) (columns :initarg :columns :initform nil) (modifiers :initarg :modifiers :initform nil) (transactions :initarg :transactions :initform nil)) (:documentation "An SQL CREATE TABLE statement.")) ;; Here's a real warhorse of a function! (declaim (inline listify)) (defun listify (x) (if (listp x) x (list x))) (defmethod output-sql ((stmt sql-create-table) database) (flet ((output-column (column-spec) (destructuring-bind (name type &optional db-type &rest constraints) column-spec (let ((type (listify type))) (output-sql name database) (write-char #\Space *sql-stream*) (write-string (if (stringp db-type) db-type ; override definition (database-get-type-specifier (car type) (cdr type) database (database-underlying-type database))) *sql-stream*) (let ((constraints (database-constraint-statement (if (and db-type (symbolp db-type)) (cons db-type constraints) constraints) database))) (when constraints (write-string " " *sql-stream*) (write-string constraints *sql-stream*))))))) (with-slots (name columns modifiers transactions) stmt (write-string "CREATE TABLE " *sql-stream*) (write-string (escaped-database-identifier name database) *sql-stream*) (write-string " (" *sql-stream*) (do ((column columns (cdr column))) ((null (cdr column)) (output-column (car column))) (output-column (car column)) (write-string ", " *sql-stream*)) (when modifiers (do ((modifier (listify modifiers) (cdr modifier))) ((null modifier)) (write-string ", " *sql-stream*) (write-string (car modifier) *sql-stream*))) (write-char #\) *sql-stream*) (when (and (eq :mysql (database-underlying-type database)) transactions (db-type-transaction-capable? :mysql database)) (write-string " ENGINE=innodb" *sql-stream*)))) t) ;; CREATE VIEW (defclass sql-create-view (%sql-expression) ((name :initarg :name :initform nil) (column-list :initarg :column-list :initform nil) (query :initarg :query :initform nil) (with-check-option :initarg :with-check-option :initform nil)) (:documentation "An SQL CREATE VIEW statement.")) (defmethod output-sql ((stmt sql-create-view) database) (with-slots (name column-list query with-check-option) stmt (write-string "CREATE VIEW " *sql-stream*) (output-sql name database) (when column-list (write-string " " *sql-stream*) (output-sql (listify column-list) database)) (write-string " AS " *sql-stream*) (output-sql query database) (when with-check-option (write-string " WITH CHECK OPTION" *sql-stream*)))) ;; ;; DATABASE-OUTPUT-SQL ;; (defmethod database-output-sql ((str string) database) (declare (optimize (speed 3) (safety 1) #+cmu (extensions:inhibit-warnings 3))) (let ((len (length str))) (declare (type fixnum len)) (cond ((zerop len) +empty-string+) ((and (null (position #\' str)) (null (position #\\ str))) (concatenate 'string "'" str "'")) (t (let ((buf (make-string (+ (* len 2) 2) :initial-element #\'))) (declare (simple-string buf)) (do* ((i 0 (incf i)) (j 1 (incf j))) ((= i len) (subseq buf 0 (1+ j))) (declare (type fixnum i j)) (let ((char (aref str i))) (declare (character char)) (cond ((char= char #\') (setf (aref buf j) #\') (incf j) (setf (aref buf j) #\')) ((and (char= char #\\) ;; MTP: only escape backslash with pgsql/mysql (member (database-underlying-type database) '(:postgresql :mysql) :test #'eq)) (setf (aref buf j) #\\) (incf j) (setf (aref buf j) #\\)) (t (setf (aref buf j) char)))))))))) (let ((keyword-package (symbol-package :foo))) (defmethod database-output-sql ((sym symbol) database) (if (null sym) +null-string+ (if (equal (symbol-package sym) keyword-package) (database-output-sql (symbol-name sym) database) (escaped-database-identifier sym))))) (defmethod database-output-sql ((tee (eql t)) database) (if database (let ((val (database-output-sql-as-type 'boolean t database (database-type database)))) (when val (typecase val (string (format nil "'~A'" val)) (integer (format nil "~A" val))))) "'Y'")) #+nil(defmethod database-output-sql ((tee (eql t)) database) (declare (ignore database)) "'Y'") (defmethod database-output-sql ((num number) database) (declare (ignore database)) (number-to-sql-string num)) (defmethod database-output-sql ((arg list) database) (if (null arg) +null-string+ (format nil "(~{~A~^,~})" (mapcar #'(lambda (val) (sql-output val database)) arg)))) (defmethod database-output-sql ((arg vector) database) (format nil "~{~A~^,~}" (map 'list #'(lambda (val) (sql-output val database)) arg))) (defmethod output-sql-hash-key ((arg vector) database) (list 'vector (map 'list (lambda (arg) (or (output-sql-hash-key arg database) (return-from output-sql-hash-key nil))) arg))) (defmethod database-output-sql ((self wall-time) database) (declare (ignore database)) (db-timestring self)) (defmethod database-output-sql ((self date) database) (declare (ignore database)) (db-datestring self)) (defmethod database-output-sql ((self duration) database) (declare (ignore database)) (format nil "'~a'" (duration-timestring self))) #+ignore (defmethod database-output-sql ((self money) database) (database-output-sql (slot-value self 'odcl::units) database)) (defmethod database-output-sql (thing database) (if (or (null thing) (eq 'null thing)) +null-string+ (error 'sql-user-error :message (format nil "No type conversion to SQL for ~A is defined for DB ~A." (type-of thing) (type-of database))))) ;; ;; Column constraint types and conversion to SQL ;; (defmethod database-constraint-statement (constraint-list database) (make-constraints-description constraint-list database)) ;; KEEP THIS SYNCED WITH database-translate-constraint (defparameter +auto-increment-names+ '(:auto-increment :auto_increment :autoincrement :identity)) (defmethod database-translate-constraint (constraint database) (case constraint (:not-null "NOT NULL") (:primary-key "PRIMARY KEY") ((:auto-increment :auto_increment :autoincrement :identity) (ecase (database-underlying-type database) (:mssql "IDENTITY (1,1)") ((:sqlite :sqlite3) "PRIMARY KEY AUTOINCREMENT") (:mysql "AUTO_INCREMENT") ;; this is modeled as a datatype instead of a constraint (:postgresql ""))) ;; everything else just get the name (T (string-upcase (symbol-name constraint))))) (defun make-constraints-description (constraint-list database &aux (rest constraint-list) constraint) (when constraint-list (flet ((next () (setf constraint (first rest) rest (rest rest)) constraint)) (with-output-to-string (s) (loop while (next) do (unless (keywordp constraint) (setf constraint (intern (symbol-name constraint) :keyword))) (write-string (database-translate-constraint constraint database) s) (when (eql :default constraint) (princ (next) s)) (write-char #\space s) ))))) (defmethod database-identifier ( name &optional database find-class-p &aux cls) "A function that takes whatever you give it, recursively coerces it, and returns a database-identifier. (escaped-database-identifiers *any-reasonable-object*) should be called to produce a string that is safe to splice directly into sql strings. This function should NOT throw errors when database is nil find-class-p should be T if we want to search for classes and check their use their view table. Should be used on symbols we are sure indicate tables ;; metaclasses has further typecases of this, so that it will ;; load less painfully (try-recompiles) in SBCL " (flet ((flatten-id (id) "if we have multiple pieces that we need to represent as db-id lets do that by rendering out the id, then creating a new db-id with that string as escaped" (let ((s (sql-output id database))) (make-instance '%database-identifier :escaped s :unescaped s)))) (setf name (dequote name)) (etypecase name (null nil) (string (%make-database-identifier name database)) (symbol ;; if this is being used as a table, we should check ;; for a class with this name and use the identifier specified ;; on it (if (and find-class-p (setf cls (find-standard-db-class name))) (database-identifier cls) (%make-database-identifier name database))) (%database-identifier name) ;; we know how to deref this without further escaping (sql-ident-table (with-slots ((inner-name name) alias) name (if alias (flatten-id name) (database-identifier inner-name)))) ;; if this is a single name we can derefence it (sql-ident-attribute (with-slots (qualifier (inner-name name)) name (if qualifier (flatten-id name) (database-identifier inner-name)))) (sql-ident (with-slots ((inner-name name)) name (database-identifier inner-name))) ;; dont know how to handle this really :/ (%sql-expression (flatten-id name)) ))) (defun %clsql-subclauses (clauses) "a helper for dealing with lists of sql clauses" (loop for c in clauses when c collect (typecase c (string (clsql-sys:sql-expression :string c)) (T c)))) (defun clsql-ands (clauses) "Correctly creates a sql 'and' expression for the clauses ignores any nil clauses returns a single child expression if there is only one returns an 'and' expression if there are many returns nil if there are no children" (let ((ex (%clsql-subclauses clauses))) (when ex (case (length ex) (1 (first ex)) (t (apply #'clsql-sys:sql-and ex)))))) (defun clsql-and (&rest clauses) "Correctly creates a sql 'and' expression for the clauses ignores any nil clauses returns a single child expression if there is only one returns an 'and' expression if there are many returns nil if there are no children" (clsql-ands clauses)) (defun clsql-ors (clauses) "Correctly creates a sql 'or' expression for the clauses ignores any nil clauses returns a single child expression if there is only one returns an 'or' expression if there are many returns nil if there are no children" (let ((ex (%clsql-subclauses clauses))) (when ex (case (length ex) (1 (first ex)) (t (apply #'clsql-sys:sql-or ex)))))) (defun clsql-or (&rest clauses) "Correctly creates a sql 'or' expression for the clauses ignores any nil clauses returns a single child expression if there is only one returns an 'or' expression if there are many returns nil if there are no children" (clsql-ors clauses)) (defclass sql-escape-string-exp (%sql-expression) ((string :initarg :string :initform nil)) (:documentation "An escaped string string expression (postgresql E'stuff') .")) (defmethod output-sql ((exp sql-escape-string-exp) database) (with-slots (string) exp (when string (write-char #\E *sql-stream*) (output-sql string database)))) cl-sql-6.7.2/sql/fddl.lisp0000644000175000017500000004757512303270414014352 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; The CLSQL Functional Data Definition Language (FDDL) ;;;; including functions for schema manipulation. Currently supported ;;;; SQL objects include tables, views, indexes, attributes and ;;;; sequences. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) ;; Truncate database (defun truncate-database (&key (database *default-database*)) "Drops all tables, views, indexes and sequences in DATABASE which defaults to *DEFAULT-DATABASE*." (unless (typep database 'database) (signal-no-database-error database)) (unless (is-database-open database) (database-reconnect database)) (when (eq :oracle (database-type database)) (ignore-errors (execute-command "PURGE RECYCLEBIN" :database database))) (when (db-type-has-views? (database-underlying-type database)) (dolist (view (list-views :database database)) (drop-view view :database database))) (dolist (table (list-tables :database database)) (drop-table table :database database)) (dolist (index (list-indexes :database database)) (drop-index index :database database)) (dolist (seq (list-sequences :database database)) (drop-sequence seq :database database)) (when (eq :oracle (database-type database)) (ignore-errors (execute-command "PURGE RECYCLEBIN" :database database))) (values)) ;; Tables (defun create-table (name description &key (database *default-database*) (constraints nil) (transactions t)) "Creates a table called NAME, which may be a string, symbol or SQL table identifier, in DATABASE which defaults to *DEFAULT-DATABASE*. DESCRIPTION is a list whose elements are lists containing the attribute names, types, and other constraints such as not-null or primary-key for each column in the table. CONSTRAINTS is a string representing an SQL table constraint expression or a list of such strings. With MySQL databases, if TRANSACTIONS is t an InnoDB table is created which supports transactions." (execute-command (make-instance 'sql-create-table :name name :columns description :modifiers constraints :transactions transactions) :database database)) (defun drop-table (name &key (if-does-not-exist :error) (database *default-database*) (owner nil)) "Drops the table called NAME from DATABASE which defaults to *DEFAULT-DATABASE*. If the table does not exist and IF-DOES-NOT-EXIST is :ignore then DROP-TABLE returns nil whereas an error is signalled if IF-DOES-NOT-EXIST is :error." (ecase if-does-not-exist (:ignore (unless (table-exists-p name :database database :owner owner) (return-from drop-table nil))) (:error t)) (let ((expr (concatenate 'string "DROP TABLE " (escaped-database-identifier name database)))) ;; Fixme: move to clsql-oracle (when (and (find-package 'clsql-oracle) (eq :oracle (database-type database)) (eql 10 (slot-value database (intern (symbol-name '#:major-server-version) (symbol-name '#:clsql-oracle))))) (setq expr (concatenate 'string expr " PURGE"))) (execute-command expr :database database))) (defun list-tables (&key (owner nil) (database *default-database*)) "Returns a list of strings representing table names in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only tables owned by users are listed. If OWNER is a string denoting a user name, only tables owned by OWNER are listed. If OWNER is :all then all tables are listed." (database-list-tables database :owner owner)) (defmethod %table-exists-p (name (database T) &key owner ) (unless database (setf database *default-database*)) (let ((name (database-identifier name database)) (tables (list-tables :owner owner :database database))) (when (member name tables :test #'database-identifier-equal) t))) (defun table-exists-p (name &key (owner nil) (database *default-database*)) "Tests for the existence of an SQL table called NAME in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only tables owned by users are examined. If OWNER is a string denoting a user name, only tables owned by OWNER are examined. If OWNER is :all then all tables are examined." (%table-exists-p name database :owner owner)) ;; Views (defun create-view (name &key as column-list (with-check-option nil) (database *default-database*)) "Creates a view called NAME in DATABASE which defaults to *DEFAULT-DATABASE*. The view is created using the query AS and the columns of the view may be specified using the COLUMN-LIST parameter. The WITH-CHECK-OPTION is nil by default but if it has a non-nil value, then all insert/update commands on the view are checked to ensure that the new data satisfy the query AS." (let* ((view-name (database-identifier name)) (stmt (make-instance 'sql-create-view :name view-name :column-list column-list :query as :with-check-option with-check-option))) (execute-command stmt :database database))) (defun drop-view (name &key (if-does-not-exist :error) (database *default-database*)) "Drops the view called NAME from DATABASE which defaults to *DEFAULT-DATABASE*. If the view does not exist and IF-DOES-NOT-EXIST is :ignore then DROP-VIEW returns nil whereas an error is signalled if IF-DOES-NOT-EXIST is :error." (ecase if-does-not-exist (:ignore (unless (view-exists-p name :database database) (return-from drop-view))) (:error t)) (let ((expr (concatenate 'string "DROP VIEW " (escaped-database-identifier name database)))) (execute-command expr :database database))) (defun list-views (&key (owner nil) (database *default-database*)) "Returns a list of strings representing view names in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only views owned by users are listed. If OWNER is a string denoting a user name, only views owned by OWNER are listed. If OWNER is :all then all views are listed." (database-list-views database :owner owner)) (defun view-exists-p (name &key (owner nil) (database *default-database*)) "Tests for the existence of an SQL view called NAME in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only views owned by users are examined. If OWNER is a string denoting a user name, only views owned by OWNER are examined. If OWNER is :all then all views are examined." (when (member (database-identifier name database) (list-views :owner owner :database database) :test #'database-identifier-equal) t)) ;; Indexes (defun create-index (name &key on (unique nil) attributes (database *default-database*)) "Creates an index called NAME on the table specified by ON in DATABASE which default to *DEFAULT-DATABASE*. The table attributes to use in constructing the index NAME are specified by ATTRIBUTES. The UNIQUE argument is nil by default but if it has a non-nil value then the indexed attributes must have unique values." (let* ((index-name (escaped-database-identifier name database)) (table-name (escaped-database-identifier on database)) (attributes (mapcar #'(lambda (a) (escaped-database-identifier a database)) (listify attributes))) (stmt (format nil "CREATE ~A INDEX ~A ON ~A (~{~A~^, ~})" (if unique "UNIQUE" "") index-name table-name attributes))) (execute-command stmt :database database))) (defun drop-index (name &key (if-does-not-exist :error) (on nil) (database *default-database*)) "Drops the index called NAME in DATABASE which defaults to *DEFAULT-DATABASE*. If the index does not exist and IF-DOES-NOT-EXIST is :ignore then DROP-INDEX returns nil whereas an error is signalled if IF-DOES-NOT-EXIST is :error. The argument ON allows the optional specification of a table to drop the index from." (ecase if-does-not-exist (:ignore (unless (index-exists-p name :database database) (return-from drop-index))) (:error t)) (let* ((db-type (database-underlying-type database)) (on (when on (escaped-database-identifier on database))) (index-name (escaped-database-identifier name database)) (index-identifier (cond ((db-type-use-fully-qualified-column-on-drop-index? db-type) (format nil "~A.~A" on index-name)) ((db-type-use-column-on-drop-index? db-type) (format nil "~A ON ~A" index-name on)) (t index-name)))) (execute-command (format nil "DROP INDEX ~A" index-identifier) :database database))) (defun list-indexes (&key (owner nil) (database *default-database*) (on nil)) "Returns a list of strings representing index names in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only indexes owned by users are listed. If OWNER is a string denoting a user name, only indexes owned by OWNER are listed. If OWNER is :all then all indexes are listed. The keyword argument ON limits the results to indexes on the specified tables. Meaningful values for ON are nil (the default) which means that all tables are considered, a string, symbol or SQL expression representing a table name in DATABASE or a list of such table identifiers." (if (null on) (database-list-indexes database :owner owner) (let ((tables (typecase on (cons on) (t (list on))))) (reduce #'append (mapcar #'(lambda (table) (database-list-table-indexes table database :owner owner)) tables))))) (defun index-exists-p (name &key (owner nil) (database *default-database*)) "Tests for the existence of an SQL index called NAME in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only indexes owned by users are examined. If OWNER is a string denoting a user name, only indexes owned by OWNER are examined. If OWNER is :all then all indexes are examined." (when (member (database-identifier name database) (list-indexes :owner owner :database database) :test #'database-identifier-equal) t)) ;; Attributes (defvar *cache-table-queries-default* nil "Specifies the default behaivour for caching of attribute types. Meaningful values are t, nil and :flush as described for the action argument to CACHE-TABLE-QUERIES.") (defun cache-table-queries (table &key (action nil) (database *default-database*)) "Controls the caching of attribute type information on the table specified by TABLE in DATABASE which defaults to *DEFAULT-DATABASE*. ACTION specifies the caching behaviour to adopt. If its value is t then attribute type information is cached whereas if its value is nil then attribute type information is not cached. If ACTION is :flush then all existing type information in the cache for TABLE is removed, but caching is still enabled. TABLE may be a string representing a table for which the caching action is to be taken while the caching action is applied to all tables if TABLE is t. Alternativly, when TABLE is :default, the default caching action specified by *CACHE-TABLE-QUERIES-DEFAULT* is applied to all table for which a caching action has not been explicitly set." (with-slots (attribute-cache) database (cond ((stringp table) (multiple-value-bind (val found) (gethash table attribute-cache) (cond ((and found (eq action :flush)) (setf (gethash table attribute-cache) (list t nil))) ((and found (eq action t)) (setf (gethash table attribute-cache) (list t (second val)))) ((and found (null action)) (setf (gethash table attribute-cache) (list nil nil))) ((not found) (setf (gethash table attribute-cache) (list action nil)))))) ((eq table t) (maphash (lambda (k v) (cond ((eq action :flush) (setf (gethash k attribute-cache) (list t nil))) ((null action) (setf (gethash k attribute-cache) (list nil nil))) ((eq t action) (setf (gethash k attribute-cache) (list t (second v)))))) attribute-cache)) ((eq table :default) (maphash (lambda (k v) (when (eq (first v) :unspecified) (cond ((eq action :flush) (setf (gethash k attribute-cache) (list t nil))) ((null action) (setf (gethash k attribute-cache) (list nil nil))) ((eq t action) (setf (gethash k attribute-cache) (list t (second v))))))) attribute-cache)))) (values)) (defun list-attributes (name &key (owner nil) (database *default-database*)) "Returns a list of strings representing the attributes of table NAME in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only attributes owned by users are listed. If OWNER is a string denoting a user name, only attributes owned by OWNER are listed. If OWNER is :all then all attributes are listed." (database-list-attributes (database-identifier name database) database :owner owner)) (defun attribute-type (attribute table &key (owner nil) (database *default-database*)) "Returns a keyword representing the vendor-specific field type of the supplied attribute ATTRIBUTE in the table specified by TABLE in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that the attribute specified by ATTRIBUTE, if it exists, must be user owned else nil is returned. If OWNER is a string denoting a user name, the attribute, if it exists, must be owned by OWNER else nil is returned, whereas if OWNER is :all then the attribute, if it exists, will be returned regardless of its owner." (database-attribute-type (database-identifier attribute database) (database-identifier table database) database :owner owner)) (defun list-attribute-types (table &key (owner nil) (database *default-database*)) "Returns a list containing information about the SQL types of each of the attributes in the table specified by TABLE in DATABASE which has a default value of *DEFAULT-DATABASE*. OWNER is nil by default which means that only attributes owned by users are listed. If OWNER is a string denoting a user name, only attributes owned by OWNER are listed. If OWNER is :all then all attributes are listed. The elements of the returned list are lists where the first element is the name of the attribute, the second element is its SQL type, the third is the type precision, the fourth is the scale of the attribute and the fifth is 1 if the attribute accepts null values and otherwise 0." (with-slots (attribute-cache) database (let ((table-ident (database-identifier table database))) (multiple-value-bind (val found) (gethash table attribute-cache) (if (and found (second val)) (second val) (let ((types (mapcar #'(lambda (attribute) (cons attribute (multiple-value-list (database-attribute-type (database-identifier attribute database) table-ident database :owner owner)))) (list-attributes table :database database :owner owner)))) (cond ((and (not found) (eq t *cache-table-queries-default*)) (setf (gethash table attribute-cache) (list :unspecified types))) ((and found (eq t (first val)) (setf (gethash table attribute-cache) (list t types))))) types)))))) ;; Sequences (defun create-sequence (name &key (database *default-database*)) "Creates a sequence called NAME in DATABASE which defaults to *DEFAULT-DATABASE*." (let ((sequence-name (database-identifier name database))) (database-create-sequence sequence-name database)) (values)) (defun drop-sequence (name &key (if-does-not-exist :error) (database *default-database*)) "Drops the sequence called NAME from DATABASE which defaults to *DEFAULT-DATABASE*. If the sequence does not exist and IF-DOES-NOT-EXIST is :ignore then DROP-SEQUENCE returns nil whereas an error is signalled if IF-DOES-NOT-EXIST is :error." (ecase if-does-not-exist (:ignore (unless (sequence-exists-p name :database database) (return-from drop-sequence))) (:error t)) (database-drop-sequence name database) (values)) (defun list-sequences (&key (owner nil) (database *default-database*)) "Returns a list of strings representing sequence names in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only sequences owned by users are listed. If OWNER is a string denoting a user name, only sequences owned by OWNER are listed. If OWNER is :all then all sequences are listed." (database-list-sequences database :owner owner)) (defun sequence-exists-p (name &key (owner nil) (database *default-database*)) "Tests for the existence of an SQL sequence called NAME in DATABASE which defaults to *DEFAULT-DATABASE*. OWNER is nil by default which means that only sequences owned by users are examined. If OWNER is a string denoting a user name, only sequences owned by OWNER are examined. If OWNER is :all then all sequences are examined." (let ((seqs (list-sequences :owner owner :database database)) ;; handle symbols, we know the db will return strings (n1 (database-identifier name database)) (n2 (%sequence-name-to-table name database))) (when (or (member n1 seqs :test #'database-identifier-equal) (member n2 seqs :test #'database-identifier-equal)) t))) (defun sequence-next (name &key (database *default-database*)) "Increment and return the next value in the sequence called NAME in DATABASE which defaults to *DEFAULT-DATABASE*." (database-sequence-next (database-identifier name database) database)) (defun set-sequence-position (name position &key (database *default-database*)) "Explicitly set the the position of the sequence called NAME in DATABASE, which defaults to *DEFAULT-DATABASE*, to POSITION which is returned." (database-set-sequence-position (database-identifier name database) position database)) (defun sequence-last (name &key (database *default-database*)) "Return the last value allocated in the sequence called NAME in DATABASE which defaults to *DEFAULT-DATABASE*." (database-sequence-last (database-identifier name database) database)) cl-sql-6.7.2/sql/transaction.lisp0000644000175000017500000001535112021503403015743 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Transaction support ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass transaction () ((commit-hooks :initform () :accessor commit-hooks) (rollback-hooks :initform () :accessor rollback-hooks) (previous-autocommit :initarg :previous-autocommit :reader previous-autocommit) (status :initform nil :accessor transaction-status :documentation "nil or :committed"))) (defun add-transaction-commit-hook (commit-hook &key (database *default-database*)) "Adds COMMIT-HOOK, which should a designator for a function with no required arguments, to the list of hooks run when COMMIT is called on DATABASE which defaults to *DEFAULT-DATABASE*." (when (transaction database) (push commit-hook (commit-hooks (transaction database))))) (defun add-transaction-rollback-hook (rollback-hook &key (database *default-database*)) "Adds ROLLBACK-HOOK, which should a designator for a function with no required arguments, to the list of hooks run when ROLLBACK is called on DATABASE which defaults to *DEFAULT-DATABASE*." (when (transaction database) (push rollback-hook (rollback-hooks (transaction database))))) (defmethod database-start-transaction ((database database)) (unless (transaction database) (setf (transaction database) (make-instance 'transaction :previous-autocommit (database-autocommit database)))) ;; TODO: database-autocommit might get lost in some scenarios ;; when pooling connections (setf (database-autocommit database) nil) (when (= (incf (transaction-level database)) 1) (let ((transaction (transaction database))) (setf (commit-hooks transaction) nil (rollback-hooks transaction) nil (transaction-status transaction) nil) (case (database-underlying-type database) (:oracle nil) (:mssql (execute-command "BEGIN TRANSACTION" :database database)) (t (execute-command "BEGIN" :database database)))))) ;;ODBC should potentially be using the following scheme for transactions: ;; turn off autocommit for begin. then use sqlendtran (or maybe sqltransact) ;; whatever is appropriate for this version of odbc. (defmethod database-commit-transaction ((database database)) (with-slots (transaction transaction-level autocommit) database (if (plusp transaction-level) (if (zerop (decf transaction-level)) (progn (case (database-underlying-type database) (:mssql (execute-command "COMMIT TRANSACTION" :database database)) (t (execute-command "COMMIT" :database database))) (setf autocommit (previous-autocommit transaction)) (map nil #'funcall (commit-hooks transaction))) (setf (transaction-status (transaction database)) nil)) (warn 'sql-warning :message (format nil "Cannot commit transaction against ~A because there is no transaction in progress." database))))) (defmethod database-abort-transaction ((database database)) (with-slots (transaction transaction-level autocommit) database (if (plusp transaction-level) (when (zerop (decf transaction-level)) (unwind-protect (case (database-underlying-type database) (:mssql (execute-command "ROLLBACK TRANSACTION" :database database)) (t (execute-command "ROLLBACK" :database database))) (setf autocommit (previous-autocommit transaction)) (map nil #'funcall (rollback-hooks transaction)))) (warn 'sql-warning :message (format nil "Cannot abort transaction against ~A because there is no transaction in progress." database))))) (defun mark-transaction-committed (database) (when (and (transaction database) (not (transaction-status (transaction database)))) (setf (transaction-status (transaction database)) :committed))) (defmacro with-transaction ((&key (database '*default-database*)) &body body) "Starts a transaction in the database specified by DATABASE, which is *DEFAULT-DATABASE* by default, and executes BODY within that transaction. If BODY aborts or throws, DATABASE is rolled back and otherwise the transaction is committed." (let ((db (gensym "db-"))) `(let ((,db ,database)) (unwind-protect (prog2 (database-start-transaction ,db) (progn ,@body) (mark-transaction-committed ,db)) (if (eq (transaction-status (transaction ,db)) :committed) (database-commit-transaction ,db) (database-abort-transaction ,db)))))) (defun commit (&key (database *default-database*)) "If DATABASE, which defaults to *DEFAULT-DATABASE*, is currently within the scope of a transaction, commits changes made since the transaction began." (database-commit-transaction database) nil) (defun rollback (&key (database *default-database*)) "If DATABASE, which defaults to *DEFAULT-DATABASE*, is currently within the scope of a transaction, rolls back changes made since the transaction began." (database-abort-transaction database) nil) (defun start-transaction (&key (database *default-database*)) "Starts a transaction block on DATABASE which defaults to *DEFAULT-DATABASE* and which continues until ROLLBACK or COMMIT are called." (unless (in-transaction-p :database database) (database-start-transaction database)) nil) (defun in-transaction-p (&key (database *default-database*)) "A predicate to test whether DATABASE, which defaults to *DEFAULT-DATABASE*, is currently within the scope of a transaction." (and database (transaction database) (= (transaction-level database) 1))) (defun set-autocommit (value &key (database *default-database*)) "Turns autocommit off for DATABASE if VALUE is NIL, and otherwise turns it on. Returns the old value of autocommit flag. For RDBMS (such as Oracle) which don't automatically commit changes, turning autocommit on has the effect of explicitly committing changes made whenever SQL statements are executed. Autocommit is turned on by default." (let ((old-value (database-autocommit database))) (setf (database-autocommit database) value) (database-autocommit database) old-value)) cl-sql-6.7.2/sql/cmucl-compat.lisp0000644000175000017500000000575411335067642016031 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: cmucl-compat.lisp ;;;; Purpose: Compatiblity library for CMUCL functions ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage #:cmucl-compat (:use #:common-lisp) (:export #:shrink-vector #:make-sequence-of-type #:result-type-or-lose #:required-argument )) (in-package #:cmucl-compat) #+(or cmu scl) (defmacro required-argument () `(ext:required-argument)) #-(or cmu scl) (defun required-argument () (error "~&A required keyword argument was not supplied")) #+(or cmu scl) (defmacro shrink-vector (vec len) `(lisp::shrink-vector ,vec ,len)) #+sbcl (defmacro shrink-vector (vec len) `(sb-kernel::shrink-vector ,vec ,len)) #-(or cmu sbcl scl) (defmacro shrink-vector (vec len) "Shrinks a vector. Optimized if vector has a fill pointer. Needs to be a macro to overwrite value of VEC." (let ((new-vec (gensym))) `(cond ((adjustable-array-p ,vec) (adjust-array ,vec ,len)) ((typep ,vec 'simple-array) (let ((,new-vec (make-array ,len :element-type (array-element-type ,vec)))) (check-type ,len fixnum) (locally (declare (optimize (speed 3) (safety 0) (space 0)) ) (dotimes (i ,len) (declare (fixnum i)) (setf (aref ,new-vec i) (aref ,vec i)))) (setq ,vec ,new-vec))) ((typep ,vec 'vector) (setf (fill-pointer ,vec) ,len) ,vec) (t (error "Unable to shrink vector ~S which is type-of ~S" ,vec (type-of ,vec))) ))) #-(or cmu scl) (defun make-sequence-of-type (type length) "Returns a sequence of the given TYPE and LENGTH." (make-sequence type length)) #+(or cmu scl) (if (fboundp 'lisp::make-sequence-of-type) (defun make-sequence-of-type (type len) (lisp::make-sequence-of-type type len)) (defun make-sequence-of-type (type len) (common-lisp::make-sequence-of-type type len))) #-(or cmu scl) (defun result-type-or-lose (type nil-ok) (unless (or type nil-ok) (error "NIL output type invalid for this sequence function")) (case type ((list cons) 'list) ((string simple-string base-string simple-base-string) 'string) (simple-vector 'simple-vector) (vector 'vector) (t (error "~S is a bad type specifier for sequence functions." type)) )) #+(or cmu scl) (defun result-type-or-lose (type nil-ok) (lisp::result-type-or-lose type nil-ok)) cl-sql-6.7.2/sql/fdml.lisp0000644000175000017500000005370712064366222014364 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; The CLSQL Functional Data Manipulation Language (FDML). ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) ;; some helpers to make dealing with attribute-value-pairs a bit more structured (defclass attribute-value-pair () ((attribute :accessor attribute :initarg :attribute :initform nil) (db-value :accessor db-value :initarg :db-value :initform nil)) (:documentation "Represents an attribute-sql-expression and its value, used to pass to insert/update. Was previously a two list")) (defun make-attribute-value-pair (slot-def value database) (check-slot-type slot-def value) (make-instance 'attribute-value-pair :attribute (sql-expression :attribute (database-identifier slot-def database)) :db-value (db-value-from-slot slot-def value database))) (defun to-attributes-and-values (av-pairs) (etypecase (first av-pairs) (list (loop for (a v) in av-pairs collect a into attributes collect v into db-values finally (return (values attributes db-values)))) (attribute-value-pair (loop for pair in av-pairs collecting (attribute pair) into attributes collecting (db-value pair) into db-values finally (return (values attributes db-values)))))) ;;; Basic operations on databases (defmethod database-query-result-set ((expr %sql-expression) database &key full-set result-types) (database-query-result-set (sql-output expr database) database :full-set full-set :result-types result-types)) (defmethod execute-command ((sql-expression string) &key (database *default-database*)) (record-sql-command sql-expression database) (let ((res (database-execute-command sql-expression database))) (record-sql-result res database)) (values)) (defmethod execute-command ((expr %sql-expression) &key (database *default-database*)) (execute-command (sql-output expr database) :database database) (values)) (defmethod query ((query-expression string) &key (database *default-database*) (result-types :auto) (flatp nil) (field-names t)) (record-sql-command query-expression database) (multiple-value-bind (rows names) (database-query query-expression database result-types field-names) (let ((result (if (and flatp (= 1 (length (car rows)))) (mapcar #'car rows) rows))) (record-sql-result result database) (if field-names (values result names) result)))) (defmethod query ((expr %sql-expression) &key (database *default-database*) (result-types :auto) (flatp nil) (field-names t)) (query (sql-output expr database) :database database :flatp flatp :result-types result-types :field-names field-names)) (defmethod query ((expr sql-object-query) &key (database *default-database*) (result-types :auto) (flatp nil) (field-names t)) (declare (ignore result-types field-names)) (apply #'select (append (slot-value expr 'objects) (slot-value expr 'exp) (when (slot-value expr 'refresh) (list :refresh (sql-output expr database))) (when (or flatp (slot-value expr 'flatp) ) (list :flatp t)) (list :database database)))) (defun print-query (query-exp &key titles (formats t) (sizes t) (stream t) (database *default-database*)) "Prints a tabular report of the results returned by the SQL query QUERY-EXP, which may be a symbolic SQL expression or a string, in DATABASE which defaults to *DEFAULT-DATABASE*. The report is printed onto STREAM which has a default value of t which means that *STANDARD-OUTPUT* is used. The TITLE argument, which defaults to nil, allows the specification of a list of strings to use as column titles in the tabular output. SIZES accepts a list of column sizes, one for each column selected by QUERY-EXP, to use in formatting the tabular report. The default value of t means that minimum sizes are computed. FORMATS is a list of format strings to be used for printing each column selected by QUERY-EXP. The default value of FORMATS is t meaning that ~A is used to format all columns or ~VA if column sizes are used." (flet ((compute-sizes (data) (mapcar #'(lambda (x) (apply #'max (mapcar #'(lambda (y) (if (null y) 3 (length y))) x))) (apply #'mapcar (cons #'list data)))) (format-record (record control sizes) (format stream "~&~?" control (if (null sizes) record (mapcan #'(lambda (s f) (list s f)) sizes record))))) (let* ((query-exp (etypecase query-exp (string query-exp) (sql-query (sql-output query-exp database)))) (data (query query-exp :database database :result-types nil :field-names nil)) (sizes (if (or (null sizes) (listp sizes)) sizes (compute-sizes (if titles (cons titles data) data)))) (formats (if (or (null formats) (not (listp formats))) (make-list (length (car data)) :initial-element (if (null sizes) "~A " "~VA ")) formats)) (control-string (format nil "~{~A~}" formats))) (when titles (format-record titles control-string sizes)) (dolist (d data (values)) (format-record d control-string sizes))))) (defun insert-records (&key (into nil) (attributes nil) (values nil) (av-pairs nil) (query nil) (database *default-database*)) "Inserts records into the table specified by INTO in DATABASE which defaults to *DEFAULT-DATABASE*. There are five ways of specifying the values inserted into each row. In the first VALUES contains a list of values to insert and ATTRIBUTES, AV-PAIRS and QUERY are nil. This can be used when values are supplied for all attributes in INTO. In the second, ATTRIBUTES is a list of column names, VALUES is a corresponding list of values and AV-PAIRS and QUERY are nil. In the third, ATTRIBUTES, VALUES and QUERY are nil and AV-PAIRS is a list of (attribute value) pairs, or attribute-value-pair objects. In the fourth, VALUES, AV-PAIRS and ATTRIBUTES are nil and QUERY is a symbolic SQL query expression in which the selected columns also exist in INTO. In the fifth method, VALUES and AV-PAIRS are nil and ATTRIBUTES is a list of column names and QUERY is a symbolic SQL query expression which returns values for the specified columns." (let ((stmt (make-sql-insert :into into :attrs attributes :vals values :av-pairs av-pairs :subquery query))) (execute-command stmt :database database))) (defun make-sql-insert (&key (into nil) (attrs nil) (vals nil) (av-pairs nil) (subquery nil)) (unless into (error 'sql-user-error :message ":into keyword not supplied")) (let ((insert (make-instance 'sql-insert :into (database-identifier into nil)))) (with-slots (attributes values query) insert (cond ((and vals (not attrs) (not query) (not av-pairs)) (setf values vals)) ((and vals attrs (not subquery) (not av-pairs)) (setf attributes attrs) (setf values vals)) ((and av-pairs (not vals) (not attrs) (not subquery)) (multiple-value-setq (attributes values) (to-attributes-and-values av-pairs))) ((and subquery (not vals) (not attrs) (not av-pairs)) (setf query subquery)) ((and subquery attrs (not vals) (not av-pairs)) (setf attributes attrs) (setf query subquery)) (t (error 'sql-user-error :message "bad or ambiguous keyword combination."))) insert))) (defun delete-records (&key (from nil) (where nil) (database *default-database*)) "Deletes records satisfying the SQL expression WHERE from the table specified by FROM in DATABASE specifies a database which defaults to *DEFAULT-DATABASE*." (let ((stmt (make-instance 'sql-delete :from (database-identifier from database) :where where))) (execute-command stmt :database database))) (defun update-records (table &key (attributes nil) (values nil) (av-pairs nil) (where nil) (database *default-database*)) "Updates the attribute values of existing records satsifying the SQL expression WHERE in the table specified by TABLE in DATABASE which defaults to *DEFAULT-DATABASE*. There are three ways of specifying the values to update for each row. In the first, VALUES contains a list of values to use in the update and ATTRIBUTES and AV-PAIRS are nil. This can be used when values are supplied for all attributes in TABLE. In the second, ATTRIBUTES is a list of column names, VALUES is a corresponding list of values and AV-PAIRS is nil. In the third, ATTRIBUTES and VALUES are nil and AV-PAIRS is an alist of (attribute value) pairs." (when av-pairs (multiple-value-setq (attributes values) (to-attributes-and-values av-pairs))) (let ((stmt (make-instance 'sql-update :table (database-identifier table database) :attributes attributes :values values :where where))) (execute-command stmt :database database))) ;;; Iteration (defmacro do-query (((&rest args) query-expression &key (database '*default-database*) (result-types :auto)) &body body) "Repeatedly executes BODY within a binding of ARGS on the fields of each row selected by the SQL query QUERY-EXPRESSION, which may be a string or a symbolic SQL expression, in DATABASE which defaults to *DEFAULT-DATABASE*. The values returned by the execution of BODY are returned. RESULT-TYPES is a list of symbols which specifies the lisp type for each field returned by QUERY-EXPRESSION. If RESULT-TYPES is nil all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field." (let ((result-set (gensym "RESULT-SET-")) (qe (gensym "QUERY-EXPRESSION-")) (columns (gensym "COLUMNS-")) (row (gensym "ROW-")) (db (gensym "DB-")) (last-form-eval (gensym "LFE-"))) `(let ((,qe ,query-expression) (,db ,database)) (typecase ,qe (sql-object-query (dolist (,row (query ,qe :database ,db)) (destructuring-bind ,args ,row ,@body))) (t ;; Functional query (multiple-value-bind (,result-set ,columns) (database-query-result-set ,qe ,db :full-set nil :result-types ,result-types) (when ,result-set (unwind-protect (do ((,row (make-list ,columns)) (,last-form-eval nil)) ((not (database-store-next-row ,result-set ,db ,row)) ,last-form-eval) (destructuring-bind ,args ,row (setq ,last-form-eval (progn ,@body)))) (database-dump-result-set ,result-set ,db))))))))) (defun map-query (output-type-spec function query-expression &key (database *default-database*) (result-types :auto)) "Map the function FUNCTION over the attribute values of each row selected by the SQL query QUERY-EXPRESSION, which may be a string or a symbolic SQL expression, in DATABASE which defaults to *DEFAULT-DATABASE*. The results of the function are collected as specified in OUTPUT-TYPE-SPEC and returned like in MAP. RESULT-TYPES is a list of symbols which specifies the lisp type for each field returned by QUERY-EXPRESSION. If RESULT-TYPES is nil all results are returned as strings whereas the default value of :auto means that the lisp types are automatically computed for each field." (typecase query-expression (sql-object-query (map output-type-spec #'(lambda (x) (apply function x)) (query query-expression))) (t ;; Functional query (macrolet ((type-specifier-atom (type) `(if (atom ,type) ,type (car ,type)))) (case (type-specifier-atom output-type-spec) ((nil) (map-query-for-effect function query-expression database result-types)) (list (map-query-to-list function query-expression database result-types)) ((simple-vector simple-string vector string array simple-array bit-vector simple-bit-vector base-string simple-base-string) (map-query-to-simple output-type-spec function query-expression database result-types)) (t (funcall #'map-query (cmucl-compat:result-type-or-lose output-type-spec t) function query-expression :database database :result-types result-types))))))) (defun map-query-for-effect (function query-expression database result-types) (multiple-value-bind (result-set columns) (database-query-result-set query-expression database :full-set nil :result-types result-types) (let ((flatp (and (= columns 1) (typep query-expression 'sql-query) (slot-value query-expression 'flatp)))) (when result-set (unwind-protect (do ((row (make-list columns))) ((not (database-store-next-row result-set database row)) nil) (if flatp (apply function row) (funcall function row))) (database-dump-result-set result-set database)))))) (defun map-query-to-list (function query-expression database result-types) (multiple-value-bind (result-set columns) (database-query-result-set query-expression database :full-set nil :result-types result-types) (let ((flatp (and (= columns 1) (typep query-expression 'sql-query) (slot-value query-expression 'flatp)))) (when result-set (unwind-protect (let ((result (list nil))) (do ((row (make-list columns)) (current-cons result (cdr current-cons))) ((not (database-store-next-row result-set database row)) (cdr result)) (rplacd current-cons (list (if flatp (apply function row) (funcall function (copy-list row))))))) (database-dump-result-set result-set database)))))) (defun map-query-to-simple (output-type-spec function query-expression database result-types) (multiple-value-bind (result-set columns rows) (database-query-result-set query-expression database :full-set t :result-types result-types) (let ((flatp (and (= columns 1) (typep query-expression 'sql-query) (slot-value query-expression 'flatp)))) (when result-set (unwind-protect (if rows ;; We know the row count in advance, so we allocate once (do ((result (cmucl-compat:make-sequence-of-type output-type-spec rows)) (row (make-list columns)) (index 0 (1+ index))) ((not (database-store-next-row result-set database row)) result) (declare (fixnum index)) (setf (aref result index) (if flatp (apply function row) (funcall function (copy-list row))))) ;; Database can't report row count in advance, so we have ;; to grow and shrink our vector dynamically (do ((result (cmucl-compat:make-sequence-of-type output-type-spec 100)) (allocated-length 100) (row (make-list columns)) (index 0 (1+ index))) ((not (database-store-next-row result-set database row)) (cmucl-compat:shrink-vector result index)) (declare (fixnum allocated-length index)) (when (>= index allocated-length) (setq allocated-length (* allocated-length 2) result (adjust-array result allocated-length))) (setf (aref result index) (if flatp (apply function row) (funcall function (copy-list row)))))) (database-dump-result-set result-set database)))))) ;;; Row processing macro from CLSQL (defmacro for-each-row (((&rest fields) &key from order-by where distinct limit) &body body) (let ((d (gensym "DISTINCT-")) (bind-fields (loop for f in fields collect (car f))) (w (gensym "WHERE-")) (o (gensym "ORDER-BY-")) (frm (gensym "FROM-")) (l (gensym "LIMIT-")) (q (gensym "QUERY-"))) `(let ((,frm ,from) (,w ,where) (,d ,distinct) (,l ,limit) (,o ,order-by)) (let ((,q (query-string ',fields ,frm ,w ,d ,o ,l))) (loop for tuple in (query ,q) collect (destructuring-bind ,bind-fields tuple ,@body)))))) (defun query-string (fields from where distinct order-by limit) (concatenate 'string (format nil "select ~A~{~A~^,~} from ~{~A~^ and ~}" (if distinct "distinct " "") (field-names fields) (from-names from)) (if where (format nil " where ~{~A~^ ~}" (where-strings where)) "") (if order-by (format nil " order by ~{~A~^, ~}" (order-by-strings order-by))) (if limit (format nil " limit ~D" limit) ""))) (defun lisp->sql-name (field) (typecase field (string field) (symbol (string-upcase (symbol-name field))) (cons (cadr field)) (t (format nil "~A" field)))) (defun field-names (field-forms) "Return a list of field name strings from a fields form" (loop for field-form in field-forms collect (lisp->sql-name (if (cadr field-form) (cadr field-form) (car field-form))))) (defun from-names (from) "Return a list of field name strings from a fields form" (loop for table in (if (atom from) (list from) from) collect (lisp->sql-name table))) (defun where-strings (where) (loop for w in (if (atom (car where)) (list where) where) collect (if (consp w) (format nil "~A ~A ~A" (second w) (first w) (third w)) (format nil "~A" w)))) (defun order-by-strings (order-by) (loop for o in order-by collect (if (atom o) (lisp->sql-name o) (format nil "~A ~A" (lisp->sql-name (car o)) (lisp->sql-name (cadr o)))))) ;;; Large objects support (defun create-large-object (&key (database *default-database*)) "Creates a new large object in the database and returns the object identifier" (database-create-large-object database)) (defun write-large-object (object-id data &key (database *default-database*)) "Writes data to the large object" (database-write-large-object object-id data database)) (defun read-large-object (object-id &key (database *default-database*)) "Reads the large object content" (database-read-large-object object-id database)) (defun delete-large-object (object-id &key (database *default-database*)) "Deletes the large object in the database" (database-delete-large-object object-id database)) ;;; Prepared statements (defun prepare-sql (sql-stmt types &key (database *default-database*) (result-types :auto) field-names) "Prepares a SQL statement for execution. TYPES contains a list of types corresponding to the input parameters. Returns a prepared-statement object. A type can be :int :double :null (:blob n) (:string n) " (unless (db-type-has-prepared-stmt? (database-type database)) (error 'sql-user-error :message (format nil "Database backend type ~:@(~A~) does not support prepared statements." (database-type database)))) (database-prepare sql-stmt types database result-types field-names)) (defun bind-parameter (prepared-stmt position value) "Sets the value of a parameter is in prepared statement." (database-bind-parameter prepared-stmt position value) value) (defun run-prepared-sql (prepared-stmt) "Execute the prepared sql statment. All input parameters must be bound." (database-run-prepared prepared-stmt)) (defun free-prepared-sql (prepared-stmt) "Delete the objects associated with a prepared statement." (database-free-prepared prepared-stmt)) cl-sql-6.7.2/sql/kmr-mop.lisp0000644000175000017500000000740112064366222015012 0ustar kevinkevin;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: kmr-mop.lisp ;;;; Purpose: MOP support for multiple-implementions ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Apr 2003 ;;;; ;;;; This file imports MOP symbols into the CLSQL-MOP package and then ;;;; re-exports into CLSQL-SYS them to hide differences in ;;;; MOP implementations. ;;;; ;;;; This file was extracted from the KMRCL utilities ;;;; ************************************************************************* (in-package #:clsql-sys) #+lispworks (defun intern-eql-specializer (slot) `(eql ,slot)) (defmacro process-class-option (metaclass slot-name &optional required) #+lispworks `(defmethod clos:process-a-class-option ((class ,metaclass) (name (eql ,slot-name)) value) (when (and ,required (null value)) (error "metaclass ~A class slot ~A must have a value" (quote ,metaclass) name)) (list name `',value)) #-lispworks (declare (ignore metaclass slot-name required)) ) (defmacro process-slot-option (metaclass slot-name) #+lispworks `(defmethod clos:process-a-slot-option ((class ,metaclass) (option (eql ,slot-name)) value already-processed-options slot) (list* option `',value already-processed-options)) #-lispworks (declare (ignore metaclass slot-name)) ) (eval-when (:compile-toplevel :load-toplevel :execute) (defclass %slot-order-test-class () ((a) (b))) (finalize-inheritance (find-class '%slot-order-test-class)) (let ((slots (class-slots (find-class '%slot-order-test-class)))) (ecase (slot-definition-name (first slots)) (a) (b (pushnew :mop-slot-order-reversed cl:*features*))))) (defun ordered-class-slots (class) #+mop-slot-order-reversed (reverse (class-slots class)) #-mop-slot-order-reversed (class-slots class)) (defun ordered-class-direct-slots (class) "Gets an ordered list of direct class slots" ;; NB: this used to return effective-slot-definitions in direct ;; opposition to the function name. Not sure why (setf class (to-class class)) #+mop-slot-order-reversed (reverse (class-direct-slots class)) #-mop-slot-order-reversed (class-direct-slots class)) (defun find-slot-if (class predicate &optional direct? recurse?) "Looks up a direct-slot-definition by name" (setf class (to-class class)) (labels ((find-it (class) (let* ((slots (if direct? (ordered-class-direct-slots class) (ordered-class-slots class))) (it (find-if predicate slots))) (or it (when recurse? (loop for sup in (class-direct-superclasses class) for rtn = (find-it sup) until rtn finally (return rtn))))))) (find-it class))) (defun find-slot-by-name (class slot-name &optional direct? recurse?) "Looks up a direct-slot-definition by name" (setf class (to-class class) slot-name (to-slot-name slot-name)) (find-slot-if class (lambda (slot-def) (eql (to-slot-name slot-def) slot-name)) direct? recurse?)) ;; Lispworks has symbol for slot rather than the slot instance (defun %svuc-slot-name (slot) #+lispworks slot #-lispworks (slot-definition-name slot)) (defun %svuc-slot-object (slot class) (declare (ignorable class)) #+lispworks (clos:find-slot-definition slot class) #-lispworks slot) cl-sql-6.7.2/sql/recording.lisp0000644000175000017500000001647511577723403015425 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; CLSQL broadcast streams which can be used to monitor the ;;;; flow of commands to, and results from, a database. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defun start-sql-recording (&key (type :commands) (database *default-database*)) "Starts recording of SQL commands sent to and/or results returned from DATABASE which defaults to *DEFAULT-DATABASE*. The SQL is output on one or more broadcast streams, initially just *STANDARD-OUTPUT*, and the functions ADD-SQL-STREAM and DELETE-SQL-STREAM may be used to add or delete command or result recording streams. The default value of TYPE is :commands which means that SQL commands sent to DATABASE are recorded. If TYPE is :results then SQL results returned from DATABASE are recorded. Both commands and results may be recorded by passing TYPE value of :both." (when (or (eq type :both) (eq type :commands)) (setf (command-recording-stream database) (make-broadcast-stream *standard-output*))) (when (or (eq type :both) (eq type :results)) (setf (result-recording-stream database) (make-broadcast-stream *standard-output*))) (values)) (defun stop-sql-recording (&key (type :commands) (database *default-database*)) "Stops recording of SQL commands sent to and/or results returned from DATABASE which defaults to *DEFAULT-DATABASE*. The default value of TYPE is :commands which means that SQL commands sent to DATABASE will no longer be recorded. If TYPE is :results then SQL results returned from DATABASE will no longer be recorded. Recording may be stopped for both commands and results by passing TYPE value of :both." (when (or (eq type :both) (eq type :commands)) (setf (command-recording-stream database) nil)) (when (or (eq type :both) (eq type :results)) (setf (result-recording-stream database) nil)) (values)) (defun sql-recording-p (&key (type :commands) (database *default-database*)) "Predicate to test whether the SQL recording specified by TYPE is currently enabled for DATABASE which defaults to *DEFAULT-DATABASE*. TYPE may be one of :commands, :results, :both or :either, defaulting to :commands, otherwise nil is returned." (when (or (and (eq type :commands) (command-recording-stream database)) (and (eq type :results) (result-recording-stream database)) (and (eq type :both) (result-recording-stream database) (command-recording-stream database)) (and (eq type :either) (or (result-recording-stream database) (command-recording-stream database)))) t)) (defun add-sql-stream (stream &key (type :commands) (database *default-database*)) "Adds the supplied stream STREAM (or T for *standard-output*) as a component of the recording broadcast stream for the SQL recording type specified by TYPE on DATABASE which defaults to *DEFAULT-DATABASE*. TYPE must be one of :commands, :results, or :both, defaulting to :commands, depending on whether the stream is to be added for recording SQL commands, results or both." (when (or (eq type :both) (eq type :commands)) (unless (member stream (list-sql-streams :type :commands :database database)) (setf (command-recording-stream database) (apply #'make-broadcast-stream (cons stream (list-sql-streams :type :commands :database database)))))) (when (or (eq type :both) (eq type :results)) (unless (member stream (list-sql-streams :type :results :database database)) (setf (result-recording-stream database) (apply #'make-broadcast-stream (cons stream (list-sql-streams :type :results :database database)))))) stream) (defun delete-sql-stream (stream &key (type :commands) (database *default-database*)) "Removes the supplied stream STREAM from the recording broadcast stream for the SQL recording type specified by TYPE on DATABASE which defaults to *DEFAULT-DATABASE*. TYPE must be one of :commands, :results, or :both, defaulting to :commands, depending on whether the stream is to be added for recording SQL commands, results or both." (when (or (eq type :both) (eq type :commands)) (setf (command-recording-stream database) (apply #'make-broadcast-stream (remove stream (list-sql-streams :type :commands :database database))))) (when (or (eq type :both) (eq type :results)) (setf (result-recording-stream database) (apply #'make-broadcast-stream (remove stream (list-sql-streams :type :results :database database))))) stream) (defun list-sql-streams (&key (type :commands) (database *default-database*)) "Returns the list of component streams for the broadcast stream recording SQL commands sent to and/or results returned from DATABASE which defaults to *DEFAULT-DATABASE*. TYPE must be one of :commands, :results, or :both, defaulting to :commands, and determines whether the listed streams contain those recording SQL commands, results or both." (let ((crs (command-recording-stream database)) (rrs (result-recording-stream database))) (cond ((eq type :commands) (when crs (broadcast-stream-streams crs))) ((eq type :results) (when rrs (broadcast-stream-streams rrs))) ((eq type :both) (append (when crs (broadcast-stream-streams crs)) (when rrs (broadcast-stream-streams rrs)))) (t (error "Unknown recording type. ~A" type))))) (defun sql-stream (&key (type :commands) (database *default-database*)) "Returns the broadcast stream used for recording SQL commands sent to or results returned from DATABASE which defaults to *DEFAULT-DATABASE*. TYPE must be one of :commands or :results, defaulting to :commands, and determines whether the stream returned is that used for recording SQL commands or results." (cond ((eq type :commands) (command-recording-stream database)) ((eq type :results) (result-recording-stream database)) (t (error "Unknown recording type. ~A" type)))) (defun record-sql-command (expr database) (when database (with-slots (command-recording-stream) database (when command-recording-stream (format command-recording-stream "~&;; ~A ~A => ~A~%" (iso-timestring (get-time)) (database-name database) expr))))) (defun record-sql-result (res database) (when database (with-slots (result-recording-stream) database (when result-recording-stream (format result-recording-stream "~&;; ~A ~A <= ~A~%" (iso-timestring (get-time)) (database-name database) res))))) cl-sql-6.7.2/sql/decimals.lisp0000644000175000017500000003661312651763351015226 0ustar kevinkevin;;; DECIMALS ;; ;; A decimal number parser and formatting package for Common Lisp. ;; ;; Author: Teemu Likonen ;; ;; License: Public domain ;; ;; This program is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. (defpackage #:decimals (:use #:cl) (:export #:round-half-away-from-zero #:format-decimal-number #:parse-decimal-number #:decimal-parse-error #:define-decimal-formatter)) (in-package #:decimals) (defun round-half-away-from-zero (number &optional (divisor 1)) "Divide _number_ by _divisor_ and round the result to the nearest integer. If the result is half-way between two integers round away from zero. Two values are returned: quotient and remainder. This is similar to `cl:round` function except that `cl:round` rounds to an even integer when number is exactly between two integers. Examples: (round-half-away-from-zero 3/2) => 2, -1/2 (round 3/2) => 2, -1/2 (round-half-away-from-zero 5/2) => 3, -1/2 (round 5/2) => 2, 1/2" (if (zerop number) (values 0 0) (let ((quotient (if (plusp number) (floor (+ (/ number divisor) 1/2)) (ceiling (- (/ number divisor) 1/2))))) (values quotient (- number (* quotient divisor)))))) (defun divide-into-groups (string &key (separator #\Space) (from-end nil) (group-digits 3)) (assert (and (integerp group-digits) (plusp group-digits)) (group-digits) "The GROUP-DIGITS argument must be a positive integer") (setf separator (princ-to-string separator)) (if (zerop (length separator)) string (flet ((make-groups (string separator) (loop :with length := (length string) :with result := (make-array length :element-type 'character :fill-pointer 0 :adjustable t) :for c :across string :for i :upfrom 1 :do (vector-push-extend c result) :if (and (zerop (rem i group-digits)) (< i length)) :do (loop :for c :across separator :do (vector-push-extend c result)) :finally (return result)))) (if from-end (nreverse (make-groups (reverse string) (reverse separator))) (make-groups string separator))))) (defun decimal-round-split (number &key (round-magnitude 0) (rounder #'round-half-away-from-zero) (positive-sign #\+) (negative-sign #\-) (zero-sign nil)) (assert (integerp round-magnitude) (round-magnitude) "ROUND-MAGNITUDE argument must be an integer.") (when (floatp number) (setf number (rational number))) (let ((divisor (expt 10 round-magnitude))) (setf number (* divisor (funcall rounder number divisor)))) (let ((sign (cond ((plusp number) (or positive-sign "")) ((minusp number) (or negative-sign "")) (t (or zero-sign ""))))) (multiple-value-bind (integer fractional) (truncate (abs number)) (let ((fractional-string (with-output-to-string (out) (loop :with next := fractional :with remainder :repeat (abs round-magnitude) :until (zerop next) :do (setf (values next remainder) (truncate (* next 10))) (princ next out) (setf next remainder))))) (list (princ-to-string sign) (princ-to-string integer) fractional-string))))) (defun string-align (string width &key (side :left) (char #\Space)) (if (>= (length string) width) string (let ((result (make-string width :initial-element char))) (ecase side (:left (replace result string)) (:right (replace result string :start1 (- width (length string)))))))) (defun format-decimal-number (number &key (round-magnitude 0) (rounder #'round-half-away-from-zero) (decimal-separator #\.) (integer-group-separator nil) (integer-group-digits 3) (integer-minimum-width 0) (integer-pad-char #\Space) (fractional-group-separator nil) (fractional-group-digits 3) (fractional-minimum-width 0) (fractional-pad-char #\Space) (show-trailing-zeros nil) (positive-sign nil) (negative-sign #\-) (zero-sign nil)) "Apply specified decimal number formatting rules to _number_ and return a formatted string. The second return value is (almost) the same formatted string divided into four strings. It's a list of four strings: sign, integer part, decimal separator and fractional part. Formatting arguments _integer-minimum-width_ and _fractional-minimum-width_ do not apply to the second return value. Everything else does. _Number_ must be of type `real`. This function uses `rational` types internally. If the given _number_ is a `float` it is first turned into `rational` by calling `cl:rational`. Formatting rules are specified with keyword arguments, as described below. The default value is in parentheses. * `round-magnitude (0)` This is the order of magnitude used for rounding. The value must be an integer and it is interpreted as a power of 10. * `show-trailing-zeros (nil)` If the value is non-nil print all trailing zeros in fractional part. Examples: (format-decimal-number 1/5 :round-magnitude -3 :show-trailing-zeros nil) => \"0.2\" (format-decimal-number 1/5 :round-magnitude -3 :show-trailing-zeros t) => \"0.200\" * `rounder (#'round-half-away-from-zero)` The value must be a function (or a symbol naming a function). It is used to round the number to the specified round magnitude. The function must work like `cl:truncate`, `cl:floor`, `cl:ceiling` and `cl:round`, that is, take two arguments, a number and a divisor, and return the quotient as the first value. This package introduces another rounding function, `round-half-away-from-zero`, which is used by default. See its documentation for more information. * `decimal-separator (#\\.)` If the value is non-nil the `princ` output of the value will be added between integer and fractional parts. Probably the most useful types are `character` and `string`. * `integer-group-separator (nil)` * `fractional-group-separator (nil)` If the value is non-nil the digits in integer or fractional parts are put in groups. The `princ` output of the value will be added between digit groups. * `integer-group-digits (3)` * `fractional-group-digits (3)` The value is a positive integer defining the number of digits in groups. * `integer-minimum-width (0)` * `fractional-minimum-width (0)` Format integer or fractional part using minimum of this amount of characters, possibly using some padding characters (see below). _positive-sign_, _negative-sign_ or _zero-sign_ (see below) is included when calculating the width of the integer part. Similarly _decimal-separator_ is included when calculating the width of the fractional part. * `integer-pad-char (#\\Space)` * `fractional-pad-char (#\\Space)` The value is the padding character which is used to fill _integer-minimum-width_ or _fractional-minimum-width_. * `positive-sign (nil)` * `negative-sign (#\\-)` * `zero-sign (nil)` If values are non-nil these are used as the leading sign for positive, negative and zero numbers. The `princ` output of the value is used." (destructuring-bind (sign integer fractional) (decimal-round-split number :round-magnitude round-magnitude :rounder rounder :positive-sign positive-sign :negative-sign negative-sign :zero-sign zero-sign) (setf decimal-separator (if decimal-separator (princ-to-string decimal-separator) "") integer (divide-into-groups integer :separator (or integer-group-separator "") :group-digits integer-group-digits :from-end t) fractional (divide-into-groups (if (and show-trailing-zeros (plusp (- (- (length fractional)) round-magnitude))) (replace (make-string (abs round-magnitude) :initial-element #\0) fractional) fractional) :separator (or fractional-group-separator "") :group-digits fractional-group-digits :from-end nil)) (values (concatenate 'string (string-align (concatenate 'string sign integer) integer-minimum-width :side :right :char integer-pad-char) (string-align (if (plusp (length fractional)) (concatenate 'string decimal-separator fractional) "") fractional-minimum-width :side :left :char fractional-pad-char)) (list sign integer decimal-separator fractional)))) (defmacro define-decimal-formatter (name &body keyword-arguments) "Define a decimal number formatter function to use with the `~/` directive of `cl:format`. The valid format is this: (define-decimal-formatter name (:keyword form) ...) _Name_ is the symbol that names the function. _Keyword_ must be a valid keyword argument for the `format-decimal-number` function (see its documentation for more information). _Form_ is evaluated and the value is used with the _keyword_ argument. Macro's side effect is that global function _name_ is defined. It can be used with the `~/` directive of `cl:format` function. Examples: (define-decimal-formatter my-formatter (:round-magnitude -6) (:decimal-separator \",\") (:integer-group-separator \" \") (:integer-minimum-width 4) (:fractional-group-separator \" \") (:fractional-minimum-width 10) (:show-trailing-zeros t)) => MY-FORMATTER (format nil \"~/my-formatter/\" 10/6) => \" 1,666 667 \" (format nil \"~/my-formatter/\" 100/8) => \" 12,500 000 \" The `~/` directive function call can optionally take up to three arguments to override the defaults: ~round-magnitude,integer-minimum-width,fractional-minimum-width/FUNCTION/ For example: (format nil \"~-2,3,4/my-formatter/\" 10/6) => \" 1,67 \"" (let ((key-arg (gensym))) `(let ((,key-arg (list ,@(loop :for (keyword value) :in keyword-arguments :do (assert (keywordp keyword) (keyword) "Keyword required.") :collect keyword :collect value)))) (defun ,name (stream number &optional colon-p at-sign-p round-magnitude integer-minimum-width fractional-minimum-width) (declare (ignore colon-p at-sign-p)) (let ((args (copy-list ,key-arg))) (when round-magnitude (setf (getf args :round-magnitude) round-magnitude)) (when integer-minimum-width (setf (getf args :integer-minimum-width) integer-minimum-width)) (when fractional-minimum-width (setf (getf args :fractional-minimum-width) fractional-minimum-width)) (princ (apply #'format-decimal-number number args) stream)))))) (defun number-string-to-integer (string) (handler-case (parse-integer string) (parse-error () nil))) (defun number-string-to-fractional (string) (when (every #'digit-char-p string) (setf string (string-right-trim "0" string)) (handler-case (/ (parse-integer string) (expt 10 (length string))) (parse-error () nil)))) (define-condition decimal-parse-error (parse-error) nil (:report "Not a valid decimal number string.") (:documentation "Function `parse-decimal-number` signals this condition when it couldn't parse a decimal number from string.")) (defun parse-decimal-number (string &key (decimal-separator #\.) (positive-sign #\+) (negative-sign #\-) (start 0) (end nil)) "Examine _string_ (or its substring from _start_ to _end_) for a decimal number. Assume that the decimal number is exact and return it as a rational number. Rules for parsing: First all leading and trailing `#\\Space` characters are stripped. The resulting string may start with a _positive-sign_ or a _negative-sign_ character. The latter causes this function to assume a negative number. The following characters in the string must include one or more digit characters and it may include one _decimal-separator_ character which separates integer and fractional parts. All other characters are illegal. If these rules are not met a `decimal-parse-error` condition is signaled. Examples: (parse-decimal-number \"0.2\") => 1/5 (parse-decimal-number \".2\") => 1/5 (parse-decimal-number \"+3.\") => 3 (parse-decimal-number \" -7 \") => -7 (parse-decimal-number \"−12,345\" :decimal-separator #\\, :negative-sign #\\−) => -2469/200" (setf string (string-trim " " (subseq string start end))) (if (not (plusp (length string))) (error 'decimal-parse-error) (let ((sign 1)) (cond ((char= (aref string 0) negative-sign) (setf sign -1 string (subseq string 1))) ((char= (aref string 0) positive-sign) (setf string (subseq string 1)))) (if (and (every (lambda (item) (or (digit-char-p item) (char= item decimal-separator))) string) (some #'digit-char-p string) (<= 0 (count decimal-separator string) 1)) (let ((pos (position decimal-separator string))) (* sign (+ (or (number-string-to-integer (subseq string 0 pos)) 0) (if pos (or (number-string-to-fractional (subseq string (1+ pos))) 0) 0)))) (error 'decimal-parse-error))))) cl-sql-6.7.2/sql/generic-postgresql.lisp0000644000175000017500000004234612303270414017245 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Generic postgresql layer, used by db-postgresql and db-postgresql-socket ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defclass generic-postgresql-database (database) ((has-table-pg_roles :type boolean :reader has-table-pg_roles :initform nil)) (:documentation "Encapsulate same behavior across postgresql and postgresql-socket backends.")) ;; Object functions (defmethod database-get-type-specifier ((type symbol) args database (db-type (eql :postgresql))) "Special database types for POSTGRESQL backends" (declare (ignore database db-type)) (case type (wall-time ;; TODO: why is this WITHOUT... "TIMESTAMP WITHOUT TIME ZONE") (string ;; TODO: the default to CHAR here seems specious as the PG docs claim ;; that char is slower than varchar (if args (format nil "CHAR(~A)" (car args)) "VARCHAR")) (number (cond ((and (consp args) (= (length args) 2)) (format nil "NUMERIC(~D,~D)" (first args) (second args))) ((and (consp args) (= (length args) 1)) (format nil "NUMERIC(~D)" (first args))) (t "NUMERIC"))) ((tinyint smallint) "INT2") (t (call-next-method)))) ;;; Backend functions (defun owner-clause (owner) (cond ((stringp owner) (format nil " AND (relowner=(SELECT usesysid FROM pg_user WHERE (usename='~A')))" owner)) ((null owner) (format nil " AND (relowner<>(SELECT usesysid FROM pg_user WHERE usename='postgres'))")) (t ""))) (defun has-table (name database) (let ((name-retrieved (caar (database-query (format nil "SELECT relname FROM pg_class WHERE relname='~A'" name) database nil nil)))) (if (and (stringp name-retrieved) (plusp (length name-retrieved))) t nil))) (defmethod slot-unbound (class (obj generic-postgresql-database) (slot (eql 'has-table-pg_roles))) ;; Lazily cache slot value (declare (ignore class)) (setf (slot-value obj 'has-table-pg_roles) (has-table "pg_roles" obj))) (defun database-list-objects-of-type (database type owner) (mapcar #'car (database-query (format nil (if (and (has-table-pg_roles database) (not (eq owner :all))) " SELECT c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_roles r ON r.oid = c.relowner LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('~A','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND pg_catalog.pg_table_is_visible(c.oid) ~A" "SELECT relname FROM pg_class WHERE (relkind = '~A')~A") type (owner-clause owner)) database nil nil))) (defmethod database-list-tables ((database generic-postgresql-database) &key (owner nil)) (database-list-objects-of-type database "r" owner)) (defmethod database-list-views ((database generic-postgresql-database) &key (owner nil)) (database-list-objects-of-type database "v" owner)) (defmethod database-list-indexes ((database generic-postgresql-database) &key (owner nil)) (database-list-objects-of-type database "i" owner)) (defmethod database-list-table-indexes (table (database generic-postgresql-database) &key (owner nil)) (let ((indexrelids (database-query (format nil "select indexrelid from pg_index where indrelid=(select relfilenode from pg_class where LOWER(relname)='~A'~A)" (string-downcase (unescaped-database-identifier table)) (owner-clause owner)) database :auto nil)) (result nil)) (dolist (indexrelid indexrelids (nreverse result)) (push (caar (database-query (format nil "select relname from pg_class where relfilenode='~A'" (car indexrelid)) database nil nil)) result)))) (defmethod database-list-attributes ((table %database-identifier) (database generic-postgresql-database) &key (owner nil)) (let* ((table (unescaped-database-identifier table)) (owner-clause (cond ((stringp owner) (format nil " AND (relowner=(SELECT usesysid FROM pg_user WHERE usename='~A'))" owner)) ((null owner) " AND (not (relowner=1))") (t ""))) (result (mapcar #'car (database-query (format nil "SELECT attname FROM pg_class,pg_attribute WHERE pg_class.oid=attrelid AND attisdropped = FALSE AND relname='~A'~A" (string-downcase table) owner-clause) database nil nil)))) (if result (remove-if #'(lambda (it) (member it '("cmin" "cmax" "xmax" "xmin" "oid" "ctid" ;; kmr -- added tableoid "tableoid") :test #'equal)) result)))) (defmethod database-attribute-type ((attribute %database-identifier) (table %database-identifier) (database generic-postgresql-database) &key (owner nil) &aux (table (unescaped-database-identifier table)) (attribute (unescaped-database-identifier attribute))) (let ((row (car (database-query (format nil "SELECT pg_type.typname,pg_attribute.attlen,pg_attribute.atttypmod,pg_attribute.attnotnull FROM pg_type,pg_class,pg_attribute WHERE pg_class.oid=pg_attribute.attrelid AND pg_class.relname='~A' AND pg_attribute.attname='~A' AND pg_attribute.atttypid=pg_type.oid~A" (string-downcase table) (string-downcase attribute) (owner-clause owner)) database nil nil)))) (when row (destructuring-bind (typname attlen atttypmod attnull) row (setf attlen (%get-int attlen) atttypmod (%get-int atttypmod)) (let ((coltype (ensure-keyword typname)) (colnull (typecase attnull (string (if (string-equal "f" attnull) 1 0)) (null 1) (T 0))) collen colprec) (setf (values collen colprec) (case coltype ((:numeric :decimal) (if (= -1 atttypmod) (values nil nil) (values (ash (- atttypmod 4) -16) (boole boole-and (- atttypmod 4) #xffff)))) (otherwise (values (cond ((and (= -1 attlen) (= -1 atttypmod)) nil) ((= -1 attlen) (- atttypmod 4)) (t attlen)) nil)))) (values coltype collen colprec colnull)))))) (defmethod database-create-sequence (sequence-name (database generic-postgresql-database)) (let ((cmd (concatenate 'string "CREATE SEQUENCE " (escaped-database-identifier sequence-name database)))) (database-execute-command cmd database))) (defmethod database-drop-sequence (sequence-name (database generic-postgresql-database)) (database-execute-command (concatenate 'string "DROP SEQUENCE " (escaped-database-identifier sequence-name database)) database)) (defmethod database-list-sequences ((database generic-postgresql-database) &key (owner nil)) (database-list-objects-of-type database "S" owner)) (defmethod database-set-sequence-position (name (position integer) (database generic-postgresql-database)) (values (%get-int (caar (database-query (format nil "SELECT SETVAL ('~A', ~A)" (escaped-database-identifier name) position) database nil nil))))) (defmethod database-sequence-next (sequence-name (database generic-postgresql-database)) (values (%get-int (caar (database-query (concatenate 'string "SELECT NEXTVAL ('" (escaped-database-identifier sequence-name) "')") database nil nil))))) (defmethod database-sequence-last (sequence-name (database generic-postgresql-database)) (values (%get-int (caar (database-query (concatenate 'string "SELECT LAST_VALUE FROM " (escaped-database-identifier sequence-name)) database nil nil))))) (defmethod auto-increment-sequence-name (table column (database generic-postgresql-database)) (let* ((sequence-name (or (database-identifier (slot-value column 'autoincrement-sequence)) (combine-database-identifiers (list table column 'seq) database)))) (when (search "'" (escaped-database-identifier sequence-name) :test #'string-equal) (signal-database-too-strange "PG Sequence names shouldnt contain single quotes for the sake of sanity")) sequence-name)) (defmethod database-last-auto-increment-id ((database generic-postgresql-database) table column) (let ((seq-name (auto-increment-sequence-name table column database))) (first (clsql:query (format nil "SELECT currval ('~a')" (escaped-database-identifier seq-name)) :flatp t :database database :result-types '(:int))))) (defmethod database-generate-column-definition (class slotdef (database generic-postgresql-database)) (when (member (view-class-slot-db-kind slotdef) '(:base :key)) (let ((cdef (list (sql-expression :attribute (database-identifier slotdef database)) (specified-type slotdef) (view-class-slot-db-type slotdef))) (const (listify (view-class-slot-db-constraints slotdef))) (seq (auto-increment-sequence-name class slotdef database))) (when seq (setf const (remove :auto-increment const)) (unless (member :default const) (let* ((next (format nil " nextval('~a')" (escaped-database-identifier seq)))) (setf const (append const (list :default next)))))) (append cdef const)))) (defmethod database-add-autoincrement-sequence ((self standard-db-class) (database generic-postgresql-database)) (let ((ordered-slots (slots-for-possibly-normalized-class self))) (dolist (slotdef ordered-slots) ;; ensure that referenceed sequences actually exist before referencing them (let ((sequence-name (auto-increment-sequence-name self slotdef database))) (when (and sequence-name (not (sequence-exists-p sequence-name :database database))) (create-sequence sequence-name :database database)))))) (defmethod database-remove-autoincrement-sequence ((table standard-db-class) (database generic-postgresql-database)) (let ((ordered-slots (slots-for-possibly-normalized-class table))) (dolist (slotdef ordered-slots) ;; ensure that referenceed sequences are dropped with the table (let ((sequence-name (auto-increment-sequence-name table slotdef database))) (when sequence-name (drop-sequence sequence-name)))))) (defun postgresql-database-list (connection-spec type) (destructuring-bind (host name &rest other-args) connection-spec (declare (ignore name)) (let ((database (database-connect (list* host "template1" other-args) type))) (unwind-protect (progn (setf (slot-value database 'clsql-sys::state) :open) (mapcar #'car (database-query "select datname from pg_database" database nil nil))) (progn (database-disconnect database) (setf (slot-value database 'clsql-sys::state) :closed)))))) (defmethod database-list (connection-spec (type (eql :postgresql))) (postgresql-database-list connection-spec type)) (defmethod database-list (connection-spec (type (eql :postgresql-socket))) (postgresql-database-list connection-spec type)) #+nil (defmethod database-describe-table ((database generic-postgresql-database) table) ;; MTP: LIST-ATTRIBUTE-TYPES currently executes separate queries for ;; each attribute. It would be more efficient to have a single SQL ;; query return the type data for all attributes. This code is ;; retained as an example of how to do this for PostgreSQL. (database-query (format nil "select a.attname, t.typname from pg_class c, pg_attribute a, pg_type t where c.relname = '~a' and a.attnum > 0 and a.attrelid = c.oid and a.atttypid = t.oid" (sql-escape (string-downcase table))) database :auto nil)) ;;; Prepared statements (defvar *next-prepared-id-num* 0) (defun next-prepared-id () (let ((num (incf *next-prepared-id-num*))) (format nil "CLSQL_PS_~D" num))) (defclass postgresql-stmt () ((database :initarg :database :reader database) (id :initarg :id :reader id) (bindings :initarg :bindings :reader bindings) (field-names :initarg :field-names :accessor stmt-field-names) (result-types :initarg :result-types :reader result-types))) (defun clsql-type->postgresql-type (type) (cond ((in type :int :integer) "INT4") ((in type :short) "INT2") ((in type :bigint) "INT8") ((in type :float :double :number) "NUMERIC") ((and (consp type) (in (car type) :char :varchar)) "VARCHAR") (t (error 'sql-user-error :message (format nil "Unknown clsql type ~A." type))))) (defun prepared-sql-to-postgresql-sql (sql) ;; FIXME: Convert #\? to "$n". Don't convert within strings (declare (simple-string sql)) (with-output-to-string (out) (do ((len (length sql)) (param 0) (in-str nil) (pos 0 (1+ pos))) ((= len pos)) (declare (fixnum len param pos)) (let ((c (schar sql pos))) (declare (character c)) (cond ((or (char= c #\") (char= c #\')) (setq in-str (not in-str)) (write-char c out)) ((and (char= c #\?) (not in-str)) (write-char #\$ out) (write-string (write-to-string (incf param)) out)) (t (write-char c out))))))) (defmethod database-prepare (sql-stmt types (database generic-postgresql-database) result-types field-names) (let ((id (next-prepared-id))) (database-execute-command (format nil "PREPARE ~A (~{~A~^,~}) AS ~A" id (mapcar #'clsql-type->postgresql-type types) (prepared-sql-to-postgresql-sql sql-stmt)) database) (make-instance 'postgresql-stmt :id id :database database :result-types result-types :field-names field-names :bindings (make-list (length types))))) (defmethod database-bind-parameter ((stmt postgresql-stmt) position value) (setf (nth (1- position) (bindings stmt)) value)) (defun binding-to-param (binding) (typecase binding (string (concatenate 'string "'" (sql-escape-quotes binding) "'")) (t binding))) (defmethod database-run-prepared ((stmt postgresql-stmt)) (with-slots (database id bindings field-names result-types) stmt (let ((query (format nil "EXECUTE ~A (~{~A~^,~})" id (mapcar #'binding-to-param bindings)))) (cond ((and field-names (not (consp field-names))) (multiple-value-bind (res names) (database-query query database result-types field-names) (setf field-names names) (values res names))) (field-names (values (nth-value 0 (database-query query database result-types nil)) field-names)) (t (database-query query database result-types field-names)))))) ;;; Capabilities (defmethod db-type-has-fancy-math? ((db-type (eql :postgresql))) t) (defmethod db-type-default-case ((db-type (eql :postgresql))) :lower) (defmethod db-type-has-prepared-stmt? ((db-type (eql :postgresql))) t) (defmethod db-type-has-prepared-stmt? ((db-type (eql :postgresql-socket))) t) (defmethod db-type-has-auto-increment? ((db-type (eql :postgresql))) t) cl-sql-6.7.2/sql/operations.lisp0000644000175000017500000002211212651763351015615 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; ;;;; Definition of SQL operations used with the symbolic SQL syntax. ;;;; ;;;; This file is part of CLSQL. ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) ;; Keep a hashtable for mapping symbols to sql generator functions, ;; for use by the bracketed reader syntax. (defvar *sql-op-table* (make-hash-table :test #'equal)) ;; Define an SQL operation type. (defmacro defsql (function definition-keys &body body) `(progn (defun ,function ,@body) (let ((symbol (cadr (member :symbol ',definition-keys)))) (setf (gethash (if symbol (symbol-name-default-case symbol) ',function) *sql-op-table*) ',function)))) ;; SQL operations (defsql sql-query (:symbol "select") (&rest args) (apply #'make-query args)) (defsql sql-any (:symbol "any") (&rest rest) (make-instance 'sql-function-exp :name 'any :args rest)) (defsql sql-some (:symbol "some") (&rest rest) (make-instance 'sql-function-exp :name 'some :args rest)) (defsql sql-all (:symbol "all") (&rest rest) (make-instance 'sql-function-exp :name 'all :args rest)) (defsql sql-e-string (:symbol "E") (&rest rest) (make-instance 'sql-escape-string-exp :string (first rest))) (defsql sql-not (:symbol "not") (&rest rest) (make-instance 'sql-value-exp :modifier 'not :components rest)) (defsql sql-union (:symbol "union") (&rest rest) (make-instance 'sql-set-exp :operator 'union :sub-expressions rest)) (defsql sql-intersect (:symbol "intersect") (&rest rest) (make-instance 'sql-set-exp :operator 'intersect :sub-expressions rest)) (defsql sql-except (:symbol "except") (&rest rest) (make-instance 'sql-set-exp :operator 'except :sub-expressions rest)) (defsql sql-minus (:symbol "minus") (&rest rest) (make-instance 'sql-set-exp :operator 'minus :sub-expressions rest)) (defsql sql-limit (:symbol "limit") (&rest rest) (make-instance 'sql-query-modifier-exp :modifier 'limit :components rest)) (defsql sql-group-by (:symbol "group-by") (&rest rest) (make-instance 'sql-query-modifier-exp :modifier '|GROUP BY| :components rest)) (defsql sql-order-by (:symbol "order-by") (&rest rest) (make-instance 'sql-query-modifier-exp :modifier '|ORDER BY| :components rest)) (defsql sql-having (:symbol "having") (&rest rest) (make-instance 'sql-query-modifier-exp :modifier 'having :components rest)) (defsql sql-null (:symbol "null") (&optional not-null-thing) (if not-null-thing (make-instance 'sql-relational-exp :operator 'is :sub-expressions (list not-null-thing nil)) (make-instance 'sql-value-exp :components 'null))) (defsql sql-not-null (:symbol "not-null") (&optional not-null-thing) (if not-null-thing (make-instance 'sql-relational-exp :operator 'IS :sub-expressions (list not-null-thing (sql-expression :string "NOT NULL"))) (sql-expression :string "NOT NULL"))) (defsql sql-exists (:symbol "exists") (&rest rest) (make-instance 'sql-function-exp :name 'exists :args rest)) (defsql sql-* (:symbol "*") (&rest rest) (if (zerop (length rest)) (make-instance 'sql-ident :name '*) (make-instance 'sql-relational-exp :operator '* :sub-expressions rest))) (defsql sql-+ (:symbol "+") (&rest rest) (if (cdr rest) (make-instance 'sql-relational-exp :operator '+ :sub-expressions rest) (make-instance 'sql-value-exp :modifier '+ :components rest))) (defsql sql-/ (:symbol "/") (&rest rest) (make-instance 'sql-relational-exp :operator '/ :sub-expressions rest)) (defsql sql-- (:symbol "-") (&rest rest) (if (cdr rest) (make-instance 'sql-relational-exp :operator '- :sub-expressions rest) (make-instance 'sql-value-exp :modifier '- :components rest))) (defsql sql-like (:symbol "like") (&rest rest) (make-instance 'sql-relational-exp :operator 'like :sub-expressions rest)) (defsql sql-uplike (:symbol "uplike") (&rest rest) (make-instance 'sql-upcase-like :sub-expressions rest)) (defsql sql-and (:symbol "and") (&rest rest) (make-instance 'sql-relational-exp :operator 'and :sub-expressions rest)) (defsql sql-or (:symbol "or") (&rest rest) (make-instance 'sql-relational-exp :operator 'or :sub-expressions rest)) (defsql sql-in (:symbol "in") (&rest rest) (make-instance 'sql-relational-exp :operator 'in :sub-expressions rest)) (defsql sql-concat-op (:symbol "concat-op") (&rest rest) (make-instance 'sql-relational-exp :operator '\|\| :sub-expressions rest)) (defsql sql-concat (:symbol "concat") (&rest rest) (make-instance 'sql-function-exp :name 'concat :args rest)) (defsql sql-substr (:symbol "substr") (&rest rest) (if (= (length rest) 3) (make-instance 'sql-function-exp :name 'substr :args rest) (error 'sql-user-error :message "SUBSTR must have 3 arguments."))) (defsql sql-substring (:symbol "substring") (&rest rest) (if (= (length rest) 3) (make-instance 'sql-function-exp :name 'substring :args rest) (error 'sql-user-error :message "SUBSTRING must have 3 arguments."))) (defsql sql-is (:symbol "is") (&rest rest) (make-instance 'sql-relational-exp :operator 'is :sub-expressions rest)) (defsql sql-= (:symbol "=") (&rest rest) (make-instance 'sql-relational-exp :operator '= :sub-expressions rest)) (defsql sql-== (:symbol "==") (&rest rest) (make-instance 'sql-assignment-exp :operator '= :sub-expressions rest)) (defsql sql-< (:symbol "<") (&rest rest) (make-instance 'sql-relational-exp :operator '< :sub-expressions rest)) (defsql sql-> (:symbol ">") (&rest rest) (make-instance 'sql-relational-exp :operator '> :sub-expressions rest)) (defsql sql-<> (:symbol "<>") (&rest rest) (make-instance 'sql-relational-exp :operator '<> :sub-expressions rest)) (defsql sql->= (:symbol ">=") (&rest rest) (make-instance 'sql-relational-exp :operator '>= :sub-expressions rest)) (defsql sql-<= (:symbol "<=") (&rest rest) (make-instance 'sql-relational-exp :operator '<= :sub-expressions rest)) (defsql sql-count (:symbol "count") (&rest rest) (make-instance 'sql-function-exp :name 'count :args rest)) (defsql sql-max (:symbol "max") (&rest rest) (make-instance 'sql-function-exp :name 'max :args rest)) (defsql sql-min (:symbol "min") (&rest rest) (make-instance 'sql-function-exp :name 'min :args rest)) (defsql sql-avg (:symbol "avg") (&rest rest) (make-instance 'sql-function-exp :name 'avg :args rest)) (defsql sql-sum (:symbol "sum") (&rest rest) (make-instance 'sql-function-exp :name 'sum :args rest)) (defsql sql-the (:symbol "the") (&rest rest) (make-instance 'sql-typecast-exp :modifier (first rest) :components (second rest))) (defsql sql-function (:symbol "function") (&rest args) (make-instance 'sql-function-exp :name (make-symbol (car args)) :args (cdr args))) (defsql sql-between (:symbol "between") (&rest rest) (if (= (length rest) 3) (make-instance 'sql-between-exp :name 'between :args rest) (error 'sql-user-error :message "BETWEEN must have 3 arguments."))) (defsql sql-distinct (:symbol "distinct") (&rest rest) (make-instance 'sql-query-modifier-exp :modifier 'distinct :components rest)) (defsql sql-coalesce (:symbol "coalesce") (&rest rest) (make-instance 'sql-function-exp :name 'coalesce :args rest)) (defsql sql-nvl (:symbol "nvl") (&rest rest) (if (= (length rest) 2) (make-instance 'sql-function-exp :name 'coalesce :args rest) (error 'sql-user-error :message "NVL accepts exactly 2 arguments."))) (defsql sql-userenv (:symbol "userenv") (&rest rest) (make-instance 'sql-function-exp :name 'userenv :args rest)) (defsql sql-lower (:symbol "lower") (&rest rest) (if (= (length rest) 1) (make-instance 'sql-function-exp :name 'lower :args rest) (error 'sql-user-error :message "LOWER must have 1 argument."))) (defsql sql-upper (:symbol "upper") (&rest rest) (if (= (length rest) 1) (make-instance 'sql-function-exp :name 'upper :args rest) (error 'sql-user-error :message "UPPER must have 1 argument."))) cl-sql-6.7.2/sql/initialize.lisp0000644000175000017500000000502411335067642015574 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: initialize.lisp ;;;; Purpose: Initializion routines for db backend ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: May 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defvar *loaded-database-types* nil "Contains a list of database types which have been defined/loaded.") (defmethod database-type-load-foreign (x) (error "No generic function defined for database-type-load-foreign with parameters of ~S" x)) (defmethod database-type-load-foreign :after (database-type) (when (database-type-library-loaded database-type) (pushnew database-type *loaded-database-types*))) (defun reload-database-types () "Reloads any foreign code for the loaded database types after a dump." (mapc #'database-type-load-foreign *loaded-database-types*)) (defvar *default-database-type* nil "Designates the default database type which is initialised by the function INITIALISE-DATABASE-TYPE.") (defvar *initialized-database-types* nil "A list of database types which have currently been initialised by calling INITIALIZE-DATABASE-TYPE.") (defun initialize-database-type (&key (database-type *default-database-type*)) "Initializes the supplied DATABASE-TYPE, if it is not already initialized, as indicated by *INITIALIZED-DATABASE-TYPES* and returns DATABASE-TYPE. *DEFAULT-DATABASE-TYPE* is set to DATABASE-TYPE and, if DATABASE-TYPE has not been initialised, it is added to *INITIALIZED-DATABASE-TYPES*. " (when (member database-type *initialized-database-types*) (return-from initialize-database-type database-type)) (let ((system (intern (concatenate 'string (symbol-name '#:clsql-) (symbol-name database-type))))) (when (not (find-package system)) (asdf:operate 'asdf:load-op system))) (when (database-initialize-database-type database-type) (push database-type *initialized-database-types*) (setf *default-database-type* database-type) database-type)) cl-sql-6.7.2/sql/conditions.lisp0000644000175000017500000001504712651763351015614 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: conditions.lisp ;;;; Purpose: Error conditions for CLSQL ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:clsql-sys) (defvar *backend-warning-behavior* :warn "Action to perform on warning messages from backend. Default is to :warn. May also be set to :error to signal an error or :ignore/nil to silently ignore the warning.") ;;; CommonSQL-compatible conditions (define-condition sql-condition () ()) (define-condition sql-error (simple-error sql-condition) ()) (define-condition sql-database-error (sql-error) ((error-id :initarg :error-id :initform nil :reader sql-error-error-id) (secondary-error-id :initarg :secondary-error-id :initform nil :reader sql-error-secondary-error-id) (database-message :initarg :message :initform nil :reader sql-error-database-message) (database :initarg :database :initform nil :reader sql-error-database)) (:report (lambda (c stream) (format stream "A database error occurred~@[ on database ~A~]: ~A / ~A~% ~A" (sql-error-database c) (sql-error-error-id c) (sql-error-secondary-error-id c) (sql-error-database-message c)))) (:documentation "Used to signal an error in a CLSQL database interface.")) (define-condition sql-connection-error (sql-database-error) ((database-type :initarg :database-type :initform nil :reader sql-error-database-type) (connection-spec :initarg :connection-spec :initform nil :reader sql-error-connection-spec)) (:report (lambda (c stream) (format stream "While trying to connect to database ~A~% using database-type ~A:~% Error ~D / ~A~% has occurred." (when (and (sql-error-connection-spec c) (sql-error-database-type c)) (database-name-from-spec (sql-error-connection-spec c) (sql-error-database-type c))) (sql-error-database-type c) (sql-error-error-id c) (sql-error-database-message c)))) (:documentation "Used to signal an error in connecting to a database.")) (define-condition sql-database-data-error (sql-database-error) ((expression :initarg :expression :initarg nil :reader sql-error-expression)) (:report (lambda (c stream) (format stream "While accessing database ~A~% with expression ~S:~% Error ~D / ~A~% has occurred." (sql-error-database c) (sql-error-expression c) (sql-error-error-id c) (sql-error-database-message c)))) (:documentation "Used to signal an error with the SQL data passed to a database.")) (define-condition sql-temporary-error (sql-database-error) () (:documentation "Used to signal an error when the database cannot currently process a valid interaction because, for example, it is still executing another command possibly issued by another user.")) (define-condition sql-timeout-error (sql-connection-error) () (:documentation "Used to signal an error when the database times out while processing some operation.")) (define-condition sql-fatal-error (sql-connection-error) () (:documentation "Used to signal an error when the database connection is no longer usable.")) (define-condition sql-user-error (sql-error) ((message :initarg :message :initform "Unspecified error" :reader sql-user-error-message)) (:report (lambda (c stream) (format stream "A CLSQL lisp code error occurred: ~A " (sql-user-error-message c)))) (:documentation "Used to signal lisp errors inside CLSQL.")) ;; Signal conditions (defun signal-closed-database-error (database) (error 'sql-fatal-error :database database :connection-spec (when database (connection-spec database)) :database-type (when database (database-type database)) :message "Database is closed.")) (defun signal-no-database-error (database) (error 'sql-database-error :database database :message (format nil "~A is not a database." database))) ;;; CLSQL Extensions (define-condition sql-warning (warning sql-condition) ((message :initarg :message :initform nil :reader sql-warning-message)) (:report (lambda (c stream) (format stream "~A" (sql-warning-message c))))) (define-condition sql-database-warning (sql-warning) ((database :initarg :database :reader sql-warning-database)) (:report (lambda (c stream) (format stream "While accessing database ~A~% Warning: ~A~% has occurred." (sql-warning-database c) (sql-warning-message c))))) (define-condition database-too-strange (sql-user-error) () (:documentation "Used to signal cases where CLSQL is going to fail at mapping your database correctly")) (defun signal-database-too-strange (message) (error 'database-too-strange :message message)) (define-condition sql-value-conversion-error (error) ((expected-type :accessor expected-type :initarg :expected-type :initform nil) (value :accessor value :initarg :value :initform nil) (database :accessor database :initarg :database :initform nil))) (defun error-converting-value (val type &optional (database *default-database*)) (restart-case (error (make-condition 'sql-value-conversion-error :expected-type type :value val :database database)) (continue () :report "Continue using the unconverted value" (values val t)) (use-value (new-val) :report "Use a different value instead of this failed conversion" (values new-val t) ))) (defun maybe-error-converting-value (new val type &optional (database *default-database*)) (if (typep new type) new (error-converting-value val type database))) cl-sql-6.7.2/sql/Makefile0000644000175000017500000000126711335067642014207 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for CLSQL SQL interface # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## SUBDIRS= include ../Makefile.common .PHONY: distclean distclean: clean cl-sql-6.7.2/clsql-sqlite.asd0000644000175000017500000000260511332141035015035 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-sqlite.asd ;;;; Purpose: ASDF file for CLSQL SQLite backend ;;;; Programmer: Aurelio Bignoli ;;;; Date Started: Aug 2003 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2003 by Aurelio Bignoli ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-sqlite-system (:use #:asdf #:cl)) (in-package #:clsql-sqlite-system) (defsystem clsql-sqlite :name "cl-sql-sqlite" :author "Aurelio Bignoli " :maintainer "Aurelio Bignoli" :licence "Lessor Lisp General Public License" :description "Common Lisp SQLite Driver" :long-description "cl-sql-sqlite package provides a database driver to SQLite database library." :depends-on (clsql clsql-uffi) :components ((:module :db-sqlite :components ((:file "sqlite-package") (:file "sqlite-loader" :depends-on ("sqlite-package")) (:file "sqlite-api" :depends-on ("sqlite-loader")) (:file "sqlite-sql" :depends-on ("sqlite-api")))))) cl-sql-6.7.2/Makefile0000644000175000017500000000243312134026311013366 0ustar kevinkevin#!/usr/bin/make ########################################################################## # FILE IDENTIFICATION # # Name: Makefile # Purpose: Makefile for the CLSQL package # Programer: Kevin M. Rosenberg # Date Started: Mar 2002 # # This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg # # CLSQL users are granted the rights to distribute and use this software # as governed by the terms of the Lisp Lesser GNU Public License # (http://opensource.franz.com/preamble.html), also known as the LLGPL. ########################################################################## PKG := clsql DEBPKG := cl-sql SUBDIRS := sql tests uffi db-mysql db-aodbc db-odbc \ db-postgresql db-postgresql-socket db-sqlite \ db-oracle DOCSUBDIRS:=doc include Makefile.common LIBSUBDIRS=db-mysql uffi .PHONY: subdirs $(LIBSUBDIRS) .PHONY: all all: $(LIBSUBDIRS) $(LIBSUBDIRS): $(MAKE) -C $@ SOURCE_FILES=interfaces sql cmucl-compat doc test-suite Makefile VERSION \ COPYING.CLSQL COPYING.MaiSQL README INSTALL ChangeLog NEWS TODO \ set-logical.cl clsql-uffi.system \ clsql.system clsql-aodbc.system clsql-mysql.system \ clsql-postgresql.system clsql-postgresql-socket.system .PHONY: doc doc: $(MAKE) -C doc .PHONY:dist dist: clean @$(MAKE) -C doc $@ cl-sql-6.7.2/db-postgresql-socket3/0000755000175000017500000000000014327126007016074 5ustar kevinkevincl-sql-6.7.2/db-postgresql-socket3/api.lisp0000644000175000017500000000440311616055736017547 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-api.lisp ;;;; Purpose: Low-level PostgreSQL interface using sockets ;;;; Authors: Kevin M. Rosenberg based on original code by Pierre R. Mai ;;;; Created: Feb 2002 ;;;; ;;;; $Id$ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2004 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:postgresql-socket3) (defmethod clsql-sys:database-type-load-foreign ((database-type (eql :postgresql-socket3))) t) (defmethod clsql-sys:database-type-library-loaded ((database-type (eql :postgresql-socket3))) "T if foreign library was able to be loaded successfully. Always true for socket interface" t) (defparameter +postgresql-server-default-port+ 5432 "Default port of PostgreSQL server.") ;;;; Condition hierarchy (define-condition postgresql-condition (condition) ((connection :initarg :connection :reader postgresql-condition-connection) (message :initarg :message :reader postgresql-condition-message)) (:report (lambda (c stream) (format stream "~@<~A occurred on connection ~A. ~:@_Reason: ~A~:@>" (type-of c) (postgresql-condition-connection c) (postgresql-condition-message c))))) (define-condition postgresql-error (error postgresql-condition) ()) (define-condition postgresql-fatal-error (postgresql-error) ()) (define-condition postgresql-login-error (postgresql-fatal-error) ()) (define-condition postgresql-warning (warning postgresql-condition) ()) (define-condition postgresql-notification (postgresql-condition) () (:report (lambda (c stream) (format stream "~@" (postgresql-condition-connection c) (postgresql-condition-message c)))))cl-sql-6.7.2/db-postgresql-socket3/package.lisp0000644000175000017500000000231412021503403020344 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-package.lisp ;;;; Purpose: Package definition for PostgreSQL interface using sockets ;;;; Programmers: Kevin M. Rosenberg ;;;; Date Started: Feb 2002 ;;;; ;;;; $Id$ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) #+lispworks (require "comm") (defpackage #:postgresql-socket3 (:use #:cl md5 #:cl-postgres) (:shadow #:postgresql-warning #:postgresql-notification) (:export #:+postgresql-server-default-port+ #:postgresql-condition #:postgresql-error #:postgresql-fatal-error #:postgresql-login-error #:postgresql-warning #:postgresql-notification #:postgresql-condition-message #:postgresql-condition-connection)) cl-sql-6.7.2/db-postgresql-socket3/sql.lisp0000644000175000017500000003133712651763351017602 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: postgresql-socket-sql.sql ;;;; Purpose: High-level PostgreSQL interface using socket ;;;; Authors: Kevin M. Rosenberg based on original code by Pierre R. Mai ;;;; Created: Feb 2002 ;;;; ;;;; $Id$ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2007 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package #:cl-user) (defpackage :clsql-postgresql-socket3 (:use #:common-lisp #:clsql-sys #:postgresql-socket3) (:export #:postgresql-socket3-database) (:documentation "This is the CLSQL socket interface (protocol version 3) to PostgreSQL.")) (in-package #:clsql-postgresql-socket3) (defvar *sqlreader* (cl-postgres:copy-sql-readtable)) (let ((dt-fn (lambda (useconds-since-2000) (let ((sec (truncate (/ useconds-since-2000 1000000))) (usec (mod useconds-since-2000 1000000))) (clsql:make-time :year 2000 :second sec :usec usec))))) (cl-postgres:set-sql-datetime-readers :table *sqlreader* :date (lambda (days-since-2000) (clsql:make-date :year 2000 :day (+ 1 days-since-2000))) :timestamp dt-fn :timestamp-with-timezone dt-fn)) ;; interface foreign library loading routines (clsql-sys:database-type-load-foreign :postgresql-socket3) (defmethod database-initialize-database-type ((database-type (eql :postgresql-socket3))) t) ;; Field type conversion (defun convert-to-clsql-warning (database condition) (ecase *backend-warning-behavior* (:warn (warn 'sql-database-warning :database database :message (cl-postgres:database-error-message condition))) (:error (error 'sql-database-error :database database :message (format nil "Warning upgraded to error: ~A" (cl-postgres:database-error-message condition)))) ((:ignore nil) ;; do nothing ))) (defun convert-to-clsql-error (database expression condition) (error 'sql-database-data-error :database database :expression expression :error-id (type-of condition) :message (cl-postgres:database-error-message condition))) (defmacro with-postgresql-handlers ((database &optional expression) &body body) (let ((database-var (gensym)) (expression-var (gensym))) `(let ((,database-var ,database) (,expression-var ,expression)) (handler-bind ((postgresql-warning (lambda (c) (convert-to-clsql-warning ,database-var c))) (cl-postgres:database-error (lambda (c) (convert-to-clsql-error ,database-var ,expression-var c)))) ,@body)))) (defclass postgresql-socket3-database (generic-postgresql-database) ((connection :accessor database-connection :initarg :connection :type cl-postgres:database-connection))) (defmethod database-type ((database postgresql-socket3-database)) :postgresql-socket3) (defmethod database-name-from-spec (connection-spec (database-type (eql :postgresql-socket3))) (check-connection-spec connection-spec database-type (host db user password &optional port options tty)) (destructuring-bind (host db user password &optional port options tty) connection-spec (declare (ignore password options tty)) (concatenate 'string (etypecase host (null "localhost") (keyword "unix") (pathname (namestring host)) (string host)) (when port (concatenate 'string ":" (etypecase port (integer (write-to-string port)) (string port)))) "/" db "/" user))) (defmethod database-connect (connection-spec (database-type (eql :postgresql-socket3))) (check-connection-spec connection-spec database-type (host db user password &optional port options tty)) (destructuring-bind (host db user password &optional (port +postgresql-server-default-port+) (options "") (tty "")) connection-spec (declare (ignore options tty)) (handler-case (handler-bind ((warning (lambda (c) (warn 'sql-warning :format-control "~A" :format-arguments (list (princ-to-string c)))))) (cl-postgres:open-database db user password host port)) (cl-postgres:database-error (c) ;; Connect failed (error 'sql-connection-error :database-type database-type :connection-spec connection-spec :error-id (type-of c) :message (cl-postgres:database-error-message c))) (:no-error (connection) ;; Success, make instance (make-instance 'postgresql-socket3-database :name (database-name-from-spec connection-spec database-type) :database-type :postgresql-socket3 :connection-spec connection-spec :connection connection))))) (defmethod database-disconnect ((database postgresql-socket3-database)) (cl-postgres:close-database (database-connection database)) t) (defvar *include-field-names* nil) ;; THE FOLLOWING MACRO EXPANDS TO THE FUNCTION BELOW IT, ;; BUT TO GET null CONVENTIONS CORRECT I NEEDED TO TWEAK THE EXPANSION ;; ;; (cl-postgres:def-row-reader clsql-default-row-reader (fields) ;; (values (loop :while (cl-postgres:next-row) ;; :collect (loop :for field :across fields ;; :collect (cl-postgres:next-field field))) ;; (when *include-field-names* ;; (loop :for field :across fields ;; :collect (cl-postgres:field-name field))))) (defun clsql-default-row-reader (stream fields) (declare (type stream stream) (type (simple-array cl-postgres::field-description) fields)) (flet ((cl-postgres:next-row () (cl-postgres::look-for-row stream)) (cl-postgres:next-field (cl-postgres::field) (declare (type cl-postgres::field-description cl-postgres::field)) (let ((cl-postgres::size (cl-postgres::read-int4 stream))) (declare (type (signed-byte 32) cl-postgres::size)) (if (eq cl-postgres::size -1) nil (funcall (cl-postgres::field-interpreter cl-postgres::field) stream cl-postgres::size))))) (let ((results (loop :while (cl-postgres:next-row) :collect (loop :for field :across fields :collect (cl-postgres:next-field field)))) (col-names (when *include-field-names* (loop :for field :across fields :collect (cl-postgres:field-name field))))) ;;multiple return values were not working here (list results col-names)))) (defmethod database-query ((expression string) (database postgresql-socket3-database) result-types field-names) (let ((connection (database-connection database)) (cl-postgres:*sql-readtable* *sqlreader*)) (with-postgresql-handlers (database expression) (let ((*include-field-names* field-names)) (apply #'values (cl-postgres:exec-query connection expression #'clsql-default-row-reader))) ))) (defmethod query ((obj command-object) &key (database *default-database*) (result-types :auto) (flatp nil) (field-names t)) (clsql-sys::record-sql-command (format nil "~&~A~&{Params: ~{~A~^, ~}}" (expression obj) (parameters obj)) database) (multiple-value-bind (rows names) (database-query obj database result-types field-names) (let ((result (if (and flatp (= 1 (length (car rows)))) (mapcar #'car rows) rows))) (clsql-sys::record-sql-result result database) (if field-names (values result names) result)))) (defmethod database-query ((obj command-object) (database postgresql-socket3-database) result-types field-names) (let ((connection (database-connection database)) (cl-postgres:*sql-readtable* *sqlreader*)) (with-postgresql-handlers (database obj) (let ((*include-field-names* field-names)) (unless (has-been-prepared obj) (cl-postgres:prepare-query connection (prepared-name obj) (expression obj)) (setf (has-been-prepared obj) T)) (apply #'values (cl-postgres:exec-prepared connection (prepared-name obj) (parameters obj) #'clsql-default-row-reader)))))) (defmethod database-execute-command ((expression string) (database postgresql-socket3-database)) (let ((connection (database-connection database))) (with-postgresql-handlers (database expression) ;; return row count? (second (multiple-value-list (cl-postgres:exec-query connection expression)))))) (defmethod execute-command ((obj command-object) &key (database *default-database*)) (clsql-sys::record-sql-command (expression obj) database) (let ((res (database-execute-command obj database))) (clsql-sys::record-sql-result res database) ;; return row count? res)) (defmethod database-execute-command ((obj command-object) (database postgresql-socket3-database)) (let ((connection (database-connection database))) (with-postgresql-handlers (database obj) (unless (has-been-prepared obj) (cl-postgres:prepare-query connection (prepared-name obj) (expression obj)) (setf (has-been-prepared obj) T)) (second (multiple-value-list (cl-postgres:exec-prepared connection (prepared-name obj) (parameters obj))))))) ;;;; Cursoring interface (defmethod database-query-result-set ((expression string) (database postgresql-socket3-database) &key full-set result-types) (declare (ignore result-types)) (declare (ignore full-set)) (error "Cursoring interface is not supported for postgresql-socket3-database try cl-postgres:exec-query with a custom row-reader")) (defmethod database-dump-result-set (result-set (database postgresql-socket3-database)) (error "Cursoring interface is not supported for postgresql-socket3-database try cl-postgres:exec-query with a custom row-reader") T) (defmethod database-store-next-row (result-set (database postgresql-socket3-database) list) (error "Cursoring interface is not supported for postgresql-socket3-database try cl-postgres:exec-query with a custom row-reader")) ;;;;;;;;;;;;;;;;;;;;;;;;;; (defmethod database-create (connection-spec (type (eql :postgresql-socket3))) (destructuring-bind (host name user password &optional port options tty) connection-spec (declare (ignore port options tty)) (let ((database (database-connect (list host "postgres" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "create database ~A" name) database) (database-disconnect database))))) (defmethod database-destroy (connection-spec (type (eql :postgresql-socket3))) (destructuring-bind (host name user password &optional port options tty) connection-spec (declare (ignore port options tty)) (let ((database (database-connect (list host "postgres" user password) type))) (setf (slot-value database 'clsql-sys::state) :open) (unwind-protect (database-execute-command (format nil "drop database ~A" name) database) (database-disconnect database))))) (defmethod database-probe (connection-spec (type (eql :postgresql-socket3))) (when (find (second connection-spec) (database-list connection-spec type) :test #'string-equal) t)) ;; Database capabilities (defmethod db-backend-has-create/destroy-db? ((db-type (eql :postgresql-socket3))) nil) (defmethod db-type-has-fancy-math? ((db-type (eql :postgresql-socket3))) t) (defmethod db-type-default-case ((db-type (eql :postgresql-socket3))) :lower) (defmethod database-underlying-type ((database postgresql-socket3-database)) :postgresql) (when (clsql-sys:database-type-library-loaded :postgresql-socket3) (clsql-sys:initialize-database-type :database-type :postgresql-socket3)) cl-sql-6.7.2/clsql-uffi.asd0000644000175000017500000000303312303270414014464 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-uffi.asd ;;;; Purpose: ASDF definition file for CLSQL UFFI Helper package ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (in-package cl-user) (defpackage clsql-uffi-system (:use #:asdf #:cl)) (in-package clsql-uffi-system) (defsystem clsql-uffi :name "cl-sql-base" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common UFFI Helper functions for Common Lisp SQL Interface Library" :long-description "cl-sql-uffi package provides common helper functions using the UFFI for the CLSQL package." :depends-on (clsql #-:clsql-cffi (:version uffi "2.0") #+:clsql-cffi cffi-uffi-compat) :components ((:module :uffi :components ((:file "clsql-uffi-package") (:file "clsql-uffi-loader" :depends-on ("clsql-uffi-package")) (:file "clsql-uffi" :depends-on ("clsql-uffi-package")))))) cl-sql-6.7.2/CONTRIBUTORS0000644000175000017500000000206612473715066013632 0ustar kevinkevinCLSQL Contributors ------------------ Kevin Rosenberg (main author CLSQL) Marcus Pearce (initial port UncommonSQL, co-developer of CLSQL version 3.0) Pierre Mai (original author MaiSQL from which CLSQL was based) Aurelio Bignoli (SQLite backend) Marc Battyani (Large object support for postgresql, initial connection pool code) Ryan Davis, Nathan Bird, & Russ Tyndall (sponsored by http://www.acceleration.net/programming/) Victor (vityok@github), sqlite3 backend updates and clsql_uffi long-long support Aaron Burrow, clsql_uffi unsigned integer bugs Ilya Khaprov deadtrickster@github - mysql backend stored-procedure / multiple result set support USQL Contributors ----------------- This is a list of those individuals who have contributed in some way or other to Uncommonsql. The sources of the attributions are CVS annotation, patch submission, and original authorship, write us if we've missed anybody. Jesse Bouwman Craig Brozefsky Sean Champ Matthew Danish Adam Di Carlo Lyn Headley John Krug Pierre Mai (original author) Christopher J. Vogt cl-sql-6.7.2/clsql-mysql.asd0000644000175000017500000000702011577723152014716 0ustar kevinkevin;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: clsql-mysql.asd ;;;; Purpose: ASDF definition file for CLSQL MySQL backend ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL. ;;;; ************************************************************************* (defpackage #:clsql-mysql-system (:use #:asdf #:cl)) (in-package #:clsql-mysql-system) (eval-when (:compile-toplevel :load-toplevel :execute) (unless (find-package 'uffi) (asdf:operate 'asdf:load-op 'uffi))) (defvar *library-file-dir* (merge-pathnames "db-mysql/" (make-pathname :name nil :type nil :defaults *load-truename*))) (defclass clsql-mysql-source-file (c-source-file) ()) (defmethod output-files ((o compile-op) (c clsql-mysql-source-file)) (let* ((library-file-type (funcall (intern (symbol-name'#:default-foreign-library-type) (symbol-name '#:uffi)))) (found (some #'(lambda (dir) (probe-file (make-pathname :directory dir :name (component-name c) :type library-file-type))) '((:absolute "usr" "lib" "clsql"))))) (list (if found found (make-pathname :name (component-name c) :type library-file-type :defaults *library-file-dir*))))) (defmethod perform ((o load-op) (c clsql-mysql-source-file)) t) (defmethod operation-done-p ((o load-op) (c clsql-mysql-source-file)) (and (find-package '#:mysql) (symbol-function (intern (symbol-name '#:mysql-get-client-info) (find-package '#:mysql))) t)) (defmethod perform ((o compile-op) (c clsql-mysql-source-file)) (unless (operation-done-p o c) #-(or win32 win64 windows mswindows) (unless (zerop (run-shell-command #-freebsd "cd ~A; make" #+freebsd "cd ~A; gmake" (namestring *library-file-dir*))) (error 'operation-error :component c :operation o)))) (defmethod operation-done-p ((o compile-op) (c clsql-mysql-source-file)) (or (and (probe-file #p"/usr/lib/clsql/clsql_mysql.so") t) (let ((lib (make-pathname :defaults (component-pathname c) :type (uffi:default-foreign-library-type)))) (and (probe-file lib) (probe-file (component-pathname c)) (> (file-write-date lib) (file-write-date (component-pathname c))))))) ;;; System definition (defsystem :clsql-mysql :name "cl-sql-mysql" :author "Kevin M. Rosenberg " :maintainer "Kevin M. Rosenberg " :licence "Lessor Lisp General Public License" :description "Common Lisp SQL MySQL Driver" :long-description "cl-sql-mysql package provides a database driver to the MySQL database system." :depends-on (clsql clsql-uffi) :components ((:module :db-mysql :components ((:file "mysql-package") (:clsql-mysql-source-file "clsql_mysql" :depends-on ("mysql-package")) (:file "mysql-loader" :depends-on ("mysql-package" "clsql_mysql")) (:file "mysql-client-info" :depends-on ("mysql-loader")) (:file "mysql-api" :depends-on ("mysql-client-info")) (:file "mysql-sql" :depends-on ("mysql-api")) (:file "mysql-objects" :depends-on ("mysql-sql")))))) cl-sql-6.7.2/README0000644000175000017500000000310312570246521012614 0ustar kevinkevinCLSQL is a Common Lisp to SQL engine interface by Kevin M. Rosenberg. It includes both functional and object oriented subsystems for data definition and manipulation as well as an integrated symbolic SQL syntax. CLSQL supports a number of RDBMS and uses the UFFI (http://uffi.kpe.io) library for compatibility with Allegro CL, Lispworks, CMUCL, SBCL and OpenMCL. CLSQL has incorporated code from the following projects. At this point in 2004, development of has stopped on these incorporated projects. - Pierre Mai's MaiSQL - onShore Development's UncommonSQL - Paul Meurer's SQL/ODBC - Cadabra's Oracle interface CLSQL's home is http://clsql.kpe.io. Documentation is available as a PDF file in doc/clsql.pdf and as HTML files in doc/html.tar.gz. CONTRIBUTING ------------ If you would like to report a bug please do so through the clsql mailing list. http://lists.kpe.io/mailman/listinfo/CLSQL Patches are welcome. It will be much easier for us to incorporate if you use [git](http://git-scm.com/). Please keep distinct changes in seperate patches as it makes it much easier to review. If you have something small to to send to the mailing list `git format-patch` is your friend. If you have a bigger set of patches then I recommend creating a fork on github from https://github.com/UnwashedMeme/clsql. Once your patches are available there either issue a pull request or let us know about it on the mailing list. * http://help.github.com/ has some excellent tutorials on getting started. * http://git-scm.com/book is an excellent in depth tutorial on how to use git effectively.